Quantex GmbH
Votre région : Europe

PassThruIoctl v4.04 v5.0

Gestion des entrées/sorties

Dernière modification :

Description

Fonction universelle de gestion du dispositif et du canal. Elle exécute différentes opérations selon le paramètre IoctlID : lecture/écriture de la configuration, initialisation des protocoles, vidage des tampons et autres opérations de service.

long PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)

Paramètres

IoctlID Valeur Description
GET_CONFIG 0x01 Lecture des paramètres du protocole
SET_CONFIG 0x02 Écriture des paramètres du protocole
READ_VBATT 0x03 Lecture de la tension d'alimentation
FIVE_BAUD_INIT 0x04 Initialisation à 5 bauds de K-Line
FAST_INIT 0x05 Initialisation Fast de K-Line
CLEAR_TX_BUFFER 0x07 Vidage de la file de transmission
CLEAR_RX_BUFFER 0x08 Vidage de la file de réception
CLEAR_PERIODIC_MSGS 0x09 Vidage des messages périodiques
CLEAR_MSG_FILTERS 0x0A Vidage de tous les filtres
CLEAR_FUNCT_MSG_LOOKUP_TABLE 0x0B Vidage de la table des adresses fonctionnelles
ADD_TO_FUNCT_MSG_LOOKUP_TABLE 0x0C Ajout à la table des adresses fonctionnelles
DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE 0x0D Suppression de la table des adresses fonctionnelles
READ_PROG_VOLTAGE 0x0E Lecture de la tension de programmation
SW_CAN_HS 0x8000 Commutation de SW-CAN en mode haute vitesse
SW_CAN_NS 0x8001 Commutation de SW-CAN en mode normal
BUS_ON v5.0 0x0F Connexion du contrôleur CAN au bus
REQUEST_CONNECTION J2534-2 0x800A Établissement de la connexion TP 2.0
TEARDOWN_CONNECTION J2534-2 0x800B Fermeture de la connexion TP 2.0
GET_DEVICE_INFO J2534-2 0x800C Obtention des informations sur le dispositif
GET_PROTOCOL_INFO J2534-2 0x800D Obtention des informations sur le protocole
ISO13400_PS Quantex 0x8110-0x8113 Commandes DoIP (Diagnostics over IP)

Codes d'erreur retournés

Code Description Causes possibles et solutions
STATUS_NOERROR Fonction exécutée avec succès
ERR_DEVICE_NOT_CONNECTED Aucune connexion avec l'adaptateur
  • L'adaptateur est éteint ou hors de portée
  • Solution : vérifiez l'alimentation de l'adaptateur et la connexion réseau
ERR_INVALID_CHANNEL_ID Identifiant de canal non valide
  • Le ChannelID n'a pas été obtenu via PassThruConnect ou le canal est fermé
  • Solution : assurez-vous que PassThruConnect s'est exécuté avec succès
ERR_INVALID_IOCTL_ID Identifiant IoctlID non valide
  • L'IoctlID indiqué n'est pas pris en charge
  • Solution : vérifiez que la valeur de IoctlID est correcte
ERR_NULL_PARAMETER NULL a été transmis à la place d'un pointeur obligatoire
  • pInput ou pOutput est égal à NULL alors qu'un pointeur est requis
  • Solution : transmettez des pointeurs corrects
ERR_NOT_SUPPORTED Opération non prise en charge
  • L'adaptateur ne prend pas en charge l'opération demandée
  • Solution : vérifiez les capacités de l'adaptateur via GET_DEVICE_INFO
ERR_INVALID_IOCTL_VALUE Valeur de paramètre non admise
  • La valeur de pInput est en dehors des limites autorisées
  • Solution : vérifiez les plages de valeurs autorisées
ERR_INVALID_MSG Structure de message incorrecte
  • Structure incorrecte dans pInput pour FAST_INIT
  • Solution : vérifiez que les champs de PASSTHRU_MSG sont corrects
ERR_FAILED Erreur indéterminée
  • Erreur interne de la bibliothèque ou de l'adaptateur
  • Solution : appelez PassThruGetLastError() pour obtenir la description

READ_VBATT — Lecture de la tension d'alimentation

Retourne la tension sur le connecteur OBD-II (broche 16). La valeur est exprimée en millivolts ; pour obtenir des volts, divisez-la par 1000. La commande ne nécessite pas de canal ouvert et peut être exécutée immédiatement après PassThruOpen.

pInput NULL
pOutput unsigned long* — tension en mV

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long DeviceID;  // Obtenu de PassThruOpen
unsigned long voltage;
long ret;

