tirecheck-device-sdk 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -21,13 +21,15 @@ const store = {
21
21
  simulatedDevices: {},
22
22
  /** undefined - no information but since we get advertisings it is most likely disconnected, connecting - trying to connect via bluetooth, connected - connected via bluetooth (can send write and read), paired - all additional connection steps completed (setMtu, sendPin, etc) */
23
23
  deviceState: {},
24
- // undefined => connecting => connected => paired => disconnecting => disconnected
24
+ // undefined => connecting => connected => paired => disconnecting => undefined
25
25
  bridgesReboot: {},
26
26
  //** Ios uses generated device Id, bridges send mac address in advertising so internaly we always use mac address but when real device id is needed we check mapping table for it */
27
27
  deviceIdMapingTable: {},
28
- setState(deviceId, state) {
28
+ /** Used to change device state in store, also notifies app via calback. Every undefined state should have its reason so that app can handle it accordingly */
29
+ setState(deviceId, state, reason) {
30
+ if (state === void 0 && !reason) console.error("setState called with undefined state and no reason");
29
31
  this.deviceState[deviceId] = state;
30
- deviceStateChangeCallback?.(deviceId, state);
32
+ deviceStateChangeCallback?.(deviceId, state, reason);
31
33
  }
32
34
  };
33
35
 
@@ -322,7 +324,8 @@ const bridgeAdvertisingParser = {
322
324
  };
323
325
  function getAdvertisingType(device) {
324
326
  if (device.advertising?.kCBAdvDataIsConnectable) {
325
- return "connectable";
327
+ const adv = Array.from(new Uint8Array(device.advertising.kCBAdvDataManufacturerData));
328
+ return adv.length > 34 ? "connectable" : "unknown";
326
329
  }
327
330
  const numberArray = Array.from(new Uint8Array(device.advertising));
328
331
  if (___default.isEqual(numberArray.slice(0, 4), [2, 1, 6, 7])) {
@@ -414,11 +417,8 @@ const bridgeOtaAdvertisingParser = {
414
417
  let bridgeId = "";
415
418
  let processedByteCount = 0;
416
419
  if (store.platform === "ios") {
417
- if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress)
418
- return console.warn("No mac address in advertising data");
419
- const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).map(
420
- (x) => bridgeTools.decimalToHex(x).toUpperCase()
421
- );
420
+ if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress) return void 0;
421
+ const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).slice(-6).reverse().map((x) => bridgeTools.decimalToHex(x).toUpperCase());
422
422
  deviceId = macAddress.join(":");
423
423
  bridgeId = macAddress.join("");
424
424
  } else {
@@ -438,7 +438,7 @@ const bridgeOtaAdvertisingParser = {
438
438
  }
439
439
  } while (processedByteCount < adv.length);
440
440
  }
441
- if (!deviceId) return console.warn("Failed to get device Id");
441
+ if (!deviceId) return void 0;
442
442
  store.deviceIdMapingTable[deviceId] = device.id;
443
443
  const bleDevice = {
444
444
  ...device,
@@ -463,6 +463,7 @@ const deviceMeta = {
463
463
  },
464
464
  bridgeOta: {
465
465
  nameRegex: /(CAN BLE BRDG OTA.*|0303.{2}_B)/,
466
+ mtu: store.platform === "android" ? 512 : 180,
466
467
  characteristic: {
467
468
  serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
468
469
  characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d7"
@@ -515,19 +516,17 @@ const deviceMeta = {
515
516
  const checkUnreachableDevicesTimeouts = {};
516
517
  let deviceAdvertisingCallback;
517
518
  let deviceUnreachableCallback;
518
- let deviceLostConnectionCallback;
519
519
  let deviceStateChangeCallback;
520
520
  const bluetooth = {
521
521
  /** Triggered when "scanDevices" detects device supported by SDK */
522
522
  onDeviceAdvertising(callback) {
523
523
  deviceAdvertisingCallback = callback;
524
524
  },
525
+ /** Triggered when device doesnt send advertisement for 60 seconds */
525
526
  onDeviceUnreachable(callback) {
526
527
  deviceUnreachableCallback = callback;
527
528
  },
528
- onDeviceLostConnection(callback) {
529
- deviceLostConnectionCallback = callback;
530
- },
529
+ /** Triggered when device changed state, allows app to react to state changes */
531
530
  onDeviceStateChange(callback) {
532
531
  deviceStateChangeCallback = callback;
533
532
  },
@@ -572,13 +571,17 @@ async function connect(deviceId, disconnectCallback) {
572
571
  if (connectedDevice) break;
573
572
  } catch (e) {
574
573
  console.warn(`${attempt} connect fail`, e);
575
- if (attempt === 3) throw new Error("Connection unsuccessful");
574
+ if (attempt === 3) {
575
+ store.setState(deviceId, void 0, "failedConnection");
576
+ throw new Error("Connection unsuccessful");
577
+ }
576
578
  }
577
579
  }
580
+ clearTimeout(checkUnreachableDevicesTimeouts[deviceId]);
578
581
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
579
582
  const isConnected = await ble.isConnected(_deviceId);
580
583
  if (!isConnected) {
581
- store.setState(deviceId, void 0);
584
+ store.setState(deviceId, void 0, "failedConnection");
582
585
  throw new Error("Connect Error");
583
586
  }
584
587
  store.setState(deviceId, "connected");
@@ -589,8 +592,7 @@ function connectInner(deviceId, disconnectCallback) {
589
592
  return new Promise(
590
593
  (resolve, reject) => ble.connect(_deviceId, resolve, (err) => {
591
594
  if (toolsSvc.canCommunicateWith(deviceId)) {
592
- deviceLostConnectionCallback?.(deviceId);
593
- disconnectCallback(deviceId);
595
+ disconnectCallback(deviceId, "lostConnection");
594
596
  }
595
597
  reject(err);
596
598
  })
@@ -603,14 +605,18 @@ async function disconnect(deviceId) {
603
605
  const isConnected = await ble.isConnected(_deviceId);
604
606
  if (!isConnected) return;
605
607
  }
606
- store.setState(deviceId, void 0);
608
+ store.setState(deviceId, void 0, "failedDisconnection");
607
609
  throw new Error("Disconnect unsuccessful");
608
610
  }
609
- async function write(deviceId, serviceUuid, characteristicUuid, value) {
611
+ async function write(deviceId, serviceUuid, characteristicUuid, value, withResponse) {
610
612
  if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Write Error: Not connected to device");
611
613
  try {
612
614
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
613
- await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
615
+ if (withResponse) {
616
+ await ble.write(_deviceId, serviceUuid, characteristicUuid, value);
617
+ } else {
618
+ await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
619
+ }
614
620
  } catch (e) {
615
621
  throw new Error(`Write Error: ${e}`);
616
622
  }
@@ -657,7 +663,7 @@ function refreshUnreachableTimeouts(deviceId) {
657
663
  clearTimeout(checkUnreachableDevicesTimeouts[deviceId]);
658
664
  }
659
665
  checkUnreachableDevicesTimeouts[deviceId] = setTimeout(() => {
660
- store.setState(deviceId, void 0);
666
+ delete store.devices[deviceId];
661
667
  deviceUnreachableCallback?.(deviceId);
662
668
  }, 6e4);
663
669
  }
@@ -1547,13 +1553,14 @@ const promiseQueue$1 = {
1547
1553
  );
1548
1554
  }
1549
1555
  });
1550
- return withTimeout(promise, 5e3, "Command timed out");
1556
+ return withTimeout(promise, 5e3, `Command timed out ${responseIdentifier}`);
1551
1557
  });
1552
1558
  return promiseQueue;
1553
1559
  },
