Uniwersalna funkcja zarządzania urządzeniem i kanałem. Wykonuje różne operacje w zależności od parametru IoctlID: odczyt/zapis konfiguracji, inicjalizacja protokołów, czyszczenie buforów i inne operacje pomocnicze.
long PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)
Parametry
unsigned long ChannelID — identyfikator kanału uzyskany z PassThruConnect. Dla niektórych poleceń (READ_VBATT, GET_DEVICE_INFO) używany jest DeviceID.
unsigned long IoctlID — identyfikator operacji (zob. tabelę poniżej).
void* pInput — wskaźnik na dane wejściowe. Typ zależy od IoctlID.
void* pOutput — wskaźnik na dane wyjściowe. Typ zależy od IoctlID.
Rozwiązanie: sprawdź zasilanie adaptera i połączenie sieciowe
ERR_INVALID_CHANNEL_ID
Nieprawidłowy identyfikator kanału
ChannelID nie został uzyskany przez PassThruConnect lub kanał jest zamknięty
Rozwiązanie: upewnij się, że PassThruConnect zakończył się pomyślnie
ERR_INVALID_IOCTL_ID
Nieprawidłowy identyfikator IoctlID
Podany IoctlID nie jest obsługiwany
Rozwiązanie: sprawdź poprawność wartości IoctlID
ERR_NULL_PARAMETER
Przekazano NULL zamiast wymaganego wskaźnika
pInput lub pOutput jest równy NULL, gdy wymagany jest wskaźnik
Rozwiązanie: przekaż poprawne wskaźniki
ERR_NOT_SUPPORTED
Operacja nieobsługiwana
Adapter nie obsługuje żądanej operacji
Rozwiązanie: sprawdź możliwości adaptera przez GET_DEVICE_INFO
ERR_INVALID_IOCTL_VALUE
Niedopuszczalna wartość parametru
Wartość w pInput wykracza poza dopuszczalne granice
Rozwiązanie: sprawdź dopuszczalne zakresy wartości
ERR_INVALID_MSG
Nieprawidłowa struktura komunikatu
Błędna struktura w pInput dla FAST_INIT
Rozwiązanie: sprawdź poprawność pól PASSTHRU_MSG
ERR_FAILED
Nieokreślony błąd
Wewnętrzny błąd biblioteki lub adaptera
Rozwiązanie: wywołaj PassThruGetLastError(), aby uzyskać opis
READ_VBATT — Odczyt napięcia zasilania
Zwraca napięcie na złączu OBD-II (styk 16). Wartość w miliwoltach, aby uzyskać wolty, podziel przez 1000. Polecenie nie wymaga otwartego kanału i może być wykonane od razu po PassThruOpen.
pInput
NULL
pOutput
unsigned long* — napięcie w mV
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long DeviceID; // Uzyskany z PassThruOpen
unsigned long voltage;
long ret;
ret = PassThruIoctl(DeviceID, READ_VBATT, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
printf("Napięcie: %.2f V\n", voltage / 1000.0);
}
Przykład w Kotlin (Android)
// deviceID uzyskany wcześniej z ptOpen
val result = j2534.ptIoctl(deviceID, READ_VBATT, 0, null)
if (result.status == STATUS_NOERROR) {
val voltageV = result.outputValue / 1000.0
Log.i("J2534", "Napięcie: ${"%.2f".format(voltageV)} V")
}
Przykład w Python
from ctypes import *
voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_VBATT, None, byref(voltage))
if ret == 0: # STATUS_NOERROR
print(f"Napięcie: {voltage.value / 1000:.2f} V")
Przykład w C#
uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_VBATT, IntPtr.Zero, out voltage);
if (ret == 0)
{
Console.WriteLine($"Napięcie: {voltage / 1000.0:F2} V");
}
READ_PROG_VOLTAGE — Odczyt napięcia programowania
Zwraca bieżące napięcie na wyjściu programowania. Wartość w miliwoltach, zaokrąglona do najbliższej dziesiątej części wolta.
pInput
NULL
pOutput
unsigned long* — napięcie w mV
Przykład w 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("Napięcie programowania: %.2f V\n", voltage / 1000.0);
}
Przykład w 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", "Napięcie programowania: ${"%.2f".format(voltageV)} V")
}
Przykład w Python
from ctypes import *
voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_PROG_VOLTAGE, None, byref(voltage))
if ret == 0:
print(f"Napięcie programowania: {voltage.value / 1000:.2f} V")
Przykład w C#
uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_PROG_VOLTAGE, IntPtr.Zero, out voltage);
if (ret == 0)
{
Console.WriteLine($"Napięcie programowania: {voltage / 1000.0:F2} V");
}
FIVE_BAUD_INIT — Inicjalizacja 5-bodowa
Uruchamia wolną (5 bodów) inicjalizację dla protokołów ISO 9141 i ISO 14230 (K-Line). Odbiera KeyWord od ECU. Tryb inicjalizacji ustawiany jest parametrem FIVE_BAUD_MOD przez SET_CONFIG. Prędkość transmisji jest określana automatycznie.
pInput
SBYTE_ARRAY* — adres inicjalizacji (1 bajt)
pOutput
SBYTE_ARRAY* — KeyWord (2 bajty)
Parametr FIVE_BAUD_MOD określa tryb inicjalizacji: ISO9141-2/ISO14230-4 (0), inwersja KB2 (1), inwersja adresu (2), ISO9141 bez inwersji (3).
// channelID uzyskany z ptConnect dla ISO14230
val initAddress = byteArrayOf(0x33) // Adres inicjalizacji
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 } // Adres inicjalizacji
};
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 — Inicjalizacja Fast
Uruchamia szybką inicjalizację dla protokołu ISO 14230 (K-Line). Wysyła żądanie StartCommunication i zwraca odpowiedź ECU. Używana dla KWP2000.
pInput
PASSTHRU_MSG* — żądanie inicjalizacji
pOutput
PASSTHRU_MSG* — odpowiedź ECU
Ważne: Przy adresie funkcjonalnym (rozgłoszeniowym) na żądanie może odpowiedzieć kilka ECU. W pOutput znajdzie się tylko pierwsza odpowiedź, pozostałe trafią do kolejki odbiorczej.
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Uzyskany z PassThruConnect
PASSTHRU_MSG InputMsg;
PASSTHRU_MSG OutputMsg;
long ret;
// Żądanie StartCommunication
InputMsg.ProtocolID = ISO14230;
InputMsg.TxFlags = 0;
InputMsg.DataSize = 4;
InputMsg.Data[0] = 0x81; // Format: adres fizyczny, 1 bajt danych
InputMsg.Data[1] = 0x10; // Adres docelowy (ECU)
InputMsg.Data[2] = 0xF1; // Adres źródłowy (tester)
InputMsg.Data[3] = 0x81; // SID: StartCommunication
ret = PassThruIoctl(ChannelID, FAST_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
printf("Odpowiedź ECU: %d bajtów\n", OutputMsg.DataSize);
for (int i = 0; i < OutputMsg.DataSize; i++)
printf("%02X ", OutputMsg.Data[i]);
}
Przykład w Kotlin (Android)
// channelID uzyskany z ptConnect dla 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", "Odpowiedź ECU: ${result.response.data.toHexString()}")
}
Przykład w 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 # Format
input_msg.Data[1] = 0x10 # Adres docelowy
input_msg.Data[2] = 0xF1 # Adres źródłowy
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"Odpowiedź ECU: {data.hex(' ').upper()}")
Przykład w C#
var inputMsg = new PASSTHRU_MSG {
ProtocolID = ISO14230,
TxFlags = 0,
DataSize = 4
};
inputMsg.Data[0] = 0x81; // Format
inputMsg.Data[1] = 0x10; // Adres docelowy
inputMsg.Data[2] = 0xF1; // Adres źródłowy
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($"Odpowiedź ECU: {BitConverter.ToString(data).Replace("-", " ")}");
}
CLEAR_TX_BUFFER — Czyszczenie kolejki nadawczej
Usuwa wszystkie komunikaty z kolejki nadawczej kanału. Używane do anulowania zaplanowanych transmisji.
pInput
NULL
pOutput
NULL
Przykład w 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("Błąd: %s\n", error);
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_TX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Błąd CLEAR_TX_BUFFER: ${result.status}")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_TX_BUFFER, None, None)
if ret != 0:
print(f"Błąd CLEAR_TX_BUFFER: {ret}")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_TX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Błąd CLEAR_TX_BUFFER: {ret}");
CLEAR_RX_BUFFER — Czyszczenie kolejki odbiorczej
Usuwa wszystkie komunikaty z kolejki odbiorczej kanału. Zaleca się wywoływanie przed rozpoczęciem nowej sesji diagnostycznej.
pInput
NULL
pOutput
NULL
Przykład w 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("Błąd: %s\n", error);
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_RX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Błąd CLEAR_RX_BUFFER: ${result.status}")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_RX_BUFFER, None, None)
if ret != 0:
print(f"Błąd CLEAR_RX_BUFFER: {ret}")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_RX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Błąd CLEAR_RX_BUFFER: {ret}");
Usuwa wszystkie komunikaty okresowe ustawione przez PassThruStartPeriodicMsg. Równoważne wywołaniu PassThruStopPeriodicMsg dla każdego komunikatu.
pInput
NULL
pOutput
NULL
Przykład w 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("Błąd: %s\n", error);
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_PERIODIC_MSGS, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Błąd CLEAR_PERIODIC_MSGS: ${result.status}")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_PERIODIC_MSGS, None, None)
if ret != 0:
print(f"Błąd CLEAR_PERIODIC_MSGS: {ret}")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_PERIODIC_MSGS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Błąd CLEAR_PERIODIC_MSGS: {ret}");
CLEAR_MSG_FILTERS — Czyszczenie filtrów
Usuwa wszystkie filtry komunikatów ustawione przez PassThruStartMsgFilter. Po wywołaniu wszystkie przychodzące komunikaty będą blokowane do czasu ustawienia nowych filtrów.
pInput
NULL
pOutput
NULL
Przykład w 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("Błąd: %s\n", error);
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, CLEAR_MSG_FILTERS, 0, null)
if (result.status != STATUS_NOERROR) {
Log.e("J2534", "Błąd CLEAR_MSG_FILTERS: ${result.status}")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, CLEAR_MSG_FILTERS, None, None)
if ret != 0:
print(f"Błąd CLEAR_MSG_FILTERS: {ret}")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, CLEAR_MSG_FILTERS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
Console.WriteLine($"Błąd CLEAR_MSG_FILTERS: {ret}");
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 — Tryb wysokiej prędkości SW-CAN
Przełącza Single-Wire CAN w tryb wysokiej prędkości (83.3 kbit/s). Używany do diagnostyki z dużą prędkością w sieciach GM.
pInput
NULL
pOutput
NULL
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Kanał SW-CAN
long ret;
// Przełączenie w tryb wysokiej prędkości
ret = PassThruIoctl(ChannelID, SW_CAN_HS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("SW-CAN w trybie High Speed (83.3 kbit/s)\n");
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, SW_CAN_HS, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "SW-CAN w trybie High Speed (83.3 kbit/s)")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, SW_CAN_HS, None, None)
if ret == 0:
print("SW-CAN w trybie High Speed (83.3 kbit/s)")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, SW_CAN_HS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("SW-CAN w trybie High Speed (83.3 kbit/s)");
SW_CAN_NS — Tryb normalny SW-CAN
Przełącza Single-Wire CAN w tryb normalny (33.3 kbit/s). Jest to tryb domyślny dla sieci GM.
pInput
NULL
pOutput
NULL
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Kanał SW-CAN
long ret;
// Przełączenie w tryb normalny
ret = PassThruIoctl(ChannelID, SW_CAN_NS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("SW-CAN w trybie Normal Speed (33.3 kbit/s)\n");
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, SW_CAN_NS, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "SW-CAN w trybie Normal Speed (33.3 kbit/s)")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, SW_CAN_NS, None, None)
if ret == 0:
print("SW-CAN w trybie Normal Speed (33.3 kbit/s)")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, SW_CAN_NS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("SW-CAN w trybie Normal Speed (33.3 kbit/s)");
BUS_ON — Podłączenie kontrolera do magistrali v5.0
Podłącza kontroler CAN do magistrali fizycznej. Używane po odłączeniu kontrolera od magistrali przez PassThruDisconnect z flagą CAN_DISCONNECT lub po otwarciu kanału bez automatycznego podłączenia.
IoctlID
0x0F
pInput
NULL
pOutput
NULL
To polecenie jest dostępne tylko w J2534 v5.00. W v04.04 kontroler podłącza się do magistrali automatycznie przy PassThruConnect.
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Kanał CAN
long ret;
// Podłączenie kontrolera do magistrali
ret = PassThruIoctl(ChannelID, BUS_ON, NULL, NULL);
if (ret == STATUS_NOERROR)
{
printf("Kontroler CAN podłączony do magistrali\n");
}
Przykład w Kotlin (Android)
val result = j2534.ptIoctl(channelID, BUS_ON, 0, null)
if (result.status == STATUS_NOERROR) {
Log.i("J2534", "Kontroler CAN podłączony do magistrali")
}
Przykład w Python
ret = j2534.PassThruIoctl(channel_id, BUS_ON, None, None)
if ret == 0:
print("Kontroler CAN podłączony do magistrali")
Przykład w C#
int ret = J2534.PassThruIoctl(channelId, BUS_ON, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
Console.WriteLine("Kontroler CAN podłączony do magistrali");
REQUEST_CONNECTION — Nawiązanie połączenia TP 2.0 J2534-2
Żąda nawiązania kanału i połączenia TP 2.0 między adapterem a ECU. Używane dla protokołu TP 2.0 (VAG). Polecenie nieblokujące — wynik połączenia przychodzi jako wskazanie do kolejki odbiorczej.
IoctlID
0x800A
pInput
SBYTE_ARRAY* — dane żądania połączenia (11 bajtów)
pOutput
NULL
Struktura danych (11 bajtów)
BytePtr[0-3]
CAN ID (identyfikator), BytePtr[0] — starszy bajt
BytePtr[4]
Destination — adres docelowy (ECU)
BytePtr[5]
Opcode — zawsze 0xC0
BytePtr[6-7]
TX-ID-A — CAN ID do nadawania
BytePtr[8-9]
RX-ID-A — CAN ID do odbioru
BytePtr[10]
Application Type — typ aplikacji
Przy pomyślnym połączeniu tworzony jest niejawny filtr PASS dla RX-ID-A. Do kolejki odbiorczej trafia wskazanie CONNECTION_ESTABLISHED. Przy błędzie — CONNECTION_LOST.
Jeśli RX-ID-A jest już używany przez inny kanał, zwracany jest ERR_NOT_UNIQUE. Jeśli NumOfBytes ≠ 11, zwracany jest ERR_INVALID_IOCTL_VALUE.
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Kanał TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[11];
long ret;
// CAN ID dla broadcast: 0x200
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x02;
data[3] = 0x00;
// Destination (adres ECU, np. 0x01 dla silnika)
data[4] = 0x01;
// Opcode (zawsze 0xC0)
data[5] = 0xC0;
// TX-ID-A (CAN ID do nadawania, np. 0x300)
data[6] = 0x03;
data[7] = 0x00;
// RX-ID-A (CAN ID do odbioru, np. 0x301)
data[8] = 0x03;
data[9] = 0x01;
// Application Type (0x01 dla diagnostyki)
data[10] = 0x01;
InputData.NumOfBytes = 11;
InputData.BytePtr = data;
ret = PassThruIoctl(ChannelID, REQUEST_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
printf("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED\n");
}
else if (ret == ERR_NOT_UNIQUE)
{
printf("RX-ID-A jest już używany przez inny kanał\n");
}
Przykład w Kotlin (Android)
// channelID — kanał 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", "Żądanie połączenia wysłane")
ERR_NOT_UNIQUE -> Log.e("TP2.0", "RX-ID-A jest już używany")
else -> Log.e("TP2.0", "Błąd: ${result.status}")
}
Przykład w 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("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED")
elif ret == ERR_NOT_UNIQUE:
print("RX-ID-A jest już używany przez inny kanał")
Przykład w 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("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED");
else if (ret == ERR_NOT_UNIQUE)
Console.WriteLine("RX-ID-A jest już używany przez inny kanał");
TEARDOWN_CONNECTION — Zerwanie połączenia TP 2.0 J2534-2
Zrywa nawiązane połączenie TP 2.0 między adapterem a ECU. Polecenie nieblokujące — potwierdzenie zerwania przychodzi jako wskazanie CONNECTION_LOST do kolejki odbiorczej.
IoctlID
0x800B
pInput
SBYTE_ARRAY* — CAN ID odbioru (4 bajty)
pOutput
NULL
Struktura danych (4 bajty)
BytePtr[0-3]
RX-ID-A — CAN ID do odbioru (ten sam, co w REQUEST_CONNECTION), BytePtr[0] — starszy bajt
Po zerwaniu połączenia niejawny filtr PASS dla RX-ID-A jest usuwany. Filtry ustawione przez PassThruStartMsgFilter pozostają aktywne.
Przykład w C/C++
#include "j2534_dll.hpp"
unsigned long ChannelID; // Kanał TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[4];
long ret;
// RX-ID-A (ten sam, co był w 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("Żądanie zerwania połączenia wysłane\n");
}
Przykład w 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", "Żądanie zerwania połączenia wysłane")
}
Przykład w 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("Żądanie zerwania połączenia wysłane")
Przykład w 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("Żądanie zerwania połączenia wysłane");