ret = PassThruIoctl(DeviceID, READ_VBATT, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
    printf("Tension : %.2f V\n", voltage / 1000.0);
}

Exemple en Kotlin (Android)

// deviceID obtenu précédemment de ptOpen
val result = j2534.ptIoctl(deviceID, READ_VBATT, 0, null)
if (result.status == STATUS_NOERROR) {
    val voltageV = result.outputValue / 1000.0
    Log.i("J2534", "Tension : ${"%.2f".format(voltageV)} V")
}

Exemple en Python

from ctypes import *

voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_VBATT, None, byref(voltage))
if ret == 0:  # STATUS_NOERROR
    print(f"Tension : {voltage.value / 1000:.2f} V")

Exemple en C#

uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_VBATT, IntPtr.Zero, out voltage);
if (ret == 0)
{
    Console.WriteLine($"Tension : {voltage / 1000.0:F2} V");
}

READ_PROG_VOLTAGE — Lecture de la tension de programmation

Retourne la tension actuelle sur la sortie de programmation. La valeur est exprimée en millivolts, arrondie au dixième de volt le plus proche.

pInput NULL
pOutput unsigned long* — tension en mV

Exemple en 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("Tension de programmation : %.2f V\n", voltage / 1000.0);
}

Exemple en 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", "Tension de programmation : ${"%.2f".format(voltageV)} V")
}

Exemple en Python

from ctypes import *

voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_PROG_VOLTAGE, None, byref(voltage))
if ret == 0:
    print(f"Tension de programmation : {voltage.value / 1000:.2f} V")

Exemple en C#

uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_PROG_VOLTAGE, IntPtr.Zero, out voltage);
if (ret == 0)
{
    Console.WriteLine($"Tension de programmation : {voltage / 1000.0:F2} V");
}

FIVE_BAUD_INIT — Initialisation à 5 bauds

Lance l'initialisation lente (5 bauds) pour les protocoles ISO 9141 et ISO 14230 (K-Line). Reçoit le KeyWord de l'ECU. Le mode d'initialisation est défini par le paramètre FIVE_BAUD_MOD via SET_CONFIG. La vitesse d'échange est déterminée automatiquement.

pInput SBYTE_ARRAY* — adresse d'initialisation (1 byte)
pOutput SBYTE_ARRAY* — KeyWord (2 bytes)
Le paramètre FIVE_BAUD_MOD détermine le mode d'initialisation : ISO9141-2/ISO14230-4 (0), inversion de KB2 (1), inversion de l'adresse (2), ISO9141 sans inversion (3).

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Obtenu de PassThruConnect
SBYTE_ARRAY InputMsg;
SBYTE_ARRAY OutputMsg;
long ret;

unsigned char initByte[1];
unsigned char keyWord[2];

initByte[0] = 0x33;  // Adresse d'initialisation de l'ECU

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]);
}

Exemple en Kotlin (Android)

// channelID obtenu de ptConnect pour ISO14230
val initAddress = byteArrayOf(0x33)  // Adresse d'initialisation

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()}")
}

Exemple en Python

from ctypes import *

input_msg = SBYTE_ARRAY()
input_msg.NumOfBytes = 1
input_msg.BytePtr = (c_ubyte * 1)(0x33)

output_msg = SBYTE_ARRAY()
output_msg.NumOfBytes = 2
keyword = (c_ubyte * 2)()
output_msg.BytePtr = keyword

ret = j2534.PassThruIoctl(channel_id, FIVE_BAUD_INIT, byref(input_msg), byref(output_msg))
if ret == 0:
    print(f"KeyWord: {keyword[0]:02X} {keyword[1]:02X}")

Exemple en C#

var inputMsg = new SBYTE_ARRAY {
    NumOfBytes = 1,
    BytePtr = new byte[] { 0x33 }  // Adresse d'initialisation
};

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 — Initialisation Fast

Lance l'initialisation rapide pour le protocole ISO 14230 (K-Line). Envoie la requête StartCommunication et retourne la réponse de l'ECU. Utilisée pour KWP2000.

pInput PASSTHRU_MSG* — requête d'initialisation
pOutput PASSTHRU_MSG* — réponse de l'ECU
Important : Avec une adresse fonctionnelle (de diffusion), plusieurs ECU peuvent répondre à la requête. Dans pOutput, seule la première réponse sera présente ; les autres seront placées dans la file de réception.

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Obtenu de PassThruConnect
PASSTHRU_MSG InputMsg;
PASSTHRU_MSG OutputMsg;
long ret;

