Quantex GmbH
Tu región: Europa

PassThruIoctl v4.04 v5.0

Gestión de entrada/salida

Última modificación:

Descripción

Función universal de gestión del dispositivo y del canal. Ejecuta diferentes operaciones según el parámetro IoctlID: lectura/escritura de la configuración, inicialización de protocolos, vaciado de búferes y otras operaciones de servicio.

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

Parámetros

IoctlID Valor Descripción
GET_CONFIG 0x01 Lectura de los parámetros del protocolo
SET_CONFIG 0x02 Escritura de los parámetros del protocolo
READ_VBATT 0x03 Lectura de la tensión de alimentación
FIVE_BAUD_INIT 0x04 Inicialización a 5 baudios de K-Line
FAST_INIT 0x05 Inicialización Fast de K-Line
CLEAR_TX_BUFFER 0x07 Vaciado de la cola de transmisión
CLEAR_RX_BUFFER 0x08 Vaciado de la cola de recepción
CLEAR_PERIODIC_MSGS 0x09 Vaciado de los mensajes periódicos
CLEAR_MSG_FILTERS 0x0A Vaciado de todos los filtros
CLEAR_FUNCT_MSG_LOOKUP_TABLE 0x0B Vaciado de la tabla de direcciones funcionales
ADD_TO_FUNCT_MSG_LOOKUP_TABLE 0x0C Adición a la tabla de direcciones funcionales
DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE 0x0D Eliminación de la tabla de direcciones funcionales
READ_PROG_VOLTAGE 0x0E Lectura de la tensión de programación
SW_CAN_HS 0x8000 Conmutación de SW-CAN al modo de alta velocidad
SW_CAN_NS 0x8001 Conmutación de SW-CAN al modo normal
BUS_ON v5.0 0x0F Conexión del controlador CAN al bus
REQUEST_CONNECTION J2534-2 0x800A Establecimiento de la conexión TP 2.0
TEARDOWN_CONNECTION J2534-2 0x800B Cierre de la conexión TP 2.0
GET_DEVICE_INFO J2534-2 0x800C Obtención de información del dispositivo
GET_PROTOCOL_INFO J2534-2 0x800D Obtención de información del protocolo
ISO13400_PS Quantex 0x8110-0x8113 Comandos DoIP (Diagnostics over IP)

Códigos de error devueltos

Código Descripción Posibles causas y soluciones
STATUS_NOERROR Función ejecutada correctamente
ERR_DEVICE_NOT_CONNECTED No hay conexión con el adaptador
  • El adaptador está apagado o fuera de alcance
  • Solución: compruebe la alimentación del adaptador y la conexión de red
ERR_INVALID_CHANNEL_ID Identificador de canal no válido
  • El ChannelID no se obtuvo mediante PassThruConnect o el canal está cerrado
  • Solución: asegúrese de que PassThruConnect se haya ejecutado correctamente
ERR_INVALID_IOCTL_ID Identificador IoctlID no válido
  • El IoctlID indicado no es compatible
  • Solución: compruebe que el valor de IoctlID sea correcto
ERR_NULL_PARAMETER Se ha pasado NULL en lugar de un puntero obligatorio
  • pInput o pOutput es igual a NULL cuando se requiere un puntero
  • Solución: pase punteros correctos
ERR_NOT_SUPPORTED Operación no compatible
  • El adaptador no admite la operación solicitada
  • Solución: compruebe las capacidades del adaptador mediante GET_DEVICE_INFO
ERR_INVALID_IOCTL_VALUE Valor de parámetro no admitido
  • El valor de pInput está fuera de los límites permitidos
  • Solución: compruebe los rangos de valores admitidos
ERR_INVALID_MSG Estructura de mensaje incorrecta
  • Estructura incorrecta en pInput para FAST_INIT
  • Solución: compruebe que los campos de PASSTHRU_MSG sean correctos
ERR_FAILED Error indeterminado
  • Error interno de la biblioteca o del adaptador
  • Solución: llame a PassThruGetLastError() para obtener la descripción

READ_VBATT — Lectura de la tensión de alimentación

Devuelve la tensión en el conector OBD-II (pin 16). El valor se da en milivoltios; para obtener voltios, divídalo entre 1000. El comando no requiere un canal abierto y puede ejecutarse inmediatamente después de PassThruOpen.

