Chapter 12: NLC400 BLE Scanner Support - zymbia-carpm/garagepro_sdk GitHub Wiki

This chapter explains how to run the SDK on an NLC400 BLE scanner that your app connects to itself: VIN check, full scan, clear codes and live data. NLC400 support was added in SDK version 29 (0.3.2); live data needs 0.6.6 or later (see Requirements).

Your app owns the Bluetooth permissions, the device scan and the BLE connection. You hand the connected scanner to the SDK, and the SDK runs every diagnostic over it without showing any dialogs or permission prompts of its own. Results and failures arrive through the same 'GProScanListener' / 'GProLiveScanListener' callbacks described in Chapter 3 and Chapter 5.

Requirements

  • SDK 0.6.6 or later. On earlier versions, standard OBD live values such as engine speed and coolant temperature come back empty on this scanner. We recommend the latest version (see Upgrade).
  • An authenticated session. Call GProAuthentication as described in Chapter 2: Authentication, using the integration token issued to you for this mode. With any other token, every operation ends in onScanAuthenticationFailure / onLiveScanAuthenticationFailure with "Master authentication failed".
  • Bluetooth permissions held by your app. On Android 12 and above these are BLUETOOTH_SCAN and BLUETOOTH_CONNECT. The SDK never requests them.

Step 1: Connect to the scanner

Create the connection with the scanner's GATT UUIDs, then connect using the SDK's callback:

GProDeviceConnection connection = GProDeviceConnection.forBle(
        UUID.fromString("0000d0f0-0000-1000-8000-00805f9b34fb"),   // service
        UUID.fromString("f3ef0320-f04f-47b0-4620-4921b116d133"),   // write characteristic
        UUID.fromString("6825da15-2f00-8b21-6967-d1508b232801"));  // notify characteristic

BluetoothGatt gatt = device.connectGatt(context, false, connection.getGattCallback());
connection.attachGatt(gatt);

device is the scanner's BluetoothDevice, taken from your own BLE scan. The UUIDs above are the NLC400's.

While the connection is attached:

  • Pass connection.getGattCallback() to connectGatt exactly as returned. Do not wrap it or substitute your own callback.
  • Call attachGatt(gatt) straight after connectGatt.
  • The SDK discovers the services and turns on notifications itself. Do not run your own GATT operations on this gatt.
  • The SDK never disconnects or closes the gatt. That stays with your app (see Step 5).

You can start an operation straight away. The SDK waits up to 15 seconds for the scanner to become ready before it reports a connection failure.

Step 2: VIN check, full scan and clear codes

Pass the connection to 'GProScanProcess' and call the functions you already use:

GProScanProcess gProScanProcess = new GProScanProcess(context, connection, scanListener);

gProScanProcess.initVinCheck(makeName, registrationNumber, jobCardId);    // read the vehicle VIN
gProScanProcess.initScan(makeName, registrationNumber, jobCardId);        // full fault scan
gProScanProcess.initClearCodes(makeName, registrationNumber, jobCardId);  // clear fault codes

The callbacks are the ones described in Chapter 3: Scan and Clear Process.

Step 3: Live data

Pass the same connection to 'GProLiveScanProcess':

GProLiveScanProcess gProLiveScanProcess = new GProLiveScanProcess(context, connection, liveListener);
gProLiveScanProcess.initLiveScan(makeName, modelName, variantName, registrationNumber, jobCardId);

From here the flow is the one in Steps 4 to 8 of Chapter 5: Live Data Scan Process:

  1. onLiveScanModulesList(moduleList) gives the modules. Pick one with selectLiveScanModule(moduleName).
  2. onLiveScanModuleCommandList(commandList) gives that module's commands. Pick the ones to run with selectLiveScanModuleCommands(commandList).
  3. onLiveScanResultUpdate(resultHashMap) then delivers fresh values repeatedly, until you stop.
  4. endLiveScan() ends the session and saves the readings gathered so far. Live data does not end on its own.

What is different from the SDK-managed flow

  • Skip the activity launchers. Step 2 of Chapter 3 and Chapter 5 (activity result launchers and forwarding onRequestPermissionsResult) is not needed.
  • No SDK screens. The SDK shows no scanner list and no Bluetooth or permission prompts. onPermissionRequest / onPermissionFailure and onLiveScanPermissionRequest / onLiveScanPermissionFailure are not called.
  • Errors arrive as callbacks. Where the SDK-managed flow would show an error dialog, you receive the failure callback instead, for example onLiveScanFailed(...) for live data.
  • onScannerConnectionCompleted / onLiveScanScannerConnectionCompleted still tell you when the SDK has started talking to the scanner.

Step 4: One operation at a time

One connection can carry a VIN check, a scan, clear codes and live data one after another. You do not need to reconnect in between.

The scanner runs one operation at a time. Let the current one finish, or end it (for example with endLiveScan() or abruptEndScan()), before starting the next. An operation started while another is still running is refused straight away through its failure callback, with the message "Another operation is already in progress".

Step 5: Stop and disconnect

Force stop. forceStop() on either process stops the current operation immediately and releases the connection, as described in Chapter 7. A connection that has been force-stopped cannot be used again: close the gatt and connect again with a new GProDeviceConnection.

When you are finished with the scanner:

connection.release();
gatt.disconnect();
gatt.close();

If the scanner disconnects during an operation, the operation ends with an error callback. Reconnecting is up to your app: connect again with a new GProDeviceConnection (Step 1), then start the operation again.

What the NLC400 supports

Function On the NLC400
VIN check Yes
Full scan and clear codes Yes
Live data Yes, on SDK 0.6.6 or later
Battery voltage (live data) Not available; the reading shows no value
K-Line modules Yes, see Chapter 9 and K-Line Start Communication below

K-Line Start Communication (0.8.4)

From 0.8.4 the SDK opens each K-Line control unit with the scanner's Start Communication command ($apkss) before reading it, following the scanner's K-Line Start Communication documents.

If a scanner does not acknowledge the command, for example because its firmware predates it, the SDK reads K-Line as in 0.8.3 for the rest of that connection. From 0.8.5 it does so only after two K-Line control units in a row go unacknowledged and only if the scanner has never acknowledged the command on that connection; scanners with firmware SV 2.39 or later always keep using it. To use the 0.8.3 behaviour on every scanner, turn it off before creating the connection:

GProDeviceConnection.setNlc400KlineStartCommunicationEnabled(false);

The scanner takes 8 to 10 seconds to open a K-Line control unit, and the SDK waits up to 12 seconds for it, after first waiting for the scanner to be ready. Leave that wait at its default unless we ask you to change it:

GProDeviceConnection.setNlc400KlineStartTimeoutMs(0);   // 0 = the built-in 12 seconds

Both settings are static, affect the whole process, and have no effect on CAN control units.

Troubleshooting

If a scan or live data comes back empty, turn on diagnostic logging before creating the connection, repeat the scan and send us the Logcat output (tag GProDiag) together with the vehicle's registration number:

GProDeviceConnection.setDiagnosticLogging(true);

Off by default. Leave it off in production.

Upgrade

implementation ('com.github.zymbia-carpm:garagepro_sdk:v0.8.5') {
    transitive = true
}

NOTE — If you are upgrading from 0.4.1 or earlier, read the breaking changes in the v0.6.0 release notes first. Among them, all listener callbacks are now delivered on the main thread.