// Requête StartCommunication
InputMsg.ProtocolID = ISO14230;
InputMsg.TxFlags = 0;
InputMsg.DataSize = 4;
InputMsg.Data[0] = 0x81;  // Format : adresse physique, 1 byte de données
InputMsg.Data[1] = 0x10;  // Adresse de destination (ECU)
InputMsg.Data[2] = 0xF1;  // Adresse de source (testeur)
InputMsg.Data[3] = 0x81;  // SID: StartCommunication

ret = PassThruIoctl(ChannelID, FAST_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
    printf("Réponse de l'ECU : %d bytes\n", OutputMsg.DataSize);
    for (int i = 0; i < OutputMsg.DataSize; i++)
        printf("%02X ", OutputMsg.Data[i]);
}

Exemple en Kotlin (Android)

// channelID obtenu de ptConnect pour 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", "Réponse de l'ECU : ${result.response.data.toHexString()}")
}

Exemple en 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  # Adresse de destination
input_msg.Data[2] = 0xF1  # Adresse de source
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"Réponse de l'ECU : {data.hex(' ').upper()}")

Exemple en C#

var inputMsg = new PASSTHRU_MSG {
    ProtocolID = ISO14230,
    TxFlags = 0,
    DataSize = 4
};
inputMsg.Data[0] = 0x81;  // Format
inputMsg.Data[1] = 0x10;  // Adresse de destination
inputMsg.Data[2] = 0xF1;  // Adresse de source
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($"Réponse de l'ECU : {BitConverter.ToString(data).Replace("-", " ")}");
}

CLEAR_TX_BUFFER — Vidage de la file de transmission

Supprime tous les messages de la file de transmission du canal. Utilisée pour annuler les transmissions planifiées.

pInput NULL
pOutput NULL

Exemple en 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("Erreur : %s\n", error);
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_TX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Erreur CLEAR_TX_BUFFER: ${result.status}")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_TX_BUFFER, None, None)
if ret != 0:
    print(f"Erreur CLEAR_TX_BUFFER: {ret}")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_TX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Erreur CLEAR_TX_BUFFER: {ret}");

CLEAR_RX_BUFFER — Vidage de la file de réception

Supprime tous les messages de la file de réception du canal. Il est recommandé de l'appeler avant de démarrer une nouvelle session de diagnostic.

pInput NULL
pOutput NULL

Exemple en 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("Erreur : %s\n", error);
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_RX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Erreur CLEAR_RX_BUFFER: ${result.status}")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_RX_BUFFER, None, None)
if ret != 0:
    print(f"Erreur CLEAR_RX_BUFFER: {ret}")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_RX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Erreur CLEAR_RX_BUFFER: {ret}");

CLEAR_PERIODIC_MSGS — Vidage des messages périodiques

Supprime tous les messages périodiques établis via PassThruStartPeriodicMsg. Équivaut à appeler PassThruStopPeriodicMsg pour chaque message.

pInput NULL
pOutput NULL

Exemple en 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("Erreur : %s\n", error);
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_PERIODIC_MSGS, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Erreur CLEAR_PERIODIC_MSGS: ${result.status}")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_PERIODIC_MSGS, None, None)
if ret != 0:
    print(f"Erreur CLEAR_PERIODIC_MSGS: {ret}")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_PERIODIC_MSGS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Erreur CLEAR_PERIODIC_MSGS: {ret}");

CLEAR_MSG_FILTERS — Vidage des filtres

Supprime tous les filtres de messages établis via PassThruStartMsgFilter. Après l'appel, tous les messages entrants seront bloqués jusqu'à l'établissement de nouveaux filtres.

pInput NULL
pOutput NULL

Exemple en 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("Erreur : %s\n", error);
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_MSG_FILTERS, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Erreur CLEAR_MSG_FILTERS: ${result.status}")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_MSG_FILTERS, None, None)
if ret != 0:
    print(f"Erreur CLEAR_MSG_FILTERS: {ret}")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_MSG_FILTERS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Erreur CLEAR_MSG_FILTERS: {ret}");

CLEAR_FUNCT_MSG_LOOKUP_TABLE — Vidage de la table des adresses fonctionnelles

Vide la table des adresses fonctionnelles J1850. Utilisée pour les protocoles J1850 PWM/VPW lors de l'utilisation de l'adressage fonctionnel.

pInput NULL
pOutput NULL

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal J1850
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_FUNCT_MSG_LOOKUP_TABLE, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    // Traitement de l'erreur
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_FUNCT_MSG_LOOKUP_TABLE, None, None)

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_FUNCT_MSG_LOOKUP_TABLE, IntPtr.Zero, IntPtr.Zero);