pInput NULL
pOutput unsigned long* — tensión en mV

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

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

Ejemplo en Kotlin (Android)

// deviceID obtenido previamente 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", "Tensión: ${"%.2f".format(voltageV)} V")
}

Ejemplo 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"Tensión: {voltage.value / 1000:.2f} V")

Ejemplo en C#

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

READ_PROG_VOLTAGE — Lectura de la tensión de programación

Devuelve la tensión actual en la salida de programación. El valor se da en milivoltios, redondeado a la décima de voltio más cercana.

pInput NULL
pOutput unsigned long* — tensión en mV

Ejemplo 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("Tensión de programación: %.2f V\n", voltage / 1000.0);
}

Ejemplo 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", "Tensión de programación: ${"%.2f".format(voltageV)} V")
}

Ejemplo en Python

from ctypes import *

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

Ejemplo en C#

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

FIVE_BAUD_INIT — Inicialización a 5 baudios

Inicia la inicialización lenta (5 baudios) para los protocolos ISO 9141 e ISO 14230 (K-Line). Recibe el KeyWord de la ECU. El modo de inicialización se establece con el parámetro FIVE_BAUD_MOD mediante SET_CONFIG. La velocidad de transmisión se determina automáticamente.

pInput SBYTE_ARRAY* — dirección de inicialización (1 byte)
pOutput SBYTE_ARRAY* — KeyWord (2 bytes)
El parámetro FIVE_BAUD_MOD determina el modo de inicialización: ISO9141-2/ISO14230-4 (0), inversión de KB2 (1), inversión de la dirección (2), ISO9141 sin inversión (3).

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

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

initByte[0] = 0x33;  // Dirección de inicialización de la 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]);
}

Ejemplo en Kotlin (Android)

// channelID obtenido de ptConnect para ISO14230
val initAddress = byteArrayOf(0x33)  // Dirección de inicialización

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

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

Ejemplo en C#

var inputMsg = new SBYTE_ARRAY {
    NumOfBytes = 1,
    BytePtr = new byte[] { 0x33 }  // Dirección de inicialización
};

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 — Inicialización Fast

Inicia la inicialización rápida para el protocolo ISO 14230 (K-Line). Envía la solicitud StartCommunication y devuelve la respuesta de la ECU. Se utiliza para KWP2000.

pInput PASSTHRU_MSG* — solicitud de inicialización
pOutput PASSTHRU_MSG* — respuesta de la ECU
Importante: Con una dirección funcional (de difusión), varias ECU pueden responder a la solicitud. En pOutput solo estará la primera respuesta; las demás se colocarán en la cola de recepción.

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

// Solicitud StartCommunication
InputMsg.ProtocolID = ISO14230;
InputMsg.TxFlags = 0;
InputMsg.DataSize = 4;
InputMsg.Data[0] = 0x81;  // Formato: dirección física, 1 byte de datos
InputMsg.Data[1] = 0x10;  // Dirección de destino (ECU)
InputMsg.Data[2] = 0xF1;  // Dirección de origen (tester)
InputMsg.Data[3] = 0x81;  // SID: StartCommunication

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

Ejemplo en Kotlin (Android)

// channelID obtenido de ptConnect para 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", "Respuesta de la ECU: ${result.response.data.toHexString()}")
}

Ejemplo 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  # Formato
input_msg.Data[1] = 0x10  # Dirección de destino
input_msg.Data[2] = 0xF1  # Dirección de origen
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"Respuesta de la ECU: {data.hex(' ').upper()}")

Ejemplo en C#

var inputMsg = new PASSTHRU_MSG {
    ProtocolID = ISO14230,
    TxFlags = 0,
    DataSize = 4
};
inputMsg.Data[0] = 0x81;  // Formato
inputMsg.Data[1] = 0x10;  // Dirección de destino
inputMsg.Data[2] = 0xF1;  // Dirección de origen
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($"Respuesta de la ECU: {BitConverter.ToString(data).Replace("-", " ")}");
}

CLEAR_TX_BUFFER — Vaciado de la cola de transmisión

Elimina todos los mensajes de la cola de transmisión del canal. Se utiliza para cancelar las transmisiones programadas.

