Универсальная функция управления устройством и каналом. Выполняет различные операции в зависимости от параметра IoctlID: чтение/запись конфигурации, инициализация протоколов, очистка буферов и другие служебные операции.
long PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)
Параметры
unsigned long ChannelID — идентификатор канала, полученный от PassThruConnect. Для некоторых команд (READ_VBATT, GET_DEVICE_INFO) используется DeviceID.
unsigned long IoctlID — идентификатор операции (см. таблицу ниже).
void* pInput — указатель на входные данные. Тип зависит от IoctlID.
void* pOutput — указатель на выходные данные. Тип зависит от IoctlID.
Решение: вызовите PassThruGetLastError() для описания
READ_VBATT — Чтение напряжения питания
Возвращает напряжение на разъёме OBD-II (контакт 16). Значение в милливольтах, для получения вольт разделите на 1000. Команда не требует открытого канала и может выполняться сразу после PassThruOpen.
pInput
NULL
pOutput
unsigned long* — напряжение в мВ
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long DeviceID; // Получен от PassThruOpen
unsigned long voltage;
long ret;
ret = PassThruIoctl(DeviceID, READ_VBATT, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
printf("Напряжение: %.2f V\n", voltage / 1000.0);
}
Пример на Kotlin (Android)
// deviceID получен ранее от ptOpen
val result = j2534.ptIoctl(deviceID, READ_VBATT, 0, null)
if (result.status == STATUS_NOERROR) {
val voltageV = result.outputValue / 1000.0
Log.i("J2534", "Напряжение: ${"%.2f".format(voltageV)} V")
}
Пример на Python
from ctypes import *
voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_VBATT, None, byref(voltage))
if ret == 0: # STATUS_NOERROR
print(f"Напряжение: {voltage.value / 1000:.2f} V")
Пример на C#
uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_VBATT, IntPtr.Zero, out voltage);
if (ret == 0)
{
Console.WriteLine($"Напряжение: {voltage / 1000.0:F2} V");
}
Возвращает текущее напряжение на выходе программирования. Значение в милливольтах, округлённое до ближайшей десятой вольта.
pInput
NULL
pOutput
unsigned long* — напряжение в мВ
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long DeviceID;
unsigned long voltage;
long ret;
ret = PassThruIoctl(DeviceID, READ_PROG_VOLTAGE, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
printf("Напряжение программирования: %.2f V\n", voltage / 1000.0);
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(deviceID, READ_PROG_VOLTAGE, 0, null)
if (result.status == STATUS_NOERROR) {
val voltageV = result.outputValue / 1000.0
Log.i("J2534", "Напряжение программирования: ${"%.2f".format(voltageV)} V")
}
Пример на Python
from ctypes import *
voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_PROG_VOLTAGE, None, byref(voltage))
if ret == 0:
print(f"Напряжение программирования: {voltage.value / 1000:.2f} V")
Пример на C#
uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_PROG_VOLTAGE, IntPtr.Zero, out voltage);
if (ret == 0)
{
Console.WriteLine($"Напряжение программирования: {voltage / 1000.0:F2} V");
}
FIVE_BAUD_INIT — 5-бод инициализация
Запускает медленную (5 бод) инициализацию для протоколов ISO 9141 и ISO 14230 (K-Line). Принимает KeyWord от ЭБУ. Режим инициализации задаётся параметром FIVE_BAUD_MOD через SET_CONFIG. Скорость обмена определяется автоматически.
pInput
SBYTE_ARRAY* — адрес инициализации (1 байт)
pOutput
SBYTE_ARRAY* — KeyWord (2 байта)
Параметр FIVE_BAUD_MOD определяет режим инициализации: ISO9141-2/ISO14230-4 (0), инверсия KB2 (1), инверсия адреса (2), ISO9141 без инверсии (3).
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Получен от PassThruConnect
SBYTE_ARRAY InputMsg;
SBYTE_ARRAY OutputMsg;
long ret;
unsigned char initByte[1];
unsigned char keyWord[2];
initByte[0] = 0x33; // Адрес инициализации ЭБУ
InputMsg.NumOfBytes = 1;
InputMsg.BytePtr = initByte;
OutputMsg.NumOfBytes = 2;
OutputMsg.BytePtr = keyWord;
ret = PassThruIoctl(ChannelID, FIVE_BAUD_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
printf("KeyWord: %02X %02X\n", keyWord[0], keyWord[1]);
}
Пример на Kotlin (Android)
// channelID получен от ptConnect для ISO14230
val initAddress = byteArrayOf(0x33) // Адрес инициализации
val result = j2534.ptFiveBaudInit(channelID, initAddress)
if (result.status == STATUS_NOERROR) {
val keyWord = result.keyWord
Log.i("J2534", "KeyWord: ${keyWord[0].toHex()} ${keyWord[1].toHex()}")
}
var inputMsg = new SBYTE_ARRAY {
NumOfBytes = 1,
BytePtr = new byte[] { 0x33 } // Адрес инициализации
};
var outputMsg = new SBYTE_ARRAY {
NumOfBytes = 2,
BytePtr = new byte[2]
};
int ret = J2534.PassThruIoctl(channelId, FIVE_BAUD_INIT, ref inputMsg, ref outputMsg);
if (ret == 0)
{
Console.WriteLine($"KeyWord: {outputMsg.BytePtr[0]:X2} {outputMsg.BytePtr[1]:X2}");
}
FAST_INIT — Fast инициализация
Запускает быструю инициализацию для протокола ISO 14230 (K-Line). Отправляет запрос StartCommunication и возвращает ответ ЭБУ. Используется для KWP2000.
pInput
PASSTHRU_MSG* — запрос инициализации
pOutput
PASSTHRU_MSG* — ответ ЭБУ
Важно: При функциональном (широковещательном) адресе на запрос могут ответить несколько ЭБУ. В pOutput будет только первый ответ, остальные попадут в приёмную очередь.
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Получен от PassThruConnect
PASSTHRU_MSG InputMsg;
PASSTHRU_MSG OutputMsg;
long ret;
// Запрос StartCommunication
InputMsg.ProtocolID = ISO14230;
InputMsg.TxFlags = 0;
InputMsg.DataSize = 4;
InputMsg.Data[0] = 0x81; // Формат: физический адрес, 1 байт данных
InputMsg.Data[1] = 0x10; // Целевой адрес (ЭБУ)
InputMsg.Data[2] = 0xF1; // Адрес источника (тестер)
InputMsg.Data[3] = 0x81; // SID: StartCommunication
ret = PassThruIoctl(ChannelID, FAST_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
printf("Ответ ЭБУ: %d байт\n", OutputMsg.DataSize);
for (int i = 0; i < OutputMsg.DataSize; i++)
printf("%02X ", OutputMsg.Data[i]);
}
Пример на Kotlin (Android)
// channelID получен от ptConnect для ISO14230
val request = PassThruMsg(
protocolID = ISO14230,
txFlags = 0u,
dataSize = 4,
data = byteArrayOf(0x81.toByte(), 0x10, 0xF1.toByte(), 0x81.toByte())
)
val result = j2534.ptFastInit(channelID, request)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "Ответ ЭБУ: ${result.response.data.toHexString()}")
}
Пример на Python
from ctypes import *
input_msg = PASSTHRU_MSG()
input_msg.ProtocolID = ISO14230
input_msg.TxFlags = 0
input_msg.DataSize = 4
input_msg.Data[0] = 0x81 # Формат
input_msg.Data[1] = 0x10 # Целевой адрес
input_msg.Data[2] = 0xF1 # Адрес источника
input_msg.Data[3] = 0x81 # SID: StartCommunication
output_msg = PASSTHRU_MSG()
ret = j2534.PassThruIoctl(channel_id, FAST_INIT, byref(input_msg), byref(output_msg))
if ret == 0:
data = bytes(output_msg.Data[:output_msg.DataSize])
print(f"Ответ ЭБУ: {data.hex(' ').upper()}")
Пример на C#
var inputMsg = new PASSTHRU_MSG {
ProtocolID = ISO14230,
TxFlags = 0,
DataSize = 4
};
inputMsg.Data[0] = 0x81; // Формат
inputMsg.Data[1] = 0x10; // Целевой адрес
inputMsg.Data[2] = 0xF1; // Адрес источника
inputMsg.Data[3] = 0x81; // SID: StartCommunication
var outputMsg = new PASSTHRU_MSG();
int ret = J2534.PassThruIoctl(channelId, FAST_INIT, ref inputMsg, ref outputMsg);
if (ret == 0)
{
var data = new byte[outputMsg.DataSize];
Array.Copy(outputMsg.Data, data, outputMsg.DataSize);
Console.WriteLine($"Ответ ЭБУ: {BitConverter.ToString(data).Replace("-", " ")}");
}
CLEAR_TX_BUFFER — Очистка очереди передачи
Удаляет все сообщения из очереди передачи канала. Используется для отмены запланированных передач.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID;
long ret;
ret = PassThruIoctl(ChannelID, CLEAR_TX_BUFFER, NULL, NULL);
if (ret != STATUS_NOERROR)
{
char error[256];
PassThruGetLastError(error);
printf("Ошибка: %s\n", error);
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_TX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Ошибка CLEAR_TX_BUFFER: ${result.status}")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_TX_BUFFER, None, None)
if ret != 0:
print(f"Ошибка CLEAR_TX_BUFFER: {ret}")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_TX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Ошибка CLEAR_TX_BUFFER: {ret}");
CLEAR_RX_BUFFER — Очистка очереди приёма
Удаляет все сообщения из очереди приёма канала. Рекомендуется вызывать перед началом новой диагностической сессии.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID;
long ret;
ret = PassThruIoctl(ChannelID, CLEAR_RX_BUFFER, NULL, NULL);
if (ret != STATUS_NOERROR)
{
char error[256];
PassThruGetLastError(error);
printf("Ошибка: %s\n", error);
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_RX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Ошибка CLEAR_RX_BUFFER: ${result.status}")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_RX_BUFFER, None, None)
if ret != 0:
print(f"Ошибка CLEAR_RX_BUFFER: {ret}")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_RX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Ошибка CLEAR_RX_BUFFER: {ret}");
Удаляет все периодические сообщения, установленные через PassThruStartPeriodicMsg. Эквивалентно вызову PassThruStopPeriodicMsg для каждого сообщения.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID;
long ret;
ret = PassThruIoctl(ChannelID, CLEAR_PERIODIC_MSGS, NULL, NULL);
if (ret != STATUS_NOERROR)
{
char error[256];
PassThruGetLastError(error);
printf("Ошибка: %s\n", error);
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_PERIODIC_MSGS, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Ошибка CLEAR_PERIODIC_MSGS: ${result.status}")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_PERIODIC_MSGS, None, None)
if ret != 0:
print(f"Ошибка CLEAR_PERIODIC_MSGS: {ret}")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_PERIODIC_MSGS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Ошибка CLEAR_PERIODIC_MSGS: {ret}");
CLEAR_MSG_FILTERS — Очистка фильтров
Удаляет все фильтры сообщений, установленные через PassThruStartMsgFilter. После вызова все входящие сообщения будут блокироваться до установки новых фильтров.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID;
long ret;
ret = PassThruIoctl(ChannelID, CLEAR_MSG_FILTERS, NULL, NULL);
if (ret != STATUS_NOERROR)
{
char error[256];
PassThruGetLastError(error);
printf("Ошибка: %s\n", error);
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_MSG_FILTERS, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Ошибка CLEAR_MSG_FILTERS: ${result.status}")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_MSG_FILTERS, None, None)
if ret != 0:
print(f"Ошибка CLEAR_MSG_FILTERS: {ret}")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_MSG_FILTERS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Ошибка CLEAR_MSG_FILTERS: {ret}");
Очищает таблицу функциональных адресов J1850. Используется для протоколов J1850 PWM/VPW при работе с функциональной адресацией.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал J1850
long ret;
ret = PassThruIoctl(ChannelID, CLEAR_FUNCT_MSG_LOOKUP_TABLE, NULL, NULL);
if (ret != STATUS_NOERROR)
{
// Обработка ошибки
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_FUNCT_MSG_LOOKUP_TABLE, None, None)
Пример на C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_FUNCT_MSG_LOOKUP_TABLE, IntPtr.Zero, IntPtr.Zero);
var addrList = new SBYTE_ARRAY {
NumOfBytes = 1,
BytePtr = new byte[] { 0x10 }
};
int ret = J2534.PassThruIoctl(channelId, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, ref addrList, IntPtr.Zero);
SW_CAN_HS — Высокоскоростной режим SW-CAN
Переключает Single-Wire CAN в высокоскоростной режим (83.3 кбит/с). Используется для диагностики на высокой скорости в сетях GM.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал SW-CAN
long ret;
// Переключение в высокоскоростной режим
ret = PassThruIoctl(ChannelID, SW_CAN_HS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("SW-CAN в режиме High Speed (83.3 kbit/s)\n");
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, SW_CAN_HS, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "SW-CAN в режиме High Speed (83.3 kbit/s)")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, SW_CAN_HS, None, None)
if ret == 0:
print("SW-CAN в режиме High Speed (83.3 kbit/s)")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, SW_CAN_HS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("SW-CAN в режиме High Speed (83.3 kbit/s)");
SW_CAN_NS — Нормальный режим SW-CAN
Переключает Single-Wire CAN в нормальный режим (33.3 кбит/с). Это режим по умолчанию для сетей GM.
pInput
NULL
pOutput
NULL
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал SW-CAN
long ret;
// Переключение в нормальный режим
ret = PassThruIoctl(ChannelID, SW_CAN_NS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("SW-CAN в режиме Normal Speed (33.3 kbit/s)\n");
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, SW_CAN_NS, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "SW-CAN в режиме Normal Speed (33.3 kbit/s)")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, SW_CAN_NS, None, None)
if ret == 0:
print("SW-CAN в режиме Normal Speed (33.3 kbit/s)")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, SW_CAN_NS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("SW-CAN в режиме Normal Speed (33.3 kbit/s)");
BUS_ON — Подключение контроллера к шине v5.0
Подключает CAN-контроллер к физической шине. Используется после отключения контроллера от шины через PassThruDisconnect с флагом CAN_DISCONNECT или после открытия канала без автоматического подключения.
IoctlID
0x0F
pInput
NULL
pOutput
NULL
Эта команда доступна только в J2534 v5.00. В v04.04 контроллер подключается к шине автоматически при PassThruConnect.
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал CAN
long ret;
// Подключение контроллера к шине
ret = PassThruIoctl(ChannelID, BUS_ON, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("CAN-контроллер подключён к шине\n");
}
Пример на Kotlin (Android)
val result = j2534.ptIoctl(channelID, BUS_ON, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "CAN-контроллер подключён к шине")
}
Пример на Python
ret = j2534.PassThruIoctl(channel_id, BUS_ON, None, None)
if ret == 0:
print("CAN-контроллер подключён к шине")
Пример на C#
int ret = J2534.PassThruIoctl(channelId, BUS_ON, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("CAN-контроллер подключён к шине");
REQUEST_CONNECTION — Установление TP 2.0 соединения J2534-2
Запрашивает установление канала и соединения TP 2.0 между адаптером и ЭБУ. Используется для протокола TP 2.0 (VAG). Команда неблокирующая — результат соединения приходит как индикация в очередь приёма.
IoctlID
0x800A
pInput
SBYTE_ARRAY* — данные запроса соединения (11 байт)
pOutput
NULL
Структура данных (11 байт)
BytePtr[0-3]
CAN ID (идентификатор), BytePtr[0] — старший байт
BytePtr[4]
Destination — адрес назначения (ECU)
BytePtr[5]
Opcode — всегда 0xC0
BytePtr[6-7]
TX-ID-A — CAN ID для передачи
BytePtr[8-9]
RX-ID-A — CAN ID для приёма
BytePtr[10]
Application Type — тип приложения
При успешном соединении создаётся неявный PASS-фильтр для RX-ID-A. В очередь приёма помещается индикация CONNECTION_ESTABLISHED. При ошибке — CONNECTION_LOST.
Если RX-ID-A уже используется другим каналом, возвращается ERR_NOT_UNIQUE. Если NumOfBytes ≠ 11, возвращается ERR_INVALID_IOCTL_VALUE.
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[11];
long ret;
// CAN ID для broadcast: 0x200
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x02;
data[3] = 0x00;
// Destination (адрес ECU, например 0x01 для двигателя)
data[4] = 0x01;
// Opcode (всегда 0xC0)
data[5] = 0xC0;
// TX-ID-A (CAN ID для передачи, например 0x300)
data[6] = 0x03;
data[7] = 0x00;
// RX-ID-A (CAN ID для приёма, например 0x301)
data[8] = 0x03;
data[9] = 0x01;
// Application Type (0x01 для диагностики)
data[10] = 0x01;
InputData.NumOfBytes = 11;
InputData.BytePtr = data;
ret = PassThruIoctl(ChannelID, REQUEST_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
printf("Запрос соединения отправлен, ожидаем CONNECTION_ESTABLISHED\n");
}
else if (ret == ERR_NOT_UNIQUE)
{
printf("RX-ID-A уже используется другим каналом\n");
}
Пример на Kotlin (Android)
// channelID — канал TP 2.0
val data = byteArrayOf(
0x00, 0x00, 0x02, 0x00, // CAN ID: 0x200
0x01, // Destination: ECU 0x01
0xC0.toByte(), // Opcode
0x03, 0x00, // TX-ID-A: 0x300
0x03, 0x01, // RX-ID-A: 0x301
0x01 // Application Type
)
val result = j2534.ptIoctl(channelID, REQUEST_CONNECTION, data.size, data)
when (result.status) {
STATUS_NOERROR -> Log.i("TP2.0", "Запрос соединения отправлен")
ERR_NOT_UNIQUE -> Log.e("TP2.0", "RX-ID-A уже используется")
else -> Log.e("TP2.0", "Ошибка: ${result.status}")
}
Пример на Python
from ctypes import *
data = (c_ubyte * 11)(
0x00, 0x00, 0x02, 0x00, # CAN ID: 0x200
0x01, # Destination: ECU 0x01
0xC0, # Opcode
0x03, 0x00, # TX-ID-A: 0x300
0x03, 0x01, # RX-ID-A: 0x301
0x01 # Application Type
)
input_data = SBYTE_ARRAY()
input_data.NumOfBytes = 11
input_data.BytePtr = data
ret = j2534.PassThruIoctl(channel_id, REQUEST_CONNECTION, byref(input_data), None)
if ret == 0:
print("Запрос соединения отправлен, ожидаем CONNECTION_ESTABLISHED")
elif ret == ERR_NOT_UNIQUE:
print("RX-ID-A уже используется другим каналом")
Пример на C#
var data = new byte[] {
0x00, 0x00, 0x02, 0x00, // CAN ID: 0x200
0x01, // Destination: ECU 0x01
0xC0, // Opcode
0x03, 0x00, // TX-ID-A: 0x300
0x03, 0x01, // RX-ID-A: 0x301
0x01 // Application Type
};
var inputData = new SBYTE_ARRAY {
NumOfBytes = 11,
BytePtr = data
};
int ret = J2534.PassThruIoctl(channelId, REQUEST_CONNECTION, ref inputData, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("Запрос соединения отправлен, ожидаем CONNECTION_ESTABLISHED");
else if (ret == ERR_NOT_UNIQUE)
Console.WriteLine("RX-ID-A уже используется другим каналом");
TEARDOWN_CONNECTION — Разрыв TP 2.0 соединения J2534-2
Разрывает установленное соединение TP 2.0 между адаптером и ЭБУ. Команда неблокирующая — подтверждение разрыва приходит как индикация CONNECTION_LOST в очередь приёма.
IoctlID
0x800B
pInput
SBYTE_ARRAY* — CAN ID приёма (4 байта)
pOutput
NULL
Структура данных (4 байта)
BytePtr[0-3]
RX-ID-A — CAN ID для приёма (тот же, что в REQUEST_CONNECTION), BytePtr[0] — старший байт
После разрыва соединения неявный PASS-фильтр для RX-ID-A удаляется. Фильтры, установленные через PassThruStartMsgFilter, остаются активными.
Пример на C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Канал TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[4];
long ret;
// RX-ID-A (тот же, что был в REQUEST_CONNECTION)
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x03;
data[3] = 0x01; // 0x301
InputData.NumOfBytes = 4;
InputData.BytePtr = data;
ret = PassThruIoctl(ChannelID, TEARDOWN_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
printf("Запрос разрыва соединения отправлен\n");
}
Пример на Kotlin (Android)
// RX-ID-A: 0x301
val data = byteArrayOf(0x00, 0x00, 0x03, 0x01)
val result = j2534.ptIoctl(channelID, TEARDOWN_CONNECTION, data.size, data)
if (result.status == STATUS_NOERROR) {
Log.i("TP2.0", "Запрос разрыва соединения отправлен")
}
Пример на Python
from ctypes import *
# RX-ID-A: 0x301
data = (c_ubyte * 4)(0x00, 0x00, 0x03, 0x01)
input_data = SBYTE_ARRAY()
input_data.NumOfBytes = 4
input_data.BytePtr = data
ret = j2534.PassThruIoctl(channel_id, TEARDOWN_CONNECTION, byref(input_data), None)
if ret == 0:
print("Запрос разрыва соединения отправлен")
Пример на C#
// RX-ID-A: 0x301
var data = new byte[] { 0x00, 0x00, 0x03, 0x01 };
var inputData = new SBYTE_ARRAY {
NumOfBytes = 4,
BytePtr = data
};
int ret = J2534.PassThruIoctl(channelId, TEARDOWN_CONNECTION, ref inputData, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("Запрос разрыва соединения отправлен");