@bota-dev/react-native-sdk 0.0.2
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/README.md +279 -0
- package/lib/commonjs/BotaClient.js +223 -0
- package/lib/commonjs/BotaClient.js.map +1 -0
- package/lib/commonjs/ble/BleManager.js +494 -0
- package/lib/commonjs/ble/BleManager.js.map +1 -0
- package/lib/commonjs/ble/constants.js +166 -0
- package/lib/commonjs/ble/constants.js.map +1 -0
- package/lib/commonjs/ble/index.js +54 -0
- package/lib/commonjs/ble/index.js.map +1 -0
- package/lib/commonjs/ble/parsers.js +345 -0
- package/lib/commonjs/ble/parsers.js.map +1 -0
- package/lib/commonjs/index.js +81 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/managers/DeviceManager.js +437 -0
- package/lib/commonjs/managers/DeviceManager.js.map +1 -0
- package/lib/commonjs/managers/OTAManager.js +227 -0
- package/lib/commonjs/managers/OTAManager.js.map +1 -0
- package/lib/commonjs/managers/RecordingManager.js +384 -0
- package/lib/commonjs/managers/RecordingManager.js.map +1 -0
- package/lib/commonjs/managers/index.js +27 -0
- package/lib/commonjs/managers/index.js.map +1 -0
- package/lib/commonjs/models/Device.js +2 -0
- package/lib/commonjs/models/Device.js.map +1 -0
- package/lib/commonjs/models/Recording.js +2 -0
- package/lib/commonjs/models/Recording.js.map +1 -0
- package/lib/commonjs/models/Status.js +6 -0
- package/lib/commonjs/models/Status.js.map +1 -0
- package/lib/commonjs/models/index.js +39 -0
- package/lib/commonjs/models/index.js.map +1 -0
- package/lib/commonjs/protocol/ProtocolHandler.js +343 -0
- package/lib/commonjs/protocol/ProtocolHandler.js.map +1 -0
- package/lib/commonjs/protocol/index.js +13 -0
- package/lib/commonjs/protocol/index.js.map +1 -0
- package/lib/commonjs/storage/StorageManager.js +333 -0
- package/lib/commonjs/storage/StorageManager.js.map +1 -0
- package/lib/commonjs/storage/index.js +19 -0
- package/lib/commonjs/storage/index.js.map +1 -0
- package/lib/commonjs/upload/S3Uploader.js +133 -0
- package/lib/commonjs/upload/S3Uploader.js.map +1 -0
- package/lib/commonjs/upload/UploadQueue.js +280 -0
- package/lib/commonjs/upload/UploadQueue.js.map +1 -0
- package/lib/commonjs/upload/index.js +20 -0
- package/lib/commonjs/upload/index.js.map +1 -0
- package/lib/commonjs/utils/errors.js +187 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/index.js +40 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/logger.js +135 -0
- package/lib/commonjs/utils/logger.js.map +1 -0
- package/lib/commonjs/utils/retry.js +160 -0
- package/lib/commonjs/utils/retry.js.map +1 -0
- package/lib/module/BotaClient.js +216 -0
- package/lib/module/BotaClient.js.map +1 -0
- package/lib/module/ble/BleManager.js +484 -0
- package/lib/module/ble/BleManager.js.map +1 -0
- package/lib/module/ble/constants.js +159 -0
- package/lib/module/ble/constants.js.map +1 -0
- package/lib/module/ble/index.js +8 -0
- package/lib/module/ble/index.js.map +1 -0
- package/lib/module/ble/parsers.js +328 -0
- package/lib/module/ble/parsers.js.map +1 -0
- package/lib/module/index.js +22 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/managers/DeviceManager.js +429 -0
- package/lib/module/managers/DeviceManager.js.map +1 -0
- package/lib/module/managers/OTAManager.js +219 -0
- package/lib/module/managers/OTAManager.js.map +1 -0
- package/lib/module/managers/RecordingManager.js +376 -0
- package/lib/module/managers/RecordingManager.js.map +1 -0
- package/lib/module/managers/index.js +8 -0
- package/lib/module/managers/index.js.map +1 -0
- package/lib/module/models/Device.js +2 -0
- package/lib/module/models/Device.js.map +1 -0
- package/lib/module/models/Recording.js +2 -0
- package/lib/module/models/Recording.js.map +1 -0
- package/lib/module/models/Status.js +2 -0
- package/lib/module/models/Status.js.map +1 -0
- package/lib/module/models/index.js +8 -0
- package/lib/module/models/index.js.map +1 -0
- package/lib/module/protocol/ProtocolHandler.js +336 -0
- package/lib/module/protocol/ProtocolHandler.js.map +1 -0
- package/lib/module/protocol/index.js +6 -0
- package/lib/module/protocol/index.js.map +1 -0
- package/lib/module/storage/StorageManager.js +324 -0
- package/lib/module/storage/StorageManager.js.map +1 -0
- package/lib/module/storage/index.js +6 -0
- package/lib/module/storage/index.js.map +1 -0
- package/lib/module/upload/S3Uploader.js +126 -0
- package/lib/module/upload/S3Uploader.js.map +1 -0
- package/lib/module/upload/UploadQueue.js +272 -0
- package/lib/module/upload/UploadQueue.js.map +1 -0
- package/lib/module/upload/index.js +7 -0
- package/lib/module/upload/index.js.map +1 -0
- package/lib/module/utils/errors.js +173 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/index.js +8 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/logger.js +129 -0
- package/lib/module/utils/logger.js.map +1 -0
- package/lib/module/utils/retry.js +149 -0
- package/lib/module/utils/retry.js.map +1 -0
- package/lib/typescript/src/BotaClient.d.ts +77 -0
- package/lib/typescript/src/BotaClient.d.ts.map +1 -0
- package/lib/typescript/src/ble/BleManager.d.ts +111 -0
- package/lib/typescript/src/ble/BleManager.d.ts.map +1 -0
- package/lib/typescript/src/ble/constants.d.ts +111 -0
- package/lib/typescript/src/ble/constants.d.ts.map +1 -0
- package/lib/typescript/src/ble/index.d.ts +7 -0
- package/lib/typescript/src/ble/index.d.ts.map +1 -0
- package/lib/typescript/src/ble/parsers.d.ts +100 -0
- package/lib/typescript/src/ble/parsers.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/managers/DeviceManager.d.ts +84 -0
- package/lib/typescript/src/managers/DeviceManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/OTAManager.d.ts +78 -0
- package/lib/typescript/src/managers/OTAManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/RecordingManager.d.ts +90 -0
- package/lib/typescript/src/managers/RecordingManager.d.ts.map +1 -0
- package/lib/typescript/src/managers/index.d.ts +7 -0
- package/lib/typescript/src/managers/index.d.ts.map +1 -0
- package/lib/typescript/src/models/Device.d.ts +139 -0
- package/lib/typescript/src/models/Device.d.ts.map +1 -0
- package/lib/typescript/src/models/Recording.d.ts +110 -0
- package/lib/typescript/src/models/Recording.d.ts.map +1 -0
- package/lib/typescript/src/models/Status.d.ts +104 -0
- package/lib/typescript/src/models/Status.d.ts.map +1 -0
- package/lib/typescript/src/models/index.d.ts +7 -0
- package/lib/typescript/src/models/index.d.ts.map +1 -0
- package/lib/typescript/src/protocol/ProtocolHandler.d.ts +69 -0
- package/lib/typescript/src/protocol/ProtocolHandler.d.ts.map +1 -0
- package/lib/typescript/src/protocol/index.d.ts +5 -0
- package/lib/typescript/src/protocol/index.d.ts.map +1 -0
- package/lib/typescript/src/storage/StorageManager.d.ts +116 -0
- package/lib/typescript/src/storage/StorageManager.d.ts.map +1 -0
- package/lib/typescript/src/storage/index.d.ts +5 -0
- package/lib/typescript/src/storage/index.d.ts.map +1 -0
- package/lib/typescript/src/upload/S3Uploader.d.ts +38 -0
- package/lib/typescript/src/upload/S3Uploader.d.ts.map +1 -0
- package/lib/typescript/src/upload/UploadQueue.d.ts +95 -0
- package/lib/typescript/src/upload/UploadQueue.d.ts.map +1 -0
- package/lib/typescript/src/upload/index.d.ts +6 -0
- package/lib/typescript/src/upload/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/errors.d.ts +82 -0
- package/lib/typescript/src/utils/errors.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +7 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/logger.d.ts +68 -0
- package/lib/typescript/src/utils/logger.d.ts.map +1 -0
- package/lib/typescript/src/utils/retry.d.ts +53 -0
- package/lib/typescript/src/utils/retry.d.ts.map +1 -0
- package/package.json +95 -0
- package/src/BotaClient.ts +238 -0
- package/src/ble/BleManager.ts +573 -0
- package/src/ble/constants.ts +158 -0
- package/src/ble/index.ts +7 -0
- package/src/ble/parsers.ts +395 -0
- package/src/index.ts +64 -0
- package/src/managers/DeviceManager.ts +545 -0
- package/src/managers/OTAManager.ts +263 -0
- package/src/managers/RecordingManager.ts +434 -0
- package/src/managers/index.ts +12 -0
- package/src/models/Device.ts +164 -0
- package/src/models/Recording.ts +123 -0
- package/src/models/Status.ts +126 -0
- package/src/models/index.ts +7 -0
- package/src/protocol/ProtocolHandler.ts +459 -0
- package/src/protocol/index.ts +5 -0
- package/src/storage/StorageManager.ts +343 -0
- package/src/storage/index.ts +5 -0
- package/src/upload/S3Uploader.ts +164 -0
- package/src/upload/UploadQueue.ts +310 -0
- package/src/upload/index.ts +6 -0
- package/src/utils/errors.ts +310 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/logger.ts +137 -0
- package/src/utils/retry.ts +177 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device Manager - Handles device discovery, connection, and provisioning
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Buffer } from 'buffer';
|
|
6
|
+
import EventEmitter from 'eventemitter3';
|
|
7
|
+
import { getBleManager } from '../ble/BleManager';
|
|
8
|
+
import { SERVICE_DEVICE_INFO, SERVICE_BOTA_PROVISIONING, SERVICE_BOTA_CONTROL, CHAR_SERIAL_NUMBER, CHAR_FIRMWARE_REVISION, CHAR_HARDWARE_REVISION, CHAR_PAIRING_STATE, CHAR_DEVICE_TOKEN, CHAR_API_ENDPOINT, CHAR_PROVISIONING_RESULT, CHAR_DEVICE_STATUS, CHAR_TIME_SYNC, API_ENDPOINT_PRODUCTION, API_ENDPOINT_SANDBOX, PROVISIONING_SUCCESS, PROVISIONING_INVALID_TOKEN, PROVISIONING_STORAGE_ERROR, PROVISIONING_CHUNK_ERROR, OPERATION_TIMEOUT } from '../ble/constants';
|
|
9
|
+
import { parsePairingState, parseDeviceStatus, createTimeSyncData } from '../ble/parsers';
|
|
10
|
+
import { DeviceError, ProvisioningError } from '../utils/errors';
|
|
11
|
+
import { logger } from '../utils/logger';
|
|
12
|
+
const log = logger.tag('DeviceManager');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Device Manager class
|
|
16
|
+
*/
|
|
17
|
+
export class DeviceManager extends EventEmitter {
|
|
18
|
+
connectedDevices = new Map();
|
|
19
|
+
statusSubscriptions = new Map();
|
|
20
|
+
isInitialized = false;
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.bleManager = getBleManager();
|
|
24
|
+
this.setupBleListeners();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Initialize the device manager
|
|
29
|
+
*/
|
|
30
|
+
initialize() {
|
|
31
|
+
if (this.isInitialized) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.isInitialized = true;
|
|
35
|
+
log.info('DeviceManager initialized');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Set up BLE event listeners
|
|
40
|
+
*/
|
|
41
|
+
setupBleListeners() {
|
|
42
|
+
this.bleManager.on('deviceDiscovered', device => {
|
|
43
|
+
this.emit('deviceDiscovered', device);
|
|
44
|
+
});
|
|
45
|
+
this.bleManager.on('deviceConnected', deviceId => {
|
|
46
|
+
const device = this.connectedDevices.get(deviceId);
|
|
47
|
+
if (device) {
|
|
48
|
+
this.emit('deviceConnected', device);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
this.bleManager.on('deviceDisconnected', (deviceId, error) => {
|
|
52
|
+
const device = this.connectedDevices.get(deviceId);
|
|
53
|
+
if (device) {
|
|
54
|
+
// Update connection state
|
|
55
|
+
device.connectionState = 'disconnected';
|
|
56
|
+
}
|
|
57
|
+
this.connectedDevices.delete(deviceId);
|
|
58
|
+
|
|
59
|
+
// Clean up status subscription
|
|
60
|
+
this.statusSubscriptions.get(deviceId)?.remove();
|
|
61
|
+
this.statusSubscriptions.delete(deviceId);
|
|
62
|
+
this.emit('deviceDisconnected', deviceId, error);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Start scanning for Bota devices
|
|
68
|
+
*/
|
|
69
|
+
async startScan(options = {}) {
|
|
70
|
+
log.info('Starting device scan', options);
|
|
71
|
+
this.emit('scanStarted');
|
|
72
|
+
try {
|
|
73
|
+
await this.bleManager.startScan(options);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.emit('scanError', error);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Stop scanning for devices
|
|
82
|
+
*/
|
|
83
|
+
stopScan() {
|
|
84
|
+
log.info('Stopping device scan');
|
|
85
|
+
this.bleManager.stopScan();
|
|
86
|
+
this.emit('scanStopped');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get list of discovered devices
|
|
91
|
+
*/
|
|
92
|
+
getDiscoveredDevices() {
|
|
93
|
+
return this.bleManager.getDiscoveredDevices();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get list of connected devices
|
|
98
|
+
*/
|
|
99
|
+
getConnectedDevices() {
|
|
100
|
+
return Array.from(this.connectedDevices.values());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Connect to a discovered device
|
|
105
|
+
*/
|
|
106
|
+
async connect(device) {
|
|
107
|
+
log.info('Connecting to device', {
|
|
108
|
+
deviceId: device.id,
|
|
109
|
+
name: device.name
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Check if already connected
|
|
113
|
+
const existing = this.connectedDevices.get(device.id);
|
|
114
|
+
if (existing && existing.connectionState === 'connected') {
|
|
115
|
+
log.debug('Device already connected', {
|
|
116
|
+
deviceId: device.id
|
|
117
|
+
});
|
|
118
|
+
return existing;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Emit connecting state
|
|
122
|
+
this.emit('connectionStateChanged', device.id, 'connecting');
|
|
123
|
+
try {
|
|
124
|
+
// Connect via BLE manager
|
|
125
|
+
await this.bleManager.connect(device.id);
|
|
126
|
+
|
|
127
|
+
// Read device information
|
|
128
|
+
const serialNumber = await this.readSerialNumber(device.id);
|
|
129
|
+
const firmwareVersion = await this.readFirmwareVersion(device.id);
|
|
130
|
+
const hardwareRevision = await this.readHardwareRevision(device.id);
|
|
131
|
+
const pairingState = await this.readPairingState(device.id);
|
|
132
|
+
const mtu = await this.bleManager.getMtu(device.id);
|
|
133
|
+
const connectedDevice = {
|
|
134
|
+
id: device.id,
|
|
135
|
+
serialNumber,
|
|
136
|
+
deviceType: device.deviceType,
|
|
137
|
+
firmwareVersion,
|
|
138
|
+
hardwareRevision,
|
|
139
|
+
isProvisioned: pairingState === 'paired',
|
|
140
|
+
connectionState: 'connected',
|
|
141
|
+
mtu
|
|
142
|
+
};
|
|
143
|
+
this.connectedDevices.set(device.id, connectedDevice);
|
|
144
|
+
log.info('Device connected successfully', {
|
|
145
|
+
deviceId: device.id,
|
|
146
|
+
serialNumber,
|
|
147
|
+
isProvisioned: connectedDevice.isProvisioned
|
|
148
|
+
});
|
|
149
|
+
this.emit('connectionStateChanged', device.id, 'connected');
|
|
150
|
+
return connectedDevice;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
this.emit('connectionStateChanged', device.id, 'disconnected');
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Disconnect from a device
|
|
159
|
+
*/
|
|
160
|
+
async disconnect(device) {
|
|
161
|
+
log.info('Disconnecting from device', {
|
|
162
|
+
deviceId: device.id
|
|
163
|
+
});
|
|
164
|
+
this.emit('connectionStateChanged', device.id, 'disconnecting');
|
|
165
|
+
|
|
166
|
+
// Clean up status subscription
|
|
167
|
+
this.statusSubscriptions.get(device.id)?.remove();
|
|
168
|
+
this.statusSubscriptions.delete(device.id);
|
|
169
|
+
await this.bleManager.disconnect(device.id);
|
|
170
|
+
this.connectedDevices.delete(device.id);
|
|
171
|
+
this.emit('connectionStateChanged', device.id, 'disconnected');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Check if a device is connected
|
|
176
|
+
*/
|
|
177
|
+
isConnected(deviceId) {
|
|
178
|
+
return this.bleManager.isConnected(deviceId);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Provision a device with a token
|
|
183
|
+
*/
|
|
184
|
+
async provision(device, deviceToken, environment = 'production') {
|
|
185
|
+
log.info('Provisioning device', {
|
|
186
|
+
deviceId: device.id,
|
|
187
|
+
environment
|
|
188
|
+
});
|
|
189
|
+
if (!this.isConnected(device.id)) {
|
|
190
|
+
throw DeviceError.notConnected(device.id);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Check current pairing state
|
|
194
|
+
const pairingState = await this.readPairingState(device.id);
|
|
195
|
+
if (pairingState === 'paired') {
|
|
196
|
+
log.warn('Device is already provisioned', {
|
|
197
|
+
deviceId: device.id
|
|
198
|
+
});
|
|
199
|
+
throw ProvisioningError.alreadyProvisioned(device.id);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Set up provisioning result listener
|
|
203
|
+
const resultPromise = this.waitForProvisioningResult(device.id);
|
|
204
|
+
try {
|
|
205
|
+
// Write API endpoint
|
|
206
|
+
await this.writeApiEndpoint(device.id, environment);
|
|
207
|
+
|
|
208
|
+
// Write device token (chunked)
|
|
209
|
+
await this.writeDeviceToken(device.id, deviceToken);
|
|
210
|
+
|
|
211
|
+
// Wait for provisioning result
|
|
212
|
+
const result = await resultPromise;
|
|
213
|
+
if (!result.success) {
|
|
214
|
+
switch (result.error) {
|
|
215
|
+
case 'invalid_token':
|
|
216
|
+
throw ProvisioningError.invalidToken(device.id);
|
|
217
|
+
case 'storage_error':
|
|
218
|
+
throw ProvisioningError.storageError(device.id);
|
|
219
|
+
case 'chunk_error':
|
|
220
|
+
throw ProvisioningError.chunkError(device.id);
|
|
221
|
+
default:
|
|
222
|
+
throw new ProvisioningError('Provisioning failed', 'PROVISIONING_FAILED', device.id);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Sync time to device
|
|
227
|
+
await this.syncTime(device.id);
|
|
228
|
+
|
|
229
|
+
// Update device state
|
|
230
|
+
device.isProvisioned = true;
|
|
231
|
+
log.info('Device provisioned successfully', {
|
|
232
|
+
deviceId: device.id
|
|
233
|
+
});
|
|
234
|
+
} catch (error) {
|
|
235
|
+
log.error('Provisioning failed', error, {
|
|
236
|
+
deviceId: device.id
|
|
237
|
+
});
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if a device is provisioned
|
|
244
|
+
*/
|
|
245
|
+
async isProvisioned(device) {
|
|
246
|
+
const pairingState = await this.readPairingState(device.id);
|
|
247
|
+
return pairingState === 'paired';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get device status
|
|
252
|
+
*/
|
|
253
|
+
async getStatus(device) {
|
|
254
|
+
if (!this.isConnected(device.id)) {
|
|
255
|
+
throw DeviceError.notConnected(device.id);
|
|
256
|
+
}
|
|
257
|
+
const data = await this.bleManager.readCharacteristic(device.id, SERVICE_BOTA_CONTROL, CHAR_DEVICE_STATUS);
|
|
258
|
+
return parseDeviceStatus(data);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Subscribe to device status updates
|
|
263
|
+
*/
|
|
264
|
+
subscribeToStatus(device, callback) {
|
|
265
|
+
if (!this.isConnected(device.id)) {
|
|
266
|
+
throw DeviceError.notConnected(device.id);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Remove existing subscription
|
|
270
|
+
this.statusSubscriptions.get(device.id)?.remove();
|
|
271
|
+
const subscription = this.bleManager.subscribeToCharacteristic(device.id, SERVICE_BOTA_CONTROL, CHAR_DEVICE_STATUS, data => {
|
|
272
|
+
try {
|
|
273
|
+
const status = parseDeviceStatus(data);
|
|
274
|
+
this.emit('deviceStatusUpdated', device.id, status);
|
|
275
|
+
callback(status);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
log.error('Failed to parse status update', error);
|
|
278
|
+
}
|
|
279
|
+
}, error => {
|
|
280
|
+
log.error('Status subscription error', error);
|
|
281
|
+
});
|
|
282
|
+
this.statusSubscriptions.set(device.id, subscription);
|
|
283
|
+
return () => {
|
|
284
|
+
subscription.remove();
|
|
285
|
+
this.statusSubscriptions.delete(device.id);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Sync time to device
|
|
291
|
+
*/
|
|
292
|
+
async syncTime(deviceId) {
|
|
293
|
+
log.debug('Syncing time to device', {
|
|
294
|
+
deviceId
|
|
295
|
+
});
|
|
296
|
+
const timeSyncData = createTimeSyncData();
|
|
297
|
+
await this.bleManager.writeCharacteristic(deviceId, SERVICE_BOTA_CONTROL, CHAR_TIME_SYNC, timeSyncData);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Private helper methods
|
|
301
|
+
|
|
302
|
+
async readSerialNumber(deviceId) {
|
|
303
|
+
const data = await this.bleManager.readCharacteristic(deviceId, SERVICE_DEVICE_INFO, CHAR_SERIAL_NUMBER);
|
|
304
|
+
return data.toString('utf8').replace(/\0/g, '');
|
|
305
|
+
}
|
|
306
|
+
async readFirmwareVersion(deviceId) {
|
|
307
|
+
const data = await this.bleManager.readCharacteristic(deviceId, SERVICE_DEVICE_INFO, CHAR_FIRMWARE_REVISION);
|
|
308
|
+
return data.toString('utf8').replace(/\0/g, '');
|
|
309
|
+
}
|
|
310
|
+
async readHardwareRevision(deviceId) {
|
|
311
|
+
try {
|
|
312
|
+
const data = await this.bleManager.readCharacteristic(deviceId, SERVICE_DEVICE_INFO, CHAR_HARDWARE_REVISION);
|
|
313
|
+
return data.toString('utf8').replace(/\0/g, '');
|
|
314
|
+
} catch {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async readPairingState(deviceId) {
|
|
319
|
+
const data = await this.bleManager.readCharacteristic(deviceId, SERVICE_BOTA_PROVISIONING, CHAR_PAIRING_STATE);
|
|
320
|
+
if (data.length < 1) {
|
|
321
|
+
return 'unpaired';
|
|
322
|
+
}
|
|
323
|
+
return parsePairingState(data[0]);
|
|
324
|
+
}
|
|
325
|
+
async writeApiEndpoint(deviceId, environment) {
|
|
326
|
+
const endpointByte = environment === 'production' ? API_ENDPOINT_PRODUCTION : API_ENDPOINT_SANDBOX;
|
|
327
|
+
await this.bleManager.writeCharacteristic(deviceId, SERVICE_BOTA_PROVISIONING, CHAR_API_ENDPOINT, Buffer.from([endpointByte]));
|
|
328
|
+
}
|
|
329
|
+
async writeDeviceToken(deviceId, token) {
|
|
330
|
+
const mtu = await this.bleManager.getMtu(deviceId);
|
|
331
|
+
const maxChunkSize = mtu - 5; // Account for BLE overhead + chunk header
|
|
332
|
+
|
|
333
|
+
const tokenBuffer = Buffer.from(token, 'utf8');
|
|
334
|
+
const totalChunks = Math.ceil(tokenBuffer.length / (maxChunkSize - 2));
|
|
335
|
+
log.debug('Writing device token', {
|
|
336
|
+
deviceId,
|
|
337
|
+
tokenLength: token.length,
|
|
338
|
+
totalChunks,
|
|
339
|
+
mtu
|
|
340
|
+
});
|
|
341
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
342
|
+
const start = i * (maxChunkSize - 2);
|
|
343
|
+
const end = Math.min(start + (maxChunkSize - 2), tokenBuffer.length);
|
|
344
|
+
const chunkData = tokenBuffer.slice(start, end);
|
|
345
|
+
|
|
346
|
+
// Create chunk with header: [chunk_index, total_chunks, ...data]
|
|
347
|
+
const chunk = Buffer.alloc(2 + chunkData.length);
|
|
348
|
+
chunk.writeUInt8(i, 0);
|
|
349
|
+
chunk.writeUInt8(totalChunks, 1);
|
|
350
|
+
chunkData.copy(chunk, 2);
|
|
351
|
+
await this.bleManager.writeCharacteristic(deviceId, SERVICE_BOTA_PROVISIONING, CHAR_DEVICE_TOKEN, chunk);
|
|
352
|
+
log.debug('Wrote token chunk', {
|
|
353
|
+
chunk: i + 1,
|
|
354
|
+
total: totalChunks
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
waitForProvisioningResult(deviceId) {
|
|
359
|
+
return new Promise((resolve, reject) => {
|
|
360
|
+
const timeout = setTimeout(() => {
|
|
361
|
+
subscription.remove();
|
|
362
|
+
reject(ProvisioningError.timeout(deviceId));
|
|
363
|
+
}, OPERATION_TIMEOUT);
|
|
364
|
+
const subscription = this.bleManager.subscribeToCharacteristic(deviceId, SERVICE_BOTA_PROVISIONING, CHAR_PROVISIONING_RESULT, data => {
|
|
365
|
+
clearTimeout(timeout);
|
|
366
|
+
subscription.remove();
|
|
367
|
+
if (data.length < 1) {
|
|
368
|
+
resolve({
|
|
369
|
+
success: false,
|
|
370
|
+
error: 'unknown'
|
|
371
|
+
});
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const resultCode = data[0];
|
|
375
|
+
switch (resultCode) {
|
|
376
|
+
case PROVISIONING_SUCCESS:
|
|
377
|
+
resolve({
|
|
378
|
+
success: true
|
|
379
|
+
});
|
|
380
|
+
break;
|
|
381
|
+
case PROVISIONING_INVALID_TOKEN:
|
|
382
|
+
resolve({
|
|
383
|
+
success: false,
|
|
384
|
+
error: 'invalid_token'
|
|
385
|
+
});
|
|
386
|
+
break;
|
|
387
|
+
case PROVISIONING_STORAGE_ERROR:
|
|
388
|
+
resolve({
|
|
389
|
+
success: false,
|
|
390
|
+
error: 'storage_error'
|
|
391
|
+
});
|
|
392
|
+
break;
|
|
393
|
+
case PROVISIONING_CHUNK_ERROR:
|
|
394
|
+
resolve({
|
|
395
|
+
success: false,
|
|
396
|
+
error: 'chunk_error'
|
|
397
|
+
});
|
|
398
|
+
break;
|
|
399
|
+
default:
|
|
400
|
+
resolve({
|
|
401
|
+
success: false,
|
|
402
|
+
error: 'unknown'
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
}, error => {
|
|
406
|
+
clearTimeout(timeout);
|
|
407
|
+
subscription.remove();
|
|
408
|
+
reject(new ProvisioningError(`Provisioning notification error: ${error.message}`, 'NOTIFICATION_ERROR', deviceId, error));
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Clean up resources
|
|
415
|
+
*/
|
|
416
|
+
destroy() {
|
|
417
|
+
log.info('Destroying DeviceManager');
|
|
418
|
+
|
|
419
|
+
// Clean up all status subscriptions
|
|
420
|
+
for (const sub of this.statusSubscriptions.values()) {
|
|
421
|
+
sub.remove();
|
|
422
|
+
}
|
|
423
|
+
this.statusSubscriptions.clear();
|
|
424
|
+
this.connectedDevices.clear();
|
|
425
|
+
this.removeAllListeners();
|
|
426
|
+
this.isInitialized = false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=DeviceManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Buffer","EventEmitter","getBleManager","SERVICE_DEVICE_INFO","SERVICE_BOTA_PROVISIONING","SERVICE_BOTA_CONTROL","CHAR_SERIAL_NUMBER","CHAR_FIRMWARE_REVISION","CHAR_HARDWARE_REVISION","CHAR_PAIRING_STATE","CHAR_DEVICE_TOKEN","CHAR_API_ENDPOINT","CHAR_PROVISIONING_RESULT","CHAR_DEVICE_STATUS","CHAR_TIME_SYNC","API_ENDPOINT_PRODUCTION","API_ENDPOINT_SANDBOX","PROVISIONING_SUCCESS","PROVISIONING_INVALID_TOKEN","PROVISIONING_STORAGE_ERROR","PROVISIONING_CHUNK_ERROR","OPERATION_TIMEOUT","parsePairingState","parseDeviceStatus","createTimeSyncData","DeviceError","ProvisioningError","logger","log","tag","DeviceManager","connectedDevices","Map","statusSubscriptions","isInitialized","constructor","bleManager","setupBleListeners","initialize","info","on","device","emit","deviceId","get","error","connectionState","delete","remove","startScan","options","stopScan","getDiscoveredDevices","getConnectedDevices","Array","from","values","connect","id","name","existing","debug","serialNumber","readSerialNumber","firmwareVersion","readFirmwareVersion","hardwareRevision","readHardwareRevision","pairingState","readPairingState","mtu","getMtu","connectedDevice","deviceType","isProvisioned","set","disconnect","isConnected","provision","deviceToken","environment","notConnected","warn","alreadyProvisioned","resultPromise","waitForProvisioningResult","writeApiEndpoint","writeDeviceToken","result","success","invalidToken","storageError","chunkError","syncTime","getStatus","data","readCharacteristic","subscribeToStatus","callback","subscription","subscribeToCharacteristic","status","timeSyncData","writeCharacteristic","toString","replace","undefined","length","endpointByte","token","maxChunkSize","tokenBuffer","totalChunks","Math","ceil","tokenLength","i","start","end","min","chunkData","slice","chunk","alloc","writeUInt8","copy","total","Promise","resolve","reject","timeout","setTimeout","clearTimeout","resultCode","message","destroy","sub","clear","removeAllListeners"],"sourceRoot":"../../../src","sources":["managers/DeviceManager.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTA Manager - Handles firmware over-the-air updates
|
|
3
|
+
*
|
|
4
|
+
* Note: Full Nordic DFU implementation requires native modules.
|
|
5
|
+
* This is a placeholder that handles version checking and update preparation.
|
|
6
|
+
* Actual DFU transfer would need react-native-nordic-dfu or similar.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import EventEmitter from 'eventemitter3';
|
|
10
|
+
import { getBleManager } from '../ble/BleManager';
|
|
11
|
+
import { SERVICE_BOTA_CONTROL, CHAR_DEVICE_COMMAND, DEVICE_CMD_ENTER_DFU } from '../ble/constants';
|
|
12
|
+
import { DeviceError } from '../utils/errors';
|
|
13
|
+
import { logger } from '../utils/logger';
|
|
14
|
+
import { Buffer } from 'buffer';
|
|
15
|
+
const log = logger.tag('OTAManager');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Firmware info
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* OTA progress stages
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* OTA progress
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Events emitted by OTAManager
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* OTA Manager class
|
|
35
|
+
*/
|
|
36
|
+
export class OTAManager extends EventEmitter {
|
|
37
|
+
constructor(firmwareCdnUrl = 'https://cdn.bota.dev/firmware') {
|
|
38
|
+
super();
|
|
39
|
+
this.firmwareCdnUrl = firmwareCdnUrl;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check for available firmware updates
|
|
44
|
+
*/
|
|
45
|
+
async checkForUpdate(device) {
|
|
46
|
+
log.info('Checking for firmware update', {
|
|
47
|
+
deviceId: device.id,
|
|
48
|
+
currentVersion: device.firmwareVersion,
|
|
49
|
+
deviceType: device.deviceType
|
|
50
|
+
});
|
|
51
|
+
this.emit('progress', device.id, {
|
|
52
|
+
stage: 'checking',
|
|
53
|
+
progress: 0
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
// Fetch latest firmware info from CDN
|
|
57
|
+
const response = await fetch(`${this.firmwareCdnUrl}/latest?device_type=${device.deviceType}¤t=${device.firmwareVersion}`);
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
if (response.status === 404) {
|
|
60
|
+
log.info('No update available', {
|
|
61
|
+
deviceId: device.id
|
|
62
|
+
});
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Failed to check for updates: ${response.status}`);
|
|
66
|
+
}
|
|
67
|
+
const firmware = await response.json();
|
|
68
|
+
|
|
69
|
+
// Compare versions
|
|
70
|
+
if (this.isNewerVersion(firmware.version, device.firmwareVersion)) {
|
|
71
|
+
log.info('Update available', {
|
|
72
|
+
deviceId: device.id,
|
|
73
|
+
currentVersion: device.firmwareVersion,
|
|
74
|
+
newVersion: firmware.version
|
|
75
|
+
});
|
|
76
|
+
this.emit('updateAvailable', firmware);
|
|
77
|
+
return firmware;
|
|
78
|
+
}
|
|
79
|
+
log.info('Device is up to date', {
|
|
80
|
+
deviceId: device.id,
|
|
81
|
+
version: device.firmwareVersion
|
|
82
|
+
});
|
|
83
|
+
return null;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
log.error('Failed to check for update', error, {
|
|
86
|
+
deviceId: device.id
|
|
87
|
+
});
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Download firmware package
|
|
94
|
+
*/
|
|
95
|
+
async downloadFirmware(firmware) {
|
|
96
|
+
log.info('Downloading firmware', {
|
|
97
|
+
version: firmware.version,
|
|
98
|
+
size: firmware.size
|
|
99
|
+
});
|
|
100
|
+
const response = await fetch(firmware.url);
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
throw new Error(`Failed to download firmware: ${response.status}`);
|
|
103
|
+
}
|
|
104
|
+
const data = await response.arrayBuffer();
|
|
105
|
+
|
|
106
|
+
// Verify checksum
|
|
107
|
+
// Note: In production, implement proper checksum verification
|
|
108
|
+
log.info('Firmware downloaded', {
|
|
109
|
+
size: data.byteLength
|
|
110
|
+
});
|
|
111
|
+
return data;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Prepare device for DFU mode
|
|
116
|
+
*/
|
|
117
|
+
async enterDfuMode(device) {
|
|
118
|
+
if (!getBleManager().isConnected(device.id)) {
|
|
119
|
+
throw DeviceError.notConnected(device.id);
|
|
120
|
+
}
|
|
121
|
+
log.info('Entering DFU mode', {
|
|
122
|
+
deviceId: device.id
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Send DFU command to device
|
|
126
|
+
await getBleManager().writeCharacteristic(device.id, SERVICE_BOTA_CONTROL, CHAR_DEVICE_COMMAND, Buffer.from([DEVICE_CMD_ENTER_DFU]));
|
|
127
|
+
|
|
128
|
+
// Device will disconnect and reboot into DFU mode
|
|
129
|
+
log.info('DFU command sent, device will reboot', {
|
|
130
|
+
deviceId: device.id
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Perform firmware update
|
|
136
|
+
*
|
|
137
|
+
* Note: This is a placeholder. Full implementation requires:
|
|
138
|
+
* 1. react-native-nordic-dfu for actual DFU transfer
|
|
139
|
+
* 2. Native module integration
|
|
140
|
+
* 3. DFU package preparation
|
|
141
|
+
*/
|
|
142
|
+
async performUpdate(device, firmware) {
|
|
143
|
+
log.info('Starting firmware update', {
|
|
144
|
+
deviceId: device.id,
|
|
145
|
+
version: firmware.version
|
|
146
|
+
});
|
|
147
|
+
this.emit('progress', device.id, {
|
|
148
|
+
stage: 'downloading',
|
|
149
|
+
progress: 0
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
// Download firmware
|
|
153
|
+
await this.downloadFirmware(firmware);
|
|
154
|
+
this.emit('progress', device.id, {
|
|
155
|
+
stage: 'downloading',
|
|
156
|
+
progress: 1
|
|
157
|
+
});
|
|
158
|
+
this.emit('progress', device.id, {
|
|
159
|
+
stage: 'preparing',
|
|
160
|
+
progress: 0
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Enter DFU mode
|
|
164
|
+
await this.enterDfuMode(device);
|
|
165
|
+
this.emit('progress', device.id, {
|
|
166
|
+
stage: 'preparing',
|
|
167
|
+
progress: 1
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Note: At this point, we would use react-native-nordic-dfu
|
|
171
|
+
// to perform the actual firmware transfer.
|
|
172
|
+
// For now, we throw an error indicating this needs native implementation.
|
|
173
|
+
|
|
174
|
+
throw new Error('Full DFU implementation requires react-native-nordic-dfu native module. ' + 'Device has entered DFU mode and is advertising as "BotaDFU-xxx".');
|
|
175
|
+
|
|
176
|
+
// After DFU completes:
|
|
177
|
+
// this.emit('progress', device.id, { stage: 'completed', progress: 1 });
|
|
178
|
+
// this.emit('completed', device.id, firmware.version);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
const err = error;
|
|
181
|
+
log.error('Firmware update failed', err, {
|
|
182
|
+
deviceId: device.id
|
|
183
|
+
});
|
|
184
|
+
this.emit('progress', device.id, {
|
|
185
|
+
stage: 'failed',
|
|
186
|
+
progress: 0,
|
|
187
|
+
error: err.message
|
|
188
|
+
});
|
|
189
|
+
this.emit('failed', device.id, err);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Compare semantic versions
|
|
196
|
+
*/
|
|
197
|
+
isNewerVersion(newVersion, currentVersion) {
|
|
198
|
+
const parseVersion = v => {
|
|
199
|
+
return v.split('.').map(n => parseInt(n, 10) || 0);
|
|
200
|
+
};
|
|
201
|
+
const newParts = parseVersion(newVersion);
|
|
202
|
+
const currentParts = parseVersion(currentVersion);
|
|
203
|
+
for (let i = 0; i < Math.max(newParts.length, currentParts.length); i++) {
|
|
204
|
+
const newPart = newParts[i] || 0;
|
|
205
|
+
const currentPart = currentParts[i] || 0;
|
|
206
|
+
if (newPart > currentPart) return true;
|
|
207
|
+
if (newPart < currentPart) return false;
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Clean up resources
|
|
214
|
+
*/
|
|
215
|
+
destroy() {
|
|
216
|
+
this.removeAllListeners();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=OTAManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["EventEmitter","getBleManager","SERVICE_BOTA_CONTROL","CHAR_DEVICE_COMMAND","DEVICE_CMD_ENTER_DFU","DeviceError","logger","Buffer","log","tag","OTAManager","constructor","firmwareCdnUrl","checkForUpdate","device","info","deviceId","id","currentVersion","firmwareVersion","deviceType","emit","stage","progress","response","fetch","ok","status","Error","firmware","json","isNewerVersion","version","newVersion","error","downloadFirmware","size","url","data","arrayBuffer","byteLength","enterDfuMode","isConnected","notConnected","writeCharacteristic","from","performUpdate","err","message","parseVersion","v","split","map","n","parseInt","newParts","currentParts","i","Math","max","length","newPart","currentPart","destroy","removeAllListeners"],"sourceRoot":"../../../src","sources":["managers/OTAManager.ts"],"mappings":"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","ignoreList":[]}
|