pInput NULL
pOutput NULL

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

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

CLEAR_RX_BUFFER — Vaciado de la cola de recepción

Elimina todos los mensajes de la cola de recepción del canal. Se recomienda invocarlo antes de iniciar una nueva sesión de diagnóstico.

pInput NULL
pOutput NULL

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

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

CLEAR_PERIODIC_MSGS — Vaciado de los mensajes periódicos

Elimina todos los mensajes periódicos establecidos mediante PassThruStartPeriodicMsg. Equivale a llamar a PassThruStopPeriodicMsg para cada mensaje.

pInput NULL
pOutput NULL

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

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

CLEAR_MSG_FILTERS — Vaciado de filtros

Elimina todos los filtros de mensajes establecidos mediante PassThruStartMsgFilter. Tras la invocación, todos los mensajes entrantes se bloquearán hasta que se establezcan nuevos filtros.

pInput NULL
pOutput NULL

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

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

CLEAR_FUNCT_MSG_LOOKUP_TABLE — Vaciado de la tabla de direcciones funcionales

Vacía la tabla de direcciones funcionales J1850. Se utiliza para los protocolos J1850 PWM/VPW al trabajar con direccionamiento funcional.

pInput NULL
pOutput NULL

Ejemplo 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)
{
    // Tratamiento del error
}

Ejemplo en Python

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

Ejemplo en C#

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

ADD_TO_FUNCT_MSG_LOOKUP_TABLE — Adición de una dirección funcional

Añade una dirección a la tabla de direcciones funcionales J1850. Los mensajes con esta dirección se recibirán al utilizar el direccionamiento funcional.

pInput SBYTE_ARRAY* — lista de direcciones a añadir
pOutput NULL

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

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

ret = PassThruIoctl(ChannelID, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Tratamiento del error
}

Ejemplo 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)

Ejemplo 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 — Eliminación de una dirección funcional

Elimina una dirección de la tabla de direcciones funcionales J1850.

pInput SBYTE_ARRAY* — lista de direcciones a eliminar
pOutput NULL

Ejemplo en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
SBYTE_ARRAY AddrList;
unsigned char addresses[1] = {0x10};  // Dirección a eliminar
long ret;

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

ret = PassThruIoctl(ChannelID, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Tratamiento del error
}

Ejemplo 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)

Ejemplo 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 — Modo de alta velocidad SW-CAN

Conmuta Single-Wire CAN al modo de alta velocidad (83.3 kbit/s). Se utiliza para el diagnóstico a alta velocidad en las redes GM.

pInput NULL
pOutput NULL

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

// Conmutación al modo de alta velocidad
ret = PassThruIoctl(ChannelID, SW_CAN_HS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("SW-CAN en modo High Speed (83.3 kbit/s)\n");
}

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

SW_CAN_NS — Modo normal SW-CAN

Conmuta Single-Wire CAN al modo normal (33.3 kbit/s). Es el modo predeterminado para las redes GM.

pInput NULL
pOutput NULL

Ejemplo en C/C++

#include "j2534_dll.hpp"

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

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

Ejemplo en Kotlin (Android)

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

Ejemplo en Python

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

Ejemplo en C#

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

BUS_ON — Conexión del controlador al bus v5.0

Conecta el controlador CAN al bus físico. Se utiliza tras desconectar el controlador del bus mediante PassThruDisconnect con la marca CAN_DISCONNECT, o tras abrir el canal sin conexión automática.

IoctlID 0x0F
pInput NULL
pOutput NULL
Este comando solo está disponible en J2534 v5.00. En v04.04 el controlador se conecta al bus automáticamente con PassThruConnect.

Ejemplo en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Canal CAN
long ret;

// Conexión del controlador al bus
ret = PassThruIoctl(ChannelID, BUS_ON, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Controlador CAN conectado al bus\n");
}

Ejemplo en Kotlin (Android)

val result = j2534.ptIoctl(channelID, BUS_ON, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "Controlador CAN conectado al bus")
}

Ejemplo en Python

ret = j2534.PassThruIoctl(channel_id, BUS_ON, None, None)
if ret == 0:
    print("Controlador CAN conectado al bus")

Ejemplo en C#