1554
1560
  async processMessage(deviceId, payload) {
1555
1561
  const numberArray = Array.from(new Uint8Array(payload));
1556
1562
  if (numberArray[3] === 127) {
1563
+ console.error(numberArray);
1557
1564
  return currentReject(new Error(`Command not succesful: ${numberArray[4]}`));
1558
1565
  }
1559
1566
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
@@ -1956,7 +1963,7 @@ const bridgeCommands = {
1956
1963
  if (!canCommunicateWith(device.id)) throw new Error("Bridge not connected");
1957
1964
  clearTimeout(keepAliveTimer);
1958
1965
  keepAliveTimer = setTimeout(() => {
1959
- if (!canCommunicateWith(device.id)) {
1966
+ if (!canCommunicateWith(device.id) || store.devices[device.id]?.type !== "bridge") {
1960
1967
  return;
1961
1968
  }
1962
1969
  this.sendKeepAliveCommand(device);
@@ -1970,17 +1977,16 @@ const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
1970
1977
  const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
1971
1978
  const bridgeOtaCommands = {
1972
1979
  async beginOta(deviceId) {
1973
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer);
1980
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
1974
1981
  },
1975
1982
  async uploadOtaChunk(deviceId, data) {
1976
- await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data);
1983
+ await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
1977
1984
  },
1978
1985
  async endOta(deviceId) {
1979
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer);
1986
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
1980
1987
  }
1981
1988
  };
1982
1989
 
1983
- const mtu = store.platform === "android" ? 512 : 180;
1984
1990
  const bridgeOtaService = {
1985
1991
  async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
1986
1992
  await delay(2e3);
@@ -2010,7 +2016,7 @@ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2010
2016
  )} KB)`,
2011
2017
  uploadedBytes / firmwareBinary.byteLength
2012
2018
  );
2013
- const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2019
+ const chunkSize = Math.min(deviceMeta.bridgeOta.mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2014
2020
  const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
2015
2021
  await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
2016
2022
  uploadedBytes += chunkSize;
@@ -2021,12 +2027,14 @@ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2021
2027
  const bridgeOta = {
2022
2028
  async connect(deviceId) {
2023
2029
  await bluetooth.connect(deviceId, this.disconnect);
2030
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2031
+ await ble.requestMtu(_deviceId, deviceMeta.bridgeOta.mtu);
2024
2032
  store.setState(deviceId, "paired");
2025
2033
  },
2026
- async disconnect(deviceId) {
2034
+ async disconnect(deviceId, reason) {
2027
2035
  store.setState(deviceId, "disconnecting");
2028
2036
  await bluetooth.disconnect(deviceId);
2029
- store.setState(deviceId, "disconnected");
2037
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2030
2038
  },
2031
2039
  async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
2032
2040
  return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
@@ -2055,6 +2063,7 @@ const bridgeService = {
2055
2063
  async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2056
2064
  reportStatus("Sending OTA Request...", 0.02);
2057
2065
  await bridgeCommands.sendOtaRequest(deviceId);
2066
+ await bridge.disconnect(deviceId, "firmwareUpdate");
2058
2067
  await toolsSvc.delay(2e3);
2059
2068
  await bluetooth.scanDevices();
2060
2069
  reportStatus("Discovering OTA Device...", 0.02);
@@ -2365,7 +2374,8 @@ async function getSensorReading(deviceId, positionId) {
2365
2374
  sensorStatus: value[12],
2366
2375
  eceStatus: value[13],
2367
2376
  pressureIssue: getPressureIssue(deviceId, value[13]),
2368
- ...getPressureAndTemperatureReadingObjects(value[9], value[10])
2377
+ ...getPressureAndTemperatureReadingObjects(value[9], value[10]),
2378
+ byteReading: value
2369
2379
  };
2370
2380
  }
2371
2381
  async function getVehicleReadings(deviceId, tcVehicle) {
@@ -2687,11 +2697,13 @@ const bridge = {
2687
2697
  await bridgeCommands.sendPinCommand(deviceId);
2688
2698
  store.setState(deviceId, "paired");
2689
2699
  },
2690
- async disconnect(deviceId) {
2700
+ async disconnect(deviceId, reason) {
2691
2701
  store.setState(deviceId, "disconnecting");
2692
2702
  promiseQueue$1.clearQueue("Previous pending commands aborted");
2693
2703
  await bluetooth.disconnect(deviceId);
2694
- store.setState(deviceId, "disconnected");
2704
+ delete store.devices[deviceId];
2705
+ deviceUnreachableCallback?.(deviceId);
2706
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2695
2707
  },
2696
2708
  getVehicle: bridgeService.getVehicle,
2697
2709
  setVehicle: bridgeService.setVehicle,
@@ -2827,10 +2839,10 @@ const flexiGaugeTpms = {
2827
2839
  );
2828
2840
  store.setState(deviceId, "paired");
2829
2841
  },
2830
- async disconnect(deviceId) {
2842
+ async disconnect(deviceId, reason) {
2831
2843
  store.setState(deviceId, "disconnecting");
2832
2844
  await bluetooth.disconnect(deviceId);
2833
- store.setState(deviceId, "disconnected");
2845
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2834
2846
  },
2835
2847
  onTreadDepth(callback) {
2836
2848
  flexiGaugeTpmsService.onTreadDepth(callback);
@@ -2901,7 +2913,7 @@ const bridgeSimulator = {
2901
2913
  async disconnect(deviceId) {
2902
2914
  store.deviceState[deviceId] = "disconnecting";
2903
2915
  await toolsSvc.delay(100);
2904
- store.deviceState[deviceId] = "disconnected";
2916
+ store.deviceState[deviceId] = void 0;
2905
2917
  },
2906
2918
  createSimulatedBridge(initialData) {
2907
2919
  return {
@@ -2928,7 +2940,8 @@ const bridgeSimulator = {
2928
2940
  sensorStatus: 0,
2929
2941
  pressure: { bar: 0, meas: 0, raw: 0 },
2930
2942
  pressureIssue: void 0,
2931
- temperature: { amb: 0, celsius: 0, raw: 0 }
2943
+ temperature: { amb: 0, celsius: 0, raw: 0 },
2944
+ byteReading: [0, 0, 0, 0, 0, 0, 0, 0]
2932
2945
  }
2933
2946
  },
2934
2947
  vehicle: {
package/dist/index.d.cts CHANGED
@@ -7,6 +7,7 @@ interface BleImplementation {
7
7
  connect: (device_id: string, connectCallback: (data: PeripheralDataExtended) => any, disconnectCallback: (error: string | BLEError) => any) => void;
8
8
  disconnect: (deviceId: string) => Promise<void>;
9
9
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<ArrayBuffer>;
10
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
10
11
  writeWithoutResponse: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => void;
11
12
  startNotification: (deviceId: string, serviceUuid: string, characteristicUuid: string, success: (rawData: ArrayBuffer) => any, failure?: (error: string | BLEError) => any) => Promise<void>;
12
13
  isEnabled: () => Promise<void>;
@@ -48,7 +49,7 @@ interface PeripheralCharacteristic {
48
49
  properties: string[];
49
50
  descriptors?: any[];
50
51
  }
51
- type PeripheralState = 'disconnected' | 'disconnecting' | 'connecting' | 'connected';
52
+ type PeripheralState = 'disconnecting' | 'connecting' | 'connected';
52
53
 
53
54
  declare const _default$1: {
54
55
  bridge: {
@@ -62,11 +63,12 @@ declare const _default$1: {
62
63
  };
63
64
  bridgeOta: {
64
65
  nameRegex: RegExp;
66
+ mtu: number;
65
67
  characteristic: {
66
68
  serviceId: string;
67
69
  characteristicId: string;
68
70
  };
69
- getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
71
+ getDeviceInfoFromAdvertising: (device: PeripheralData) => BleDevice | undefined;
70
72
  };
71
73
  flexiGaugeTpms: {
72
74
  nameRegex: RegExp;
@@ -766,6 +768,7 @@ interface BridgeReading {
766
768
  amb: number;
767
769
  celsius: number;
768
770
  };
771
+ byteReading: number[];
769
772
  }
770
773
  interface BridgeAutolearnStatus {
771
774
  positionId: number;
@@ -806,6 +809,7 @@ interface BridgeCommandStructureProperties {
806
809
  size: number;
807
810
  display?: 'decimal' | 'ascii';
808
811
  description: string;
812
+ optional?: boolean;
809
813
  };
810
814
  }
811
815
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
@@ -815,7 +819,7 @@ type BleDeviceType = keyof typeof _default$1;
815
819
  /** distinguish by type, e.g. `if (device.type === 'bridge')`, to access furhter fields */
816
820
  type BleDevice = BleBridge | BleBridgeOta | BleFlexiGaugeTpms;
817
821
  type BleDeviceSimulated = BleBridgeSimulated;
818
- type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | 'disconnected' | undefined;
822
+ type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | undefined;
819
823
  interface BleDeviceBase {
820
824
  /** WARNING: it differs on Android and iOS.
821
825
  * Android: device's mac address
@@ -870,25 +874,25 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
870
874
  [K in keyof T]: (...args: [next: (...paramsOverride: any[]) => ReturnType<T[K]>, ...Parameters<T[K]>]) => ReturnType<T[K]>;
871
875
  };
872
876
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
877
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
873
878
 
874
879
  declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
875
880
  /** Generic methods common for all devices */
876
881
  bluetooth: {
877
882
  onDeviceAdvertising(callback: (device: BleDevice) => void): void;
878
883
  onDeviceUnreachable(callback: (deviceId: string) => void): void;
879
- onDeviceLostConnection(callback: (deviceId: string) => void): void;
880
- onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
884
+ onDeviceStateChange(callback: (deviceId: string, state?: string, reason?: string) => void): void;
881
885
  scanDevices: (services?: string[], duration?: number) => Promise<void>;
882
886
  stopScan(): void;
883
887
  connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
884
888
  disconnect: (deviceId: string) => Promise<void>;
885
- write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
889
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer, withResponse?: boolean) => Promise<void>;
886
890
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
887
891
  };
888
892
  /** Methods for working with Tirecheck CAN Bridge */
889
893
  bridge: {
890
894
  connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
891
- disconnect(deviceId: string): Promise<void>;
895
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
892
896
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
893
897
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
894
898
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
@@ -902,13 +906,13 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
902
906
  /** Methods for working with Tirecheck CAN Bridge in OTA mode */
903
907
  bridgeOta: {
904
908
  connect(deviceId: string): Promise<void>;
905
- disconnect(deviceId: string): Promise<void>;
909
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
906
910
  updateFirmware(deviceId: string, bootloader: ArrayBuffer, firmware: ArrayBuffer, progressCallback: ReportStatusFn): Promise<void>;
907
911
  };
908
912
  /** Methods for working with Tirecheck TPMS FlexiGauge */
909
913
  flexiGaugeTpms: {
910
914
  connect(deviceId: string): Promise<void>;
911
- disconnect(deviceId: string): Promise<void>;
915
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
912
916
  onTreadDepth(callback: (value: number) => void): void;
913
917
  onButtonPress(callback: (buttonName: string) => void): void;
914
918
  onTpms(callback: (tpms: FgSensorReading | undefined) => void): void;
@@ -923,4 +927,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
923
927
  };
924
928
  };
925
929
 
926
- export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
930
+ export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.d.mts CHANGED
@@ -7,6 +7,7 @@ interface BleImplementation {
7
7
  connect: (device_id: string, connectCallback: (data: PeripheralDataExtended) => any, disconnectCallback: (error: string | BLEError) => any) => void;
8
8
  disconnect: (deviceId: string) => Promise<void>;
9
9
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<ArrayBuffer>;
10
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
10
11
  writeWithoutResponse: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => void;
11
12
  startNotification: (deviceId: string, serviceUuid: string, characteristicUuid: string, success: (rawData: ArrayBuffer) => any, failure?: (error: string | BLEError) => any) => Promise<void>;
12
13
  isEnabled: () => Promise<void>;
@@ -48,7 +49,7 @@ interface PeripheralCharacteristic {
48
49
  properties: string[];
49
50
  descriptors?: any[];
50
51
  }
51
- type PeripheralState = 'disconnected' | 'disconnecting' | 'connecting' | 'connected';
52
+ type PeripheralState = 'disconnecting' | 'connecting' | 'connected';
52
53
 
53
54
  declare const _default$1: {
54
55
  bridge: {
@@ -62,11 +63,12 @@ declare const _default$1: {
62
63
  };
63
64
  bridgeOta: {
64
65
  nameRegex: RegExp;
66
+ mtu: number;
65
67
  characteristic: {
66
68
  serviceId: string;
67
69
  characteristicId: string;
68
70
  };
69
- getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
71
+ getDeviceInfoFromAdvertising: (device: PeripheralData) => BleDevice | undefined;
70
72
  };
71
73
  flexiGaugeTpms: {
72
74
  nameRegex: RegExp;
@@ -766,6 +768,7 @@ interface BridgeReading {
766
768
  amb: number;
767
769
  celsius: number;
768
770
  };
771
+ byteReading: number[];
769
772
  }
770
773
  interface BridgeAutolearnStatus {
771
774
  positionId: number;
@@ -806,6 +809,7 @@ interface BridgeCommandStructureProperties {
806
809
  size: number;
807
810
  display?: 'decimal' | 'ascii';
808
811
  description: string;
812
+ optional?: boolean;
809
813
  };
810
814
  }
811
815
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
@@ -815,7 +819,7 @@ type BleDeviceType = keyof typeof _default$1;
815
819
  /** distinguish by type, e.g. `if (device.type === 'bridge')`, to access furhter fields */
816
820
  type BleDevice = BleBridge | BleBridgeOta | BleFlexiGaugeTpms;
817
821
  type BleDeviceSimulated = BleBridgeSimulated;
818
- type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | 'disconnected' | undefined;
822
+ type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | undefined;
819
823
  interface BleDeviceBase {
820
824
  /** WARNING: it differs on Android and iOS.
821
825
  * Android: device's mac address
@@ -870,25 +874,25 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
870
874
  [K in keyof T]: (...args: [next: (...paramsOverride: any[]) => ReturnType<T[K]>, ...Parameters<T[K]>]) => ReturnType<T[K]>;
871
875
  };
872
876
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
877
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
873
878
 
874
879
  declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
875
880
  /** Generic methods common for all devices */
876
881
  bluetooth: {
877
882
  onDeviceAdvertising(callback: (device: BleDevice) => void): void;
878
883
  onDeviceUnreachable(callback: (deviceId: string) => void): void;
879
- onDeviceLostConnection(callback: (deviceId: string) => void): void;
880
- onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
884
+ onDeviceStateChange(callback: (deviceId: string, state?: string, reason?: string) => void): void;
881
885
  scanDevices: (services?: string[], duration?: number) => Promise<void>;
882
886
  stopScan(): void;
883
887
  connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
884
888
  disconnect: (deviceId: string) => Promise<void>;
885
- write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
889
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer, withResponse?: boolean) => Promise<void>;
886
890
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
887
891
  };
888
892
  /** Methods for working with Tirecheck CAN Bridge */
889
893
  bridge: {
890
894
  connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
891
- disconnect(deviceId: string): Promise<void>;
895
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
892
896
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
893
897
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
894
898
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
@@ -902,13 +906,13 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
902
906
  /** Methods for working with Tirecheck CAN Bridge in OTA mode */
903
907
  bridgeOta: {
904
908
  connect(deviceId: string): Promise<void>;
905
- disconnect(deviceId: string): Promise<void>;
909
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
906
910
  updateFirmware(deviceId: string, bootloader: ArrayBuffer, firmware: ArrayBuffer, progressCallback: ReportStatusFn): Promise<void>;
907
911
  };
908
912
  /** Methods for working with Tirecheck TPMS FlexiGauge */
909
913
  flexiGaugeTpms: {
910
914
  connect(deviceId: string): Promise<void>;
911
- disconnect(deviceId: string): Promise<void>;
915
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
912
916
  onTreadDepth(callback: (value: number) => void): void;
913
917
  onButtonPress(callback: (buttonName: string) => void): void;
914
918
  onTpms(callback: (tpms: FgSensorReading | undefined) => void): void;
@@ -923,4 +927,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
923
927
  };
924
928
  };
925
929
 
926
- export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
930
+ export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ interface BleImplementation {
7
7
  connect: (device_id: string, connectCallback: (data: PeripheralDataExtended) => any, disconnectCallback: (error: string | BLEError) => any) => void;
8
8
  disconnect: (deviceId: string) => Promise<void>;
9
9
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<ArrayBuffer>;
10
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
10
11
  writeWithoutResponse: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => void;
11
12
  startNotification: (deviceId: string, serviceUuid: string, characteristicUuid: string, success: (rawData: ArrayBuffer) => any, failure?: (error: string | BLEError) => any) => Promise<void>;
12
13
  isEnabled: () => Promise<void>;
@@ -48,7 +49,7 @@ interface PeripheralCharacteristic {
48
49
  properties: string[];
49
50
  descriptors?: any[];
50
51
  }
51
- type PeripheralState = 'disconnected' | 'disconnecting' | 'connecting' | 'connected';
52
+ type PeripheralState = 'disconnecting' | 'connecting' | 'connected';
52
53
 
53
54
  declare const _default$1: {
54
55
  bridge: {
@@ -62,11 +63,12 @@ declare const _default$1: {
62
63
  };
63
64
  bridgeOta: {
64
65
  nameRegex: RegExp;
66
+ mtu: number;
65
67
  characteristic: {
66
68
  serviceId: string;
67
69
  characteristicId: string;
68
70
  };
69
- getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
71
+ getDeviceInfoFromAdvertising: (device: PeripheralData) => BleDevice | undefined;
70
72
  };
71
73
  flexiGaugeTpms: {
72
74
  nameRegex: RegExp;
@@ -766,6 +768,7 @@ interface BridgeReading {
766
768
  amb: number;
767
769
  celsius: number;
768
770
  };
771
+ byteReading: number[];
769
772
  }
770
773
  interface BridgeAutolearnStatus {
771
774
  positionId: number;
@@ -806,6 +809,7 @@ interface BridgeCommandStructureProperties {
806
809
  size: number;
807
810
  display?: 'decimal' | 'ascii';
808
811
  description: string;
812
+ optional?: boolean;
809
813
  };
810
814
  }
811
815
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
@@ -815,7 +819,7 @@ type BleDeviceType = keyof typeof _default$1;
815
819
  /** distinguish by type, e.g. `if (device.type === 'bridge')`, to access furhter fields */
816
820
  type BleDevice = BleBridge | BleBridgeOta | BleFlexiGaugeTpms;
817
821
  type BleDeviceSimulated = BleBridgeSimulated;
818
- type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | 'disconnected' | undefined;
822
+ type BleDeviceStatus = 'connected' | 'connecting' | 'disconnecting' | undefined;
819
823
  interface BleDeviceBase {
820
824
  /** WARNING: it differs on Android and iOS.
821
825
  * Android: device's mac address
@@ -870,25 +874,25 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
870
874
  [K in keyof T]: (...args: [next: (...paramsOverride: any[]) => ReturnType<T[K]>, ...Parameters<T[K]>]) => ReturnType<T[K]>;
871
875
  };
872
876
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
877
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
873
878
 
874
879
  declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
875
880
  /** Generic methods common for all devices */
876
881
  bluetooth: {
877
882
  onDeviceAdvertising(callback: (device: BleDevice) => void): void;
878
883
  onDeviceUnreachable(callback: (deviceId: string) => void): void;
879
- onDeviceLostConnection(callback: (deviceId: string) => void): void;
880
- onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
884
+ onDeviceStateChange(callback: (deviceId: string, state?: string, reason?: string) => void): void;
881
885
  scanDevices: (services?: string[], duration?: number) => Promise<void>;
882
886
  stopScan(): void;
883
887
  connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
884
888
  disconnect: (deviceId: string) => Promise<void>;
885
- write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
889
+ write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer, withResponse?: boolean) => Promise<void>;
886
890
  read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
887
891
  };
888
892
  /** Methods for working with Tirecheck CAN Bridge */
889
893
  bridge: {
890
894
  connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
891
- disconnect(deviceId: string): Promise<void>;
895
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
892
896
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
893
897
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
894
898
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
@@ -902,13 +906,13 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
902
906
  /** Methods for working with Tirecheck CAN Bridge in OTA mode */
903
907
  bridgeOta: {
904
908
  connect(deviceId: string): Promise<void>;
905
- disconnect(deviceId: string): Promise<void>;
909
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
906
910
  updateFirmware(deviceId: string, bootloader: ArrayBuffer, firmware: ArrayBuffer, progressCallback: ReportStatusFn): Promise<void>;
907
911
  };
908
912
  /** Methods for working with Tirecheck TPMS FlexiGauge */
909
913
  flexiGaugeTpms: {
910
914
  connect(deviceId: string): Promise<void>;
911
- disconnect(deviceId: string): Promise<void>;
915
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
912
916
  onTreadDepth(callback: (value: number) => void): void;
913
917
  onButtonPress(callback: (buttonName: string) => void): void;
914
918
  onTpms(callback: (tpms: FgSensorReading | undefined) => void): void;
@@ -923,4 +927,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation,
923
927
  };
924
928
  };
925
929
 
926
- export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
930
+ export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.mjs CHANGED
@@ -14,13 +14,15 @@ const store = {
14
14
  simulatedDevices: {},
15
15
  /** undefined - no information but since we get advertisings it is most likely disconnected, connecting - trying to connect via bluetooth, connected - connected via bluetooth (can send write and read), paired - all additional connection steps completed (setMtu, sendPin, etc) */
16
16
  deviceState: {},
17
- // undefined => connecting => connected => paired => disconnecting => disconnected
17
+ // undefined => connecting => connected => paired => disconnecting => undefined
18
18
  bridgesReboot: {},
19
19
  //** Ios uses generated device Id, bridges send mac address in advertising so internaly we always use mac address but when real device id is needed we check mapping table for it */
20
20
  deviceIdMapingTable: {},
21
- setState(deviceId, state) {
21
+ /** Used to change device state in store, also notifies app via calback. Every undefined state should have its reason so that app can handle it accordingly */
22
+ setState(deviceId, state, reason) {
23
+ if (state === void 0 && !reason) console.error("setState called with undefined state and no reason");
22
24
  this.deviceState[deviceId] = state;
23
- deviceStateChangeCallback?.(deviceId, state);
25
+ deviceStateChangeCallback?.(deviceId, state, reason);
24
26
  }
25
27
  };
26
28
 
@@ -315,7 +317,8 @@ const bridgeAdvertisingParser = {
315
317
  };
316
318
  function getAdvertisingType(device) {
317
319
  if (device.advertising?.kCBAdvDataIsConnectable) {
318
- return "connectable";
320
+ const adv = Array.from(new Uint8Array(device.advertising.kCBAdvDataManufacturerData));
321
+ return adv.length > 34 ? "connectable" : "unknown";
319
322
  }
320
323
  const numberArray = Array.from(new Uint8Array(device.advertising));
321
324
  if (_.isEqual(numberArray.slice(0, 4), [2, 1, 6, 7])) {
@@ -407,11 +410,8 @@ const bridgeOtaAdvertisingParser = {
407
410
  let bridgeId = "";
408
411
  let processedByteCount = 0;
409
412
  if (store.platform === "ios") {
410
- if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress)
411
- return console.warn("No mac address in advertising data");
412
- const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).map(
413
- (x) => bridgeTools.decimalToHex(x).toUpperCase()
414
- );
413
+ if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress) return void 0;
414
+ const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).slice(-6).reverse().map((x) => bridgeTools.decimalToHex(x).toUpperCase());
415
415
  deviceId = macAddress.join(":");
416
416
  bridgeId = macAddress.join("");
417
417
  } else {
@@ -431,7 +431,7 @@ const bridgeOtaAdvertisingParser = {
431
431
  }
432
432
  } while (processedByteCount < adv.length);
433
433
  }
434
- if (!deviceId) return console.warn("Failed to get device Id");
434
+ if (!deviceId) return void 0;
435
435
  store.deviceIdMapingTable[deviceId] = device.id;
436
436
  const bleDevice = {
437
437
  ...device,
@@ -456,6 +456,7 @@ const deviceMeta = {
456
456
  },
457
457
  bridgeOta: {
458
458
  nameRegex: /(CAN BLE BRDG OTA.*|0303.{2}_B)/,
459
+ mtu: store.platform === "android" ? 512 : 180,
459
460
  characteristic: {
460
461
  serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
461
462
  characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d7"
@@ -508,19 +509,17 @@ const deviceMeta = {
508
509
  const checkUnreachableDevicesTimeouts = {};
509
510
  let deviceAdvertisingCallback;
510
511
  let deviceUnreachableCallback;
511
- let deviceLostConnectionCallback;
512
512
  let deviceStateChangeCallback;
513
513
  const bluetooth = {
514
514
  /** Triggered when "scanDevices" detects device supported by SDK */
515
515
  onDeviceAdvertising(callback) {
516
516
  deviceAdvertisingCallback = callback;
517
517
  },
518
+ /** Triggered when device doesnt send advertisement for 60 seconds */
518
519
  onDeviceUnreachable(callback) {
519
520
  deviceUnreachableCallback = callback;
520
521
  },
521
- onDeviceLostConnection(callback) {
522
- deviceLostConnectionCallback = callback;
523
- },
522
+ /** Triggered when device changed state, allows app to react to state changes */
524
523
  onDeviceStateChange(callback) {
525
524
  deviceStateChangeCallback = callback;
526
525
  },
@@ -565,13 +564,17 @@ async function connect(deviceId, disconnectCallback) {
565
564
  if (connectedDevice) break;
566
565
  } catch (e) {
567
566
  console.warn(`${attempt} connect fail`, e);
568
- if (attempt === 3) throw new Error("Connection unsuccessful");
567
+ if (attempt === 3) {
568
+ store.setState(deviceId, void 0, "failedConnection");
569
+ throw new Error("Connection unsuccessful");
570
+ }
569
571
  }
570
572
  }
573
+ clearTimeout(checkUnreachableDevicesTimeouts[deviceId]);
571
574
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
572
575
  const isConnected = await ble.isConnected(_deviceId);
573
576
  if (!isConnected) {
574
- store.setState(deviceId, void 0);
577
+ store.setState(deviceId, void 0, "failedConnection");
575
578
  throw new Error("Connect Error");
576
579
  }
577
580
  store.setState(deviceId, "connected");
@@ -582,8 +585,7 @@ function connectInner(deviceId, disconnectCallback) {
582
585
  return new Promise(
583
586
  (resolve, reject) => ble.connect(_deviceId, resolve, (err) => {
584
587
  if (toolsSvc.canCommunicateWith(deviceId)) {
585
- deviceLostConnectionCallback?.(deviceId);
586
- disconnectCallback(deviceId);
588
+ disconnectCallback(deviceId, "lostConnection");
587
589
  }
588
590
  reject(err);
589
591
  })
@@ -596,14 +598,18 @@ async function disconnect(deviceId) {
596
598
  const isConnected = await ble.isConnected(_deviceId);
597
599
  if (!isConnected) return;
598
600
  }
599
- store.setState(deviceId, void 0);
601
+ store.setState(deviceId, void 0, "failedDisconnection");
600
602
  throw new Error("Disconnect unsuccessful");
601
603
  }
602
- async function write(deviceId, serviceUuid, characteristicUuid, value) {
604
+ async function write(deviceId, serviceUuid, characteristicUuid, value, withResponse) {
603
605
  if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Write Error: Not connected to device");
604
606
  try {
605
607
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
606
- await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
608
+ if (withResponse) {
609
+ await ble.write(_deviceId, serviceUuid, characteristicUuid, value);
610
+ } else {
611
+ await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
612
+ }
607
613
  } catch (e) {
608
614
  throw new Error(`Write Error: ${e}`);
609
615
  }
@@ -650,7 +656,7 @@ function refreshUnreachableTimeouts(deviceId) {
650
656
  clearTimeout(checkUnreachableDevicesTimeouts[deviceId]);
651
657
  }
652
658
  checkUnreachableDevicesTimeouts[deviceId] = setTimeout(() => {
653
- store.setState(deviceId, void 0);
659
+ delete store.devices[deviceId];
654
660
  deviceUnreachableCallback?.(deviceId);
655
661
  }, 6e4);
656
662
  }
@@ -1540,13 +1546,14 @@ const promiseQueue$1 = {
1540
1546
  );
1541
1547
  }
1542
1548
  });
1543
- return withTimeout(promise, 5e3, "Command timed out");
1549
+ return withTimeout(promise, 5e3, `Command timed out ${responseIdentifier}`);
1544
1550
  });
1545
1551
  return promiseQueue;
1546
1552
  },
1547
1553
  async processMessage(deviceId, payload) {
1548
1554
  const numberArray = Array.from(new Uint8Array(payload));
1549
1555
  if (numberArray[3] === 127) {
1556
+ console.error(numberArray);
1550
1557
  return currentReject(new Error(`Command not succesful: ${numberArray[4]}`));
1551
1558
  }
1552
1559
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
@@ -1949,7 +1956,7 @@ const bridgeCommands = {
1949
1956
  if (!canCommunicateWith(device.id)) throw new Error("Bridge not connected");
1950
1957
  clearTimeout(keepAliveTimer);
1951
1958
  keepAliveTimer = setTimeout(() => {
1952
- if (!canCommunicateWith(device.id)) {
1959
+ if (!canCommunicateWith(device.id) || store.devices[device.id]?.type !== "bridge") {
1953
1960
  return;
1954
1961
  }
1955
1962
  this.sendKeepAliveCommand(device);
@@ -1963,17 +1970,16 @@ const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
1963
1970
  const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
1964
1971
  const bridgeOtaCommands = {
1965
1972
  async beginOta(deviceId) {
1966
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer);
1973
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
1967
1974
  },
1968
1975
  async uploadOtaChunk(deviceId, data) {
1969
- await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data);
1976
+ await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
1970
1977
  },
1971
1978
  async endOta(deviceId) {
1972
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer);
1979
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
1973
1980
  }
1974
1981
  };
1975
1982
 
1976
- const mtu = store.platform === "android" ? 512 : 180;
1977
1983
  const bridgeOtaService = {
1978
1984
  async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
1979
1985
  await delay(2e3);
@@ -2003,7 +2009,7 @@ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2003
2009
  )} KB)`,
