Establish a connection with the adapter
Last updated:
The function establishes a connection with the ScanDoc adapter. The connection settings (IP address or BLE device name) are read from the j2534.json configuration file.
long PassThruOpen(void* pName, unsigned long* pDeviceID)
NULL or a pointer to an empty string. The connection settings are read from the configuration file.PassThruConnect(), PassThruClose() and other functions.
The connection settings are stored in the j2534.json file. The file location depends on the operating system:
| OS | File path |
|---|---|
| Windows | %APPDATA%\Quantex\j2534.jsonFor example: C:\Users\User\AppData\Roaming\Quantex\j2534.json |
| macOS | ~/Library/Application Support/Quantex/j2534.json |
| Linux | ~/.config/quantex/j2534.json |
If the file does not exist, it will be created automatically with default settings.
{
"current_device": 0,
"devices": [
{
"name": "ScanDoc",
"connection_type": "LAN",
"device_ip": "192.168.1.3",
"device_name": ""
}
],
"logs_directory": "",
"debug": false
}
| Field | Type | Description |
|---|---|---|
| current_device | number | Index of the active device in the devices array (starting from 0) |
| devices | array | Array of devices. For API v04.04, only a single device with the index current_device is used |
| name | string | Display name of the device (for the user's convenience) |
| connection_type | string | "LAN" for WLAN/Ethernet or "BLE" for BLE Low Energy |
| device_ip | string | IP address of the adapter (used when connection_type = "LAN") |
| device_name | string | Serial number or BLE device name (used when connection_type = "BLE") |
| logs_directory | string | Folder for log files. If empty, logs are saved to <config_dir>/sdlogs |
| debug | boolean | true - enable logging, false - disable |
Connecting over WLAN/LAN:
{
"current_device": 0,
"devices": [
{
"name": "ScanDoc FD",
"connection_type": "LAN",
"device_ip": "192.168.1.100",
"device_name": ""
}
],
"debug": false
}
Connecting over BLE:
{
"current_device": 0,
"devices": [
{
"name": "ScanDoc FD",
"connection_type": "BLE",
"device_ip": "",
"device_name": "N4999"
}
],
"debug": true
}
PassThruOpen() → Establish a connection with the adapter
↓
PassThruConnect() → Open a communication channel with the ECU
↓
PassThruReadMsg() / PassThruWriteMsg() → Exchange messages
↓
PassThruDisconnect() → Close the channel
↓
PassThruClose() → Release the adapter resources
PassThruClose() before the program exits. Otherwise the next connection will return the error ERR_DEVICE_IN_USE.
Connection timeout: 500 ms. If the adapter is unavailable, the function returns
ERR_DEVICE_NOT_CONNECTED after the timeout expires.
| Code | Description | Possible causes and solutions |
|---|---|---|
| STATUS_NOERROR | Function completed successfully | - |
| ERR_DEVICE_NOT_CONNECTED | No connection to the adapter |
|
| ERR_DEVICE_IN_USE | The device is already in use |
|
| ERR_NULL_PARAMETER | The pDeviceID pointer is not set | Pass a valid pointer to a variable |
| ERR_FAILED | Internal error |
|
#include "j2534_dll.hpp"
unsigned long DeviceID;
long ret;
// pName = NULL - settings are read from j2534.json
ret = PassThruOpen(NULL, &DeviceID);
if (ret != STATUS_NOERROR)
{
char error[256];
PassThruGetLastError(error);
printf("Error: %s\n", error);
return;
}
// Working with the device...
// Always close the connection
PassThruClose(DeviceID);
This example uses the J2534JNI JNI wrapper to call the native J2534 functions from Kotlin.
// J2534JNI is a wrapper class for JNI
val j2534 = J2534JNI(context)
// Pass null - settings are read from j2534.json
val deviceResult = j2534.ptOpen(null)
if (deviceResult.status == STATUS_NOERROR) {
val deviceID = deviceResult.deviceId
Log.i("J2534", "Adapter opened, DeviceID: $deviceID")
// Working with the device...
// Always close the connection
j2534.ptClose(deviceID)
} else {
Log.e("J2534", "Error: ${deviceResult.status}")
}
from ctypes import *
import platform
# Load the library depending on the OS
if platform.system() == "Windows":
j2534 = windll.LoadLibrary("j2534sd_v04_04_x64.dll")
elif platform.system() == "Darwin":
j2534 = cdll.LoadLibrary("libj2534_v04_04.dylib")
else:
j2534 = cdll.LoadLibrary("libj2534_v04_04.so")
device_id = c_ulong()
# pName = None - settings are read from j2534.json
ret = j2534.PassThruOpen(None, byref(device_id))
if ret == 0: # STATUS_NOERROR
print(f"Adapter opened, DeviceID: {device_id.value}")
# Working with the device...
# Always close the connection
j2534.PassThruClose(device_id)
else:
error = create_string_buffer(256)
j2534.PassThruGetLastError(error)
print(f"Error: {error.value.decode()}")
using System;
using System.Runtime.InteropServices;
class J2534
{
[DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PassThruOpen(IntPtr pName, out uint pDeviceID);
[DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PassThruClose(uint DeviceID);
[DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PassThruGetLastError(
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pErrorDescription);
}
// Usage:
uint deviceId;
// IntPtr.Zero = NULL - settings are read from j2534.json
int ret = J2534.PassThruOpen(IntPtr.Zero, out deviceId);
if (ret == 0) // STATUS_NOERROR
{
Console.WriteLine($"Adapter opened, DeviceID: {deviceId}");
// Working with the device...
// Always close the connection
J2534.PassThruClose(deviceId);
}
else
{
var error = new System.Text.StringBuilder(256);
J2534.PassThruGetLastError(error);
Console.WriteLine($"Error: {error}");
}