# Configuration

> **Library 2.0.0.213** · SAE J2534 v04.04 API

The library is configured through a single JSON file, `j2534.json`. It holds
the list of known devices and selects which device and which transport
(interface) `PassThruOpen(NULL)` connects to — i.e. switching devices or
moving a device from Wi-Fi to BLE is a configuration change, not a code
change.

## File location

| Platform | Path |
|----------|------|
| macOS | `~/Library/Application Support/Quantex/j2534.json` |
| Linux | `~/.config/quantex/j2534.json` |
| Windows | `%APPDATA%\Quantex\j2534.json` |
| Android | Resolved through the app context (external files dir); fallback `~/.config/quantex/j2534.json` |

If the file is missing or unparsable, `PassThruOpen` with an explicit
connection string still works; `PassThruOpen(NULL)` returns `ERR_FAILED`
(`PassThruGetLastError`: `"j2534.json parse error"` or no device configured).

## How the library uses it

`PassThruOpen(name)`:

1. If `name` contains a `;` (an explicit connection string such as
   `sd0;n192.168.12.3`) — the file is ignored for device selection and the
   string is used as-is.
2. If `name` is `NULL`, empty, or has no `;` — the library takes
   `devices[current_device]`, then `interface[current_interface]` of that
   device, and builds the connection string from it.

This means a Quantex application (or your own tool) can re-point all
J2534-04.04 applications to another device or transport by editing two integer
fields.

## Structure

```json
{
  "current_device": 0,
  "log_level": 3,
  "devices": [
    {
      "sn": "N49999",
      "current_interface": 0,
      "interface": [
        { "type": "n", "ip": "192.168.12.3" },
        { "type": "b", "device_name": "N49999" },
        { "type": "c", "device_name": "/dev/tty.usbserial-DP04XHM7" }
      ]
    }
  ]
}
```

### Top-level fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `current_device` | integer | no | Index into `devices` used by `PassThruOpen(NULL)` (default 0) |
| `log_level` | integer | no | Log verbosity: `-1` off, `0` errors, `1` +warnings, `2` +info, `3` +debug (default), `4` +verbose. Out-of-range values are clamped. At `-1` no `.qlog` file is created — see [Logging](#logging) |
| `devices` | array | yes | Device configurations (max 16) |

### Device object

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `sn` | string | yes | Serial number, e.g. `"N49999"`, `"S1001"` |
| `current_interface` | integer | no | Index into `interface` (default 0) |
| `interface` | array | yes | Connection interfaces (max 4) |
| `confirmed` | string | no | Reserved — managed by Quantex software, do not set |

Serial number prefixes: `N` — ScanDoc Nano, `S` — ScanDoc Classic,
`C` — ScanDoc Compact, `X` — ScanDoc SDMax.

### Interface object

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | yes | `"n"` (LAN/Wi-Fi), `"b"` (BLE), `"c"` (USB serial), `"h"` (reserved) |
| `ip` | string | for `"n"` | Device IP address |
| `device_name` | string | for `"b"`, `"c"` | BLE name (= serial number) or serial port path |
| `pin` | string | no | Reserved — managed by Quantex software, do not set |

Default IPs when `ip` is empty: ScanDoc Classic (`S*`) `192.168.1.3`,
ScanDoc Nano / SDMax (`N*`, `X*`) `192.168.12.3`.

### Example: two devices, second one on BLE

```json
{
  "current_device": 1,
  "devices": [
    {
      "sn": "S1001",
      "current_interface": 0,
      "interface": [ { "type": "n", "ip": "192.168.1.3" } ]
    },
    {
      "sn": "N49999",
      "current_interface": 1,
      "interface": [
        { "type": "n", "ip": "192.168.12.3" },
        { "type": "b", "device_name": "N49999" }
      ]
    }
  ]
}
```

With this file, `PassThruOpen(NULL, &id)` connects to `N49999` over BLE.

## Logging

The library writes `.qlog` files (format: [LOG_FORMAT.md](LOG_FORMAT.md)) to
`<config_dir>/sdlogs/`, one file per `PassThruOpen`:

| Platform | Log directory |
|----------|---------------|
| macOS | `~/Library/Application Support/Quantex/sdlogs/` |
| Linux | `~/.config/quantex/sdlogs/` |
| Windows | `%APPDATA%\Quantex\sdlogs\` |
| Android | `<getExternalFilesDir(null)>/sdlogs/`, i.e. `/sdcard/Android/data/<applicationId>/files/sdlogs/` |
| iOS | `<Application Support>/Quantex/sdlogs/` inside the app sandbox |

File name pattern: `id<N>_YYYYMMDD_HHMMSS.qlog`. On every `PassThruClose` the
library deletes `.qlog` files older than 30 days. The location is not
configurable.

If the library crashes, a `.crash` dump file is written to the same
directory — include it when contacting support.

### Turning the log off

`log_level: -1` disables logging: no `.qlog` file is created, nothing —
including message payloads — is written to disk. Isolated error lines may
still reach stdout (logcat on Android); they are not persisted.

Applications that must not depend on a file in a user-writable directory can
set the level from code before `PassThruOpen`. On Android that is one JNI
call (see [ANDROID.md](ANDROID.md)):

```kotlin
j2534.ptSetLogLevel(-1)   // release build: logging off
j2534.ptSetLogLevel(3)    // support case: full log
```

A level set this way wins over the `log_level` key of `j2534.json` — a config
file left in app storage cannot re-enable logging in a release build.

## Windows registry

On Windows, third-party J2534 applications find the DLL through the standard
SAE J2534 registry scheme (created by the ScanDoc installer / Quantex
software):

```reg
[HKEY_LOCAL_MACHINE\SOFTWARE\PassThruSupport.04.04\Quantex - ScanDoc]
"Name"="ScanDoc"
"Vendor"="Quantex"
"FunctionLibrary"="C:\\Program Files\\Quantex\\J2534\\j2534sd_v04_04_x64.dll"
"ConfigApplication"="C:\\Program Files\\Quantex\\J2534\\SDbootloader.exe"
; protocol capability flags
"CAN"=dword:00000001
"ISO15765"=dword:00000001
```

For 32-bit applications on 64-bit Windows the same key lives under
`HKLM\SOFTWARE\Wow6432Node\PassThruSupport.04.04\`.

The registry only locates the DLL. Device and transport selection is done by
`j2534.json` (above) or by an explicit connection string in `PassThruOpen`.
