La función devuelve secuencialmente información sobre los dispositivos encontrados durante la última llamada a
PassThruScanForDevices(). En cada llamada se devuelve información sobre el siguiente dispositivo de la lista. El orden de los dispositivos puede variar en cada nuevo escaneo.
long PassThruGetNextDevice(SDEVICE* psDevice)
Nota: No se requiere llamar a PassThruOpen() antes de usar esta función. Basta con llamar previamente a PassThruScanForDevices().
Parámetros
psDevice - Puntero a una estructura SDEVICE reservada por la aplicación. Tras la ejecución correcta de la función, la estructura se rellenará con información sobre el dispositivo.
Estructura SDEVICE
typedef struct {
char DeviceName[80]; // Nombre del dispositivo (ASCII, terminado en null)
unsigned long DeviceAvailable; // Estado de disponibilidad del dispositivo
unsigned long DeviceDLLFWStatus; // Compatibilidad de la DLL y el firmware
unsigned long DeviceConnectMedia; // Tipo de conexión (con cable/inalámbrica)
unsigned long DeviceConnectSpeed; // Velocidad de conexión (bit/s)
unsigned long DeviceSignalQuality; // Calidad de la señal (0-100%, 0xFFFFFFFF si es desconocida)
unsigned long DeviceSignalStrength; // Nivel de la señal (0-100%, 0xFFFFFFFF si es desconocido)
} SDEVICE;
Descripción de los campos de la estructura
Campo
Descripción
DeviceName
Cadena ASCII con el nombre del dispositivo (hasta 80 caracteres incluyendo el terminador NULL). El nombre está destinado a mostrarse al usuario y debe identificar el dispositivo de forma inequívoca. Ejemplos: "ScanDoc FD #N4999", "ScanDoc PRO (WLAN)"
DeviceAvailable
Estado de disponibilidad del dispositivo. Consulte la tabla de valores
DeviceDLLFWStatus
Estado de compatibilidad de la DLL y el firmware del dispositivo. Consulte la tabla de valores
Velocidad de conexión con el dispositivo en bits por segundo
DeviceSignalQuality
Calidad de la señal de 0 a 100%. El valor 0xFFFFFFFF si no se ha determinado
DeviceSignalStrength
Nivel de la señal de 0 a 100%. El valor 0xFFFFFFFF si no se ha determinado
Valores de DeviceAvailable
Constante
Valor
Descripción
DEVICE_STATE_UNKNOWN
0
No se pudo determinar el estado del dispositivo
DEVICE_AVAILABLE
1
El dispositivo está libre y listo para la conexión
DEVICE_IN_USE
2
El dispositivo ya está en uso (abierto por otra aplicación)
Valores de DeviceDLLFWStatus
Constante
Valor
Descripción
DEVICE_DLL_FW_COMPATIBILTY_UNKNOWN
0
No se pudo determinar la compatibilidad de la DLL y el firmware
DEVICE_DLL_FW_COMPATIBLE
1
La DLL y el firmware son compatibles
DEVICE_DLL_OR_FW_NOT_COMPATIBLE
2
La DLL o el firmware están desactualizados o son incompatibles
DEVICE_DLL_NOT_COMPATIBLE
3
La DLL está desactualizada o es incompatible con el dispositivo
DEVICE_FW_NOT_COMPATIBLE
4
El firmware del dispositivo está desactualizado o es incompatible con la DLL
Valores de DeviceConnectMedia
Constante
Valor
Descripción
DEVICE_CONN_UNKNOWN
0
No se pudo determinar el tipo de conexión
DEVICE_CONN_WIRELESS
1
Conexión inalámbrica (WLAN, BLE)
DEVICE_CONN_WIRED
2
Conexión con cable (USB, Ethernet)
Orden de llamada de las funciones
PassThruScanForDevices(&count) → Obtener el número de dispositivos
↓
for (i = 0; i < count; i++) {
PassThruGetNextDevice(&device) → Obtener información sobre el dispositivo
}
↓
PassThruOpen(deviceName) → Abrir el dispositivo seleccionado
Importante: La aplicación no está obligada a llamar a
PassThruGetNextDevice() para todos los dispositivos. El recorrido puede interrumpirse en cualquier momento. Sin embargo, las llamadas posteriores seguirán devolviendo los dispositivos restantes hasta el final de la lista, la descarga de la DLL o una nueva llamada a PassThruScanForDevices().
Códigos de error devueltos
Código
Descripción
Posibles causas y soluciones
STATUS_NOERROR
La función se ejecutó correctamente
La estructura psDevice se ha rellenado con información sobre el dispositivo
ERR_NULL_PARAMETER
No se ha indicado el puntero psDevice
Pase un puntero válido a la estructura SDEVICE
ERR_EXCEEDED_LIMIT
Todos los dispositivos ya han sido enumerados
La información sobre todos los dispositivos encontrados ya ha sido devuelta
Solución: llame a PassThruScanForDevices() para realizar un nuevo escaneo
ERR_BUFFER_EMPTY
La lista de dispositivos está vacía
PassThruScanForDevices() no encontró ningún dispositivo
PassThruScanForDevices() no fue llamada
Solución: llame a PassThruScanForDevices() y compruebe pDeviceCount
ERR_CONCURRENT_API_CALL
Una función de la API J2534 ya se está ejecutando
Otra función J2534 aún no ha terminado de ejecutarse
Solución: espere a que finalice la llamada anterior
ERR_NOT_SUPPORTED
La función no es compatible
La DLL no admite la enumeración dinámica de dispositivos
Solución: use PassThruOpen() directamente
ERR_FAILED
Error interno
Use PassThruGetLastError() para obtener los detalles
Ejemplos
Ejemplo en C/C++
#include "j2534_dll.hpp"
unsigned long deviceCount = 0;
// Escaneamos los dispositivos
long ret = PassThruScanForDevices(&deviceCount);
if (ret != STATUS_NOERROR || deviceCount == 0)
{
printf("No se encontraron dispositivos\n");
return;
}
printf("Dispositivos encontrados: %lu\n", deviceCount);
// Recorremos todos los dispositivos encontrados
SDEVICE device;
for (unsigned long i = 0; i < deviceCount; i++)
{
ret = PassThruGetNextDevice(&device);
if (ret != STATUS_NOERROR)
{
break;
}
printf("\nDispositivo %lu:\n", i + 1);
printf(" Nombre: %s\n", device.DeviceName);
printf(" Disponible: %s\n",
device.DeviceAvailable == DEVICE_AVAILABLE ? "Sí" :
device.DeviceAvailable == DEVICE_IN_USE ? "Ocupado" : "Desconocido");
printf(" Compatibilidad: %s\n",
device.DeviceDLLFWStatus == DEVICE_DLL_FW_COMPATIBLE ? "OK" : "Se requiere actualización");
printf(" Conexión: %s\n",
device.DeviceConnectMedia == DEVICE_CONN_WIRELESS ? "Inalámbrica" :
device.DeviceConnectMedia == DEVICE_CONN_WIRED ? "Con cable" : "Desconocida");
if (device.DeviceSignalStrength != 0xFFFFFFFF)
{
printf(" Nivel de señal: %lu%%\n", device.DeviceSignalStrength);
}
}
// Nos conectamos al primer dispositivo disponible
// (en una aplicación real hay que dar al usuario la posibilidad de elegir)
unsigned long deviceID;
ret = PassThruOpen(device.DeviceName, &deviceID);
if (ret == STATUS_NOERROR)
{
printf("\nConectado a: %s\n", device.DeviceName);
// ... trabajo con el dispositivo ...
PassThruClose(deviceID);
}
Ejemplo en Kotlin (Android)
val j2534 = J2534JNI(context)
// Escaneamos los dispositivos
val scanResult = j2534.ptScanForDevices()
if (scanResult.status != STATUS_NOERROR || scanResult.deviceCount == 0) {
Log.w("J2534", "No se encontraron dispositivos")
return
}
// Recopilamos información sobre todos los dispositivos
val devices = mutableListOf<DeviceInfo>()
for (i in 0 until scanResult.deviceCount) {
val result = j2534.ptGetNextDevice()
if (result.status == STATUS_NOERROR) {
devices.add(result.device)
Log.i("J2534", """
Dispositivo ${i + 1}:
Nombre: ${result.device.name}
Disponible: ${result.device.available}
Señal: ${result.device.signalStrength}%
""".trimIndent())
}
}
// Mostramos el cuadro de diálogo de selección de dispositivo
showDeviceSelectionDialog(devices) { selectedDevice ->
val openResult = j2534.ptOpen(selectedDevice.name)
if (openResult.status == STATUS_NOERROR) {
// Trabajo con el dispositivo...
}
}
Ejemplo en Python (ctypes)
from ctypes import *
import platform
# Carga de la biblioteca
if platform.system() == "Windows":
j2534 = windll.LoadLibrary("j2534sd_v05_00_x64.dll")
elif platform.system() == "Darwin":
j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")
else:
j2534 = cdll.LoadLibrary("libj2534_v05_00.so")
# Definición de la estructura SDEVICE
class SDEVICE(Structure):
_fields_ = [
("DeviceName", c_char * 80),
("DeviceAvailable", c_ulong),
("DeviceDLLFWStatus", c_ulong),
("DeviceConnectMedia", c_ulong),
("DeviceConnectSpeed", c_ulong),
("DeviceSignalQuality", c_ulong),
("DeviceSignalStrength", c_ulong)
]
# Constantes
DEVICE_AVAILABLE = 1
DEVICE_IN_USE = 2
DEVICE_DLL_FW_COMPATIBLE = 1
DEVICE_CONN_WIRELESS = 1
DEVICE_CONN_WIRED = 2
# Escaneamos los dispositivos
device_count = c_ulong()
ret = j2534.PassThruScanForDevices(byref(device_count))
if ret != 0 or device_count.value == 0:
print("No se encontraron dispositivos")
exit()
print(f"Dispositivos encontrados: {device_count.value}\n")
# Obtenemos información sobre cada dispositivo
devices = []
for i in range(device_count.value):
device = SDEVICE()
ret = j2534.PassThruGetNextDevice(byref(device))
if ret == 0:
devices.append(device)
name = device.DeviceName.decode('utf-8')
available = "Sí" if device.DeviceAvailable == DEVICE_AVAILABLE else \
"Ocupado" if device.DeviceAvailable == DEVICE_IN_USE else "?"
media = "WLAN/BLE" if device.DeviceConnectMedia == DEVICE_CONN_WIRELESS else \
"USB/LAN" if device.DeviceConnectMedia == DEVICE_CONN_WIRED else "?"
print(f"Dispositivo {i + 1}:")
print(f" Nombre: {name}")
print(f" Disponible: {available}")
print(f" Conexión: {media}")
if device.DeviceSignalStrength != 0xFFFFFFFF:
print(f" Señal: {device.DeviceSignalStrength}%")
print()
# Nos conectamos al primer dispositivo disponible
if devices:
device_id = c_ulong()
ret = j2534.PassThruOpen(devices[0].DeviceName, byref(device_id))
if ret == 0:
print(f"Conectado a: {devices[0].DeviceName.decode()}")
# ... trabajo con el dispositivo ...
j2534.PassThruClose(device_id)
Ejemplo en C# (P/Invoke)
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SDEVICE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string DeviceName;
public uint DeviceAvailable;
public uint DeviceDLLFWStatus;
public uint DeviceConnectMedia;
public uint DeviceConnectSpeed;
public uint DeviceSignalQuality;
public uint DeviceSignalStrength;
}
public enum DeviceAvailable : uint
{
Unknown = 0,
Available = 1,
InUse = 2
}
public enum DeviceConnectMedia : uint
{
Unknown = 0,
Wireless = 1,
Wired = 2
}
class J2534
{
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruScanForDevices(out uint pDeviceCount);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruGetNextDevice(out SDEVICE psDevice);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruOpen(string pName, out uint pDeviceID);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruClose(uint DeviceID);
}
// Uso:
uint deviceCount;
int ret = J2534.PassThruScanForDevices(out deviceCount);
if (ret != 0 || deviceCount == 0)
{
Console.WriteLine("No se encontraron dispositivos");
return;
}
Console.WriteLine($"Dispositivos encontrados: {deviceCount}\n");
var devices = new List<SDEVICE>();
for (uint i = 0; i < deviceCount; i++)
{
SDEVICE device;
ret = J2534.PassThruGetNextDevice(out device);
if (ret == 0)
{
devices.Add(device);
Console.WriteLine($"Dispositivo {i + 1}:");
Console.WriteLine($" Nombre: {device.DeviceName}");
Console.WriteLine($" Disponible: {(DeviceAvailable)device.DeviceAvailable}");
Console.WriteLine($" Conexión: {(DeviceConnectMedia)device.DeviceConnectMedia}");
if (device.DeviceSignalStrength != 0xFFFFFFFF)
Console.WriteLine($" Señal: {device.DeviceSignalStrength}%");
Console.WriteLine();
}
}
// Nos conectamos al primer dispositivo
if (devices.Count > 0)
{
uint deviceId;
ret = J2534.PassThruOpen(devices[0].DeviceName, out deviceId);
if (ret == 0)
{
Console.WriteLine($"Conectado a: {devices[0].DeviceName}");
// ... trabajo con el dispositivo ...
J2534.PassThruClose(deviceId);
}
}