ADD_TO_FUNCT_MSG_LOOKUP_TABLE — Ajout d'une adresse fonctionnelle

Ajoute une adresse à la table des adresses fonctionnelles J1850. Les messages portant cette adresse seront reçus lors de l'utilisation de l'adressage fonctionnel.

pInput SBYTE_ARRAY* — liste des adresses à ajouter
pOutput NULL

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
SBYTE_ARRAY AddrList;
unsigned char addresses[3] = {0x10, 0x18, 0x28};  // Adresses d'ECU
long ret;

AddrList.NumOfBytes = 3;
AddrList.BytePtr = addresses;

ret = PassThruIoctl(ChannelID, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Traitement de l'erreur
}

Exemple en Python

addresses = (c_ubyte * 3)(0x10, 0x18, 0x28)
addr_list = SBYTE_ARRAY()
addr_list.NumOfBytes = 3
addr_list.BytePtr = addresses

ret = j2534.PassThruIoctl(channel_id, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, byref(addr_list), None)

Exemple en C#

var addrList = new SBYTE_ARRAY {
    NumOfBytes = 3,
    BytePtr = new byte[] { 0x10, 0x18, 0x28 }
};
int ret = J2534.PassThruIoctl(channelId, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, ref addrList, IntPtr.Zero);

DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE — Suppression d'une adresse fonctionnelle

Supprime une adresse de la table des adresses fonctionnelles J1850.

pInput SBYTE_ARRAY* — liste des adresses à supprimer
pOutput NULL

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
SBYTE_ARRAY AddrList;
unsigned char addresses[1] = {0x10};  // Adresse à supprimer
long ret;

AddrList.NumOfBytes = 1;
AddrList.BytePtr = addresses;

ret = PassThruIoctl(ChannelID, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Traitement de l'erreur
}

Exemple en Python

addresses = (c_ubyte * 1)(0x10)
addr_list = SBYTE_ARRAY()
addr_list.NumOfBytes = 1
addr_list.BytePtr = addresses

ret = j2534.PassThruIoctl(channel_id, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, byref(addr_list), None)

Exemple en C#

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 — Mode haute vitesse SW-CAN

Commute Single-Wire CAN en mode haute vitesse (83.3 kbit/s). Utilisée pour le diagnostic à haute vitesse sur les réseaux GM.

pInput NULL
pOutput NULL

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal SW-CAN
long ret;

// Commutation en mode haute vitesse
ret = PassThruIoctl(ChannelID, SW_CAN_HS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("SW-CAN en mode High Speed (83.3 kbit/s)\n");
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, SW_CAN_HS, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "SW-CAN en mode High Speed (83.3 kbit/s)")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, SW_CAN_HS, None, None)
if ret == 0:
    print("SW-CAN en mode High Speed (83.3 kbit/s)")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, SW_CAN_HS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("SW-CAN en mode High Speed (83.3 kbit/s)");

SW_CAN_NS — Mode normal SW-CAN

Commute Single-Wire CAN en mode normal (33.3 kbit/s). C'est le mode par défaut pour les réseaux GM.

pInput NULL
pOutput NULL

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal SW-CAN
long ret;

// Commutation en mode normal
ret = PassThruIoctl(ChannelID, SW_CAN_NS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("SW-CAN en mode Normal Speed (33.3 kbit/s)\n");
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, SW_CAN_NS, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "SW-CAN en mode Normal Speed (33.3 kbit/s)")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, SW_CAN_NS, None, None)
if ret == 0:
    print("SW-CAN en mode Normal Speed (33.3 kbit/s)")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, SW_CAN_NS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("SW-CAN en mode Normal Speed (33.3 kbit/s)");

BUS_ON — Connexion du contrôleur au bus v5.0

Connecte le contrôleur CAN au bus physique. Utilisée après la déconnexion du contrôleur du bus via PassThruDisconnect avec le drapeau CAN_DISCONNECT, ou après l'ouverture du canal sans connexion automatique.

IoctlID 0x0F
pInput NULL
pOutput NULL
Cette commande n'est disponible que dans J2534 v5.00. Dans v04.04, le contrôleur se connecte au bus automatiquement lors de PassThruConnect.

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal CAN
long ret;

// Connexion du contrôleur au bus
ret = PassThruIoctl(ChannelID, BUS_ON, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Contrôleur CAN connecté au bus\n");
}

Exemple en Kotlin (Android)

val result = j2534.ptIoctl(channelID, BUS_ON, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "Contrôleur CAN connecté au bus")
}