int ret = J2534.PassThruIoctl(channelId, BUS_ON, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("Controlador CAN conectado al bus");

REQUEST_CONNECTION — Establecimiento de la conexión TP 2.0 J2534-2

Solicita el establecimiento del canal y de la conexión TP 2.0 entre el adaptador y la ECU. Se utiliza para el protocolo TP 2.0 (VAG). El comando es no bloqueante: el resultado de la conexión llega como una indicación a la cola de recepción.

IoctlID 0x800A
pInput SBYTE_ARRAY* — datos de la solicitud de conexión (11 bytes)
pOutput NULL

Estructura de datos (11 bytes)

BytePtr[0-3] CAN ID (identificador), BytePtr[0] — byte más significativo
BytePtr[4] Destination — dirección de destino (ECU)
BytePtr[5] Opcode — siempre 0xC0
BytePtr[6-7] TX-ID-A — CAN ID para la transmisión
BytePtr[8-9] RX-ID-A — CAN ID para la recepción
BytePtr[10] Application Type — tipo de aplicación
Con una conexión correcta se crea un filtro PASS implícito para RX-ID-A. En la cola de recepción se coloca la indicación CONNECTION_ESTABLISHED. En caso de error — CONNECTION_LOST.
Si RX-ID-A ya está siendo utilizado por otro canal, se devuelve ERR_NOT_UNIQUE. Si NumOfBytes ≠ 11, se devuelve ERR_INVALID_IOCTL_VALUE.

Ejemplo 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 para broadcast: 0x200
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x02;
data[3] = 0x00;
// Destination (dirección de la ECU, p. ej. 0x01 para el motor)
data[4] = 0x01;
// Opcode (siempre 0xC0)
data[5] = 0xC0;
// TX-ID-A (CAN ID para la transmisión, p. ej. 0x300)
data[6] = 0x03;
data[7] = 0x00;
// RX-ID-A (CAN ID para la recepción, p. ej. 0x301)
data[8] = 0x03;
data[9] = 0x01;
// Application Type (0x01 para diagnóstico)
data[10] = 0x01;

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

ret = PassThruIoctl(ChannelID, REQUEST_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Solicitud de conexión enviada, esperando CONNECTION_ESTABLISHED\n");
}
else if (ret == ERR_NOT_UNIQUE)
{
    printf("RX-ID-A ya está siendo utilizado por otro canal\n");
}

Ejemplo 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", "Solicitud de conexión enviada")
    ERR_NOT_UNIQUE -> Log.e("TP2.0", "RX-ID-A ya está en uso")
    else -> Log.e("TP2.0", "Error: ${result.status}")
}

Ejemplo 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("Solicitud de conexión enviada, esperando CONNECTION_ESTABLISHED")
elif ret == ERR_NOT_UNIQUE:
    print("RX-ID-A ya está siendo utilizado por otro canal")

Ejemplo 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("Solicitud de conexión enviada, esperando CONNECTION_ESTABLISHED");
else if (ret == ERR_NOT_UNIQUE)
    Console.WriteLine("RX-ID-A ya está siendo utilizado por otro canal");

TEARDOWN_CONNECTION — Cierre de la conexión TP 2.0 J2534-2

Cierra la conexión TP 2.0 establecida entre el adaptador y la ECU. El comando es no bloqueante: la confirmación del cierre llega como la indicación CONNECTION_LOST a la cola de recepción.

IoctlID 0x800B
pInput SBYTE_ARRAY* — CAN ID de recepción (4 bytes)
pOutput NULL

Estructura de datos (4 bytes)

BytePtr[0-3] RX-ID-A — CAN ID para la recepción (el mismo que en REQUEST_CONNECTION), BytePtr[0] — byte más significativo
Tras cerrar la conexión, el filtro PASS implícito para RX-ID-A se elimina. Los filtros establecidos mediante PassThruStartMsgFilter permanecen activos.

Ejemplo 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 (el mismo que se usó en 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("Solicitud de cierre de conexión enviada\n");
}

Ejemplo 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", "Solicitud de cierre de conexión enviada")
}

Ejemplo 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("Solicitud de cierre de conexión enviada")

Ejemplo 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("Solicitud de cierre de conexión enviada");