2004
2010
  uploadedBytes / firmwareBinary.byteLength
2005
2011
  );
2006
- const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2012
+ const chunkSize = Math.min(deviceMeta.bridgeOta.mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2007
2013
  const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
2008
2014
  await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
2009
2015
  uploadedBytes += chunkSize;
@@ -2014,12 +2020,14 @@ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2014
2020
  const bridgeOta = {
2015
2021
  async connect(deviceId) {
2016
2022
  await bluetooth.connect(deviceId, this.disconnect);
2023
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2024
+ await ble.requestMtu(_deviceId, deviceMeta.bridgeOta.mtu);
2017
2025
  store.setState(deviceId, "paired");
2018
2026
  },
2019
- async disconnect(deviceId) {
2027
+ async disconnect(deviceId, reason) {
2020
2028
  store.setState(deviceId, "disconnecting");
2021
2029
  await bluetooth.disconnect(deviceId);
2022
- store.setState(deviceId, "disconnected");
2030
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2023
2031
  },
2024
2032
  async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
2025
2033
  return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
@@ -2048,6 +2056,7 @@ const bridgeService = {
2048
2056
  async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2049
2057
  reportStatus("Sending OTA Request...", 0.02);
2050
2058
  await bridgeCommands.sendOtaRequest(deviceId);
2059
+ await bridge.disconnect(deviceId, "firmwareUpdate");
2051
2060
  await toolsSvc.delay(2e3);
2052
2061
  await bluetooth.scanDevices();
2053
2062
  reportStatus("Discovering OTA Device...", 0.02);
@@ -2358,7 +2367,8 @@ async function getSensorReading(deviceId, positionId) {
2358
2367
  sensorStatus: value[12],
2359
2368
  eceStatus: value[13],
2360
2369
  pressureIssue: getPressureIssue(deviceId, value[13]),
2361
- ...getPressureAndTemperatureReadingObjects(value[9], value[10])
2370
+ ...getPressureAndTemperatureReadingObjects(value[9], value[10]),
2371
+ byteReading: value
2362
2372
  };
2363
2373
  }
2364
2374
  async function getVehicleReadings(deviceId, tcVehicle) {
@@ -2680,11 +2690,13 @@ const bridge = {
2680
2690
  await bridgeCommands.sendPinCommand(deviceId);
2681
2691
  store.setState(deviceId, "paired");
2682
2692
  },
2683
- async disconnect(deviceId) {
2693
+ async disconnect(deviceId, reason) {
2684
2694
  store.setState(deviceId, "disconnecting");
2685
2695
  promiseQueue$1.clearQueue("Previous pending commands aborted");
2686
2696
  await bluetooth.disconnect(deviceId);
2687
- store.setState(deviceId, "disconnected");
2697
+ delete store.devices[deviceId];
2698
+ deviceUnreachableCallback?.(deviceId);
2699
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2688
2700
  },
2689
2701
  getVehicle: bridgeService.getVehicle,
2690
2702
  setVehicle: bridgeService.setVehicle,
@@ -2820,10 +2832,10 @@ const flexiGaugeTpms = {
2820
2832
  );
2821
2833
  store.setState(deviceId, "paired");
2822
2834
  },
2823
- async disconnect(deviceId) {
2835
+ async disconnect(deviceId, reason) {
2824
2836
  store.setState(deviceId, "disconnecting");
2825
2837
  await bluetooth.disconnect(deviceId);
2826
- store.setState(deviceId, "disconnected");
2838
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2827
2839
  },
2828
2840
  onTreadDepth(callback) {
2829
2841
  flexiGaugeTpmsService.onTreadDepth(callback);
@@ -2894,7 +2906,7 @@ const bridgeSimulator = {
2894
2906
  async disconnect(deviceId) {
2895
2907
  store.deviceState[deviceId] = "disconnecting";
2896
2908
  await toolsSvc.delay(100);
2897
- store.deviceState[deviceId] = "disconnected";
2909
+ store.deviceState[deviceId] = void 0;
2898
2910
  },
2899
2911
  createSimulatedBridge(initialData) {
2900
2912
  return {
@@ -2921,7 +2933,8 @@ const bridgeSimulator = {
2921
2933
  sensorStatus: 0,
2922
2934
  pressure: { bar: 0, meas: 0, raw: 0 },
2923
2935
  pressureIssue: void 0,
2924
- temperature: { amb: 0, celsius: 0, raw: 0 }
2936
+ temperature: { amb: 0, celsius: 0, raw: 0 },
2937
+ byteReading: [0, 0, 0, 0, 0, 0, 0, 0]
2925
2938
  }
2926
2939
  },
2927
2940
  vehicle: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "SDK for working with various devices produced by Tirecheck via Bluetooth (CAN Bridge, Routers, Sensors, FlexiGauge, PressureStick, etc)",
5
5
  "author": "Leonid Buneev <leonid.buneev@tirecheck.com>",
6
6
  "license": "ISC",