Exemple en Python

ret = j2534.PassThruIoctl(channel_id, BUS_ON, None, None)
if ret == 0:
    print("Contrôleur CAN connecté au bus")

Exemple en C#

int ret = J2534.PassThruIoctl(channelId, BUS_ON, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("Contrôleur CAN connecté au bus");

REQUEST_CONNECTION — Établissement de la connexion TP 2.0 J2534-2

Demande l'établissement du canal et de la connexion TP 2.0 entre l'adaptateur et l'ECU. Utilisée pour le protocole TP 2.0 (VAG). La commande est non bloquante : le résultat de la connexion arrive sous forme d'indication dans la file de réception.

IoctlID 0x800A
pInput SBYTE_ARRAY* — données de la demande de connexion (11 bytes)
pOutput NULL

Structure des données (11 bytes)

BytePtr[0-3] CAN ID (identifiant), BytePtr[0] — byte de poids fort
BytePtr[4] Destination — adresse de destination (ECU)
BytePtr[5] Opcode — toujours 0xC0
BytePtr[6-7] TX-ID-A — CAN ID pour la transmission
BytePtr[8-9] RX-ID-A — CAN ID pour la réception
BytePtr[10] Application Type — type d'application
En cas de connexion réussie, un filtre PASS implicite est créé pour RX-ID-A. L'indication CONNECTION_ESTABLISHED est placée dans la file de réception. En cas d'erreur — CONNECTION_LOST.
Si RX-ID-A est déjà utilisé par un autre canal, ERR_NOT_UNIQUE est retourné. Si NumOfBytes ≠ 11, ERR_INVALID_IOCTL_VALUE est retourné.

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[11];
long ret;

// CAN ID pour broadcast: 0x200
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x02;
data[3] = 0x00;
// Destination (adresse de l'ECU, p. ex. 0x01 pour le moteur)
data[4] = 0x01;
// Opcode (toujours 0xC0)
data[5] = 0xC0;
// TX-ID-A (CAN ID pour la transmission, p. ex. 0x300)
data[6] = 0x03;
data[7] = 0x00;
// RX-ID-A (CAN ID pour la réception, p. ex. 0x301)
data[8] = 0x03;
data[9] = 0x01;
// Application Type (0x01 pour le diagnostic)
data[10] = 0x01;

InputData.NumOfBytes = 11;
InputData.BytePtr = data;

ret = PassThruIoctl(ChannelID, REQUEST_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Demande de connexion envoyée, en attente de CONNECTION_ESTABLISHED\n");
}
else if (ret == ERR_NOT_UNIQUE)
{
    printf("RX-ID-A est déjà utilisé par un autre canal\n");
}

Exemple en Kotlin (Android)

// channelID — canal 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", "Demande de connexion envoyée")
    ERR_NOT_UNIQUE -> Log.e("TP2.0", "RX-ID-A est déjà utilisé")
    else -> Log.e("TP2.0", "Erreur : ${result.status}")
}

Exemple en 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("Demande de connexion envoyée, en attente de CONNECTION_ESTABLISHED")
elif ret == ERR_NOT_UNIQUE:
    print("RX-ID-A est déjà utilisé par un autre canal")

Exemple en 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("Demande de connexion envoyée, en attente de CONNECTION_ESTABLISHED");
else if (ret == ERR_NOT_UNIQUE)
    Console.WriteLine("RX-ID-A est déjà utilisé par un autre canal");

TEARDOWN_CONNECTION — Fermeture de la connexion TP 2.0 J2534-2

Ferme la connexion TP 2.0 établie entre l'adaptateur et l'ECU. La commande est non bloquante : la confirmation de la fermeture arrive sous forme d'indication CONNECTION_LOST dans la file de réception.

IoctlID 0x800B
pInput SBYTE_ARRAY* — CAN ID de réception (4 bytes)
pOutput NULL

Structure des données (4 bytes)

BytePtr[0-3] RX-ID-A — CAN ID pour la réception (le même que dans REQUEST_CONNECTION), BytePtr[0] — byte de poids fort
Après la fermeture de la connexion, le filtre PASS implicite pour RX-ID-A est supprimé. Les filtres établis via PassThruStartMsgFilter restent actifs.

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[4];
long ret;

// RX-ID-A (le même que celui utilisé dans 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("Demande de fermeture de connexion envoyée\n");
}

Exemple en 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", "Demande de fermeture de connexion envoyée")
}

Exemple en 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("Demande de fermeture de connexion envoyée")

Exemple en 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("Demande de fermeture de connexion envoyée");