Чтение принятых сообщений
Последнее изменение:
Функция вычитывает из очереди канала принятые сообщения. Адаптер может принять максимум 100 сообщений на одну очередь для одного канала и имеет 64 Кбайт свободной памяти для всех очередей. При заполнении очереди или всей свободной памяти приём сообщений приостанавливается.
long PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG* pMsg, unsigned long* pNumMsgs, unsigned long Timeout)
START_OF_MESSAGE с отметкой времени начала приёма. За ним следует основное сообщение с отметкой времени конца приёма.
PassThruConnect.ERR_TIMEOUT не генерируется).| Код | Описание | Возможные причины и решения |
|---|---|---|
| STATUS_NOERROR | Функция выполнена успешно | - |
| ERR_CONCURRENT_API_CALL v5.0 | Параллельный вызов API |
|
| ERR_DEVICE_NOT_OPEN v5.0 | Устройство не открыто |
|
| ERR_DEVICE_NOT_CONNECTED | Нет соединения с адаптером |
|
| ERR_INVALID_DEVICE_ID | Неверный идентификатор устройства |
|
| ERR_INVALID_CHANNEL_ID | Неверный идентификатор канала |
|
| ERR_NOT_SUPPORTED v5.0 | Функция не поддерживается |
|
| ERR_NULL_PARAMETER | Не задан указатель на буфер |
|
| ERR_TIMEOUT | Истёк таймаут ожидания |
|
| ERR_BUFFER_EMPTY | Приёмная очередь пуста |
|
| ERR_BUFFER_OVERFLOW | Приёмная очередь была переполнена |
|
| ERR_BUFFER_TOO_SMALL v5.0 | Буфер слишком мал |
|
| ERR_NO_FLOW_CONTROL | Не установлен фильтр Flow Control |
|
| ERR_FAILED | Внутренняя ошибка |
|
#include "j2534_dll.hpp"
unsigned long ChannelID; // ID, полученный от PassThruConnect
PASSTHRU_MSG Msgs[10]; // Буфер для сообщений
unsigned long NumMsgs = 10; // Запрашиваем до 10 сообщений
unsigned long Timeout = 1000; // Таймаут 1000 мс
long ret = PassThruReadMsgs(ChannelID, &Msgs[0], &NumMsgs, Timeout);
if (ret == STATUS_NOERROR || ret == ERR_TIMEOUT)
{
// Обработка полученных сообщений (NumMsgs штук)
for (unsigned long i = 0; i < NumMsgs; i++) {
if (Msgs[i].RxStatus & START_OF_MESSAGE) {
// Индикатор начала сообщения
continue;
}
// Обработка данных Msgs[i].Data, Msgs[i].DataSize
}
}
else
{
char error[256];
PassThruGetLastError(error);
printf("Error: %s\n", error);
}
// channelID получен ранее от ptConnect
val numMsgsToRead = 10
val timeout = 1000 // мс
val result = j2534.ptReadMsgs(channelID, numMsgsToRead, timeout)
if (result.status == STATUS_NOERROR || result.status == ERR_TIMEOUT) {
// Успешно прочитано result.msgs.size сообщений
for (msg in result.msgs) {
if (msg.rxStatus and START_OF_MESSAGE != 0) {
continue // Пропускаем индикатор начала
}
Log.i("J2534", "Получено: ${msg.data.toHexString()}")
}
} else {
Log.e("J2534", "Ошибка чтения: ${result.status}")
}
from ctypes import *
import platform
# Загрузка библиотеки
if platform.system() == "Windows":
j2534 = windll.LoadLibrary("j2534sd_v04_04_x64.dll")
elif platform.system() == "Darwin":
j2534 = cdll.LoadLibrary("libj2534_v04_04.dylib")
else:
j2534 = cdll.LoadLibrary("libj2534_v04_04.so")
# Структура PASSTHRU_MSG
class PASSTHRU_MSG(Structure):
_fields_ = [
("ProtocolID", c_ulong),
("RxStatus", c_ulong),
("TxFlags", c_ulong),
("Timestamp", c_ulong),
("DataSize", c_ulong),
("ExtraDataIndex", c_ulong),
("Data", c_ubyte * 4128)
]
# channel_id получен ранее от PassThruConnect
msgs = (PASSTHRU_MSG * 10)()
num_msgs = c_ulong(10)
timeout = c_ulong(1000)
ret = j2534.PassThruReadMsgs(channel_id, byref(msgs[0]), byref(num_msgs), timeout)
if ret == 0 or ret == 0x09: # STATUS_NOERROR or ERR_TIMEOUT
print(f"Получено {num_msgs.value} сообщений")
for i in range(num_msgs.value):
if msgs[i].RxStatus & 0x02: # START_OF_MESSAGE
continue
data = bytes(msgs[i].Data[:msgs[i].DataSize])
print(f"Данные: {data.hex()}")
else:
error = create_string_buffer(256)
j2534.PassThruGetLastError(error)
print(f"Ошибка: {error.value.decode()}")
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct PASSTHRU_MSG
{
public uint ProtocolID;
public uint RxStatus;
public uint TxFlags;
public uint Timestamp;
public uint DataSize;
public uint ExtraDataIndex;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4128)]
public byte[] Data;
}
class J2534
{
[DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PassThruReadMsgs(
uint ChannelID,
[In, Out] PASSTHRU_MSG[] pMsg,
ref uint pNumMsgs,
uint Timeout);
[DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PassThruGetLastError(
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pErrorDescription);
}
// Использование:
// channelId получен ранее от PassThruConnect
PASSTHRU_MSG[] msgs = new PASSTHRU_MSG[10];
for (int i = 0; i < msgs.Length; i++)
msgs[i].Data = new byte[4128];
uint numMsgs = 10;
uint timeout = 1000;
int ret = J2534.PassThruReadMsgs(channelId, msgs, ref numMsgs, timeout);
if (ret == 0 || ret == 0x09) // STATUS_NOERROR or ERR_TIMEOUT
{
Console.WriteLine($"Получено {numMsgs} сообщений");
for (uint i = 0; i < numMsgs; i++)
{
if ((msgs[i].RxStatus & 0x02) != 0) // START_OF_MESSAGE
continue;
byte[] data = new byte[msgs[i].DataSize];
Array.Copy(msgs[i].Data, data, msgs[i].DataSize);
Console.WriteLine($"Данные: {BitConverter.ToString(data)}");
}
}
else
{
var error = new System.Text.StringBuilder(256);
J2534.PassThruGetLastError(error);
Console.WriteLine($"Ошибка: {error}");
}