@bota-dev/react-native-sdk 0.0.7 → 0.0.8
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 +30 -2
- package/lib/commonjs/ble/constants.js +28 -2
- package/lib/commonjs/ble/constants.js.map +1 -1
- package/lib/commonjs/ble/parsers.js +128 -0
- package/lib/commonjs/ble/parsers.js.map +1 -1
- package/lib/commonjs/managers/DeviceManager.js +179 -0
- package/lib/commonjs/managers/DeviceManager.js.map +1 -1
- package/lib/commonjs/utils/crypto.js +169 -0
- package/lib/commonjs/utils/crypto.js.map +1 -0
- package/lib/commonjs/utils/index.js +12 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/ble/constants.js +26 -0
- package/lib/module/ble/constants.js.map +1 -1
- package/lib/module/ble/parsers.js +124 -1
- package/lib/module/ble/parsers.js.map +1 -1
- package/lib/module/managers/DeviceManager.js +181 -2
- package/lib/module/managers/DeviceManager.js.map +1 -1
- package/lib/module/utils/crypto.js +160 -0
- package/lib/module/utils/crypto.js.map +1 -0
- package/lib/module/utils/index.js +1 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/src/ble/constants.d.ts +18 -0
- package/lib/typescript/src/ble/constants.d.ts.map +1 -1
- package/lib/typescript/src/ble/parsers.d.ts +34 -1
- package/lib/typescript/src/ble/parsers.d.ts.map +1 -1
- package/lib/typescript/src/managers/DeviceManager.d.ts +73 -1
- package/lib/typescript/src/managers/DeviceManager.d.ts.map +1 -1
- package/lib/typescript/src/models/Device.d.ts +65 -0
- package/lib/typescript/src/models/Device.d.ts.map +1 -1
- package/lib/typescript/src/utils/crypto.d.ts +83 -0
- package/lib/typescript/src/utils/crypto.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +1 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/ble/constants.ts +26 -0
- package/src/ble/parsers.ts +131 -0
- package/src/managers/DeviceManager.ts +244 -0
- package/src/models/Device.ts +76 -0
- package/src/utils/crypto.ts +221 -0
- package/src/utils/index.ts +1 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Device Manager - Handles device discovery, connection, and provisioning
|
|
3
3
|
*/
|
|
4
|
+
import { Subscription } from 'react-native-ble-plx';
|
|
4
5
|
import EventEmitter from 'eventemitter3';
|
|
5
|
-
import type { DiscoveredDevice, ConnectedDevice, DeviceStatus, ScanOptions, Environment, RecordingState, StartRecordingOptions, StopRecordingOptions } from '../models/Device';
|
|
6
|
+
import type { DiscoveredDevice, ConnectedDevice, DeviceStatus, ScanOptions, Environment, RecordingState, StartRecordingOptions, StopRecordingOptions, WiFiConfigGrant, WiFiCredentials, WiFiConfigResult, WiFiStatusInfo } from '../models/Device';
|
|
6
7
|
import type { DeviceManagerEvents } from '../models/Status';
|
|
7
8
|
/**
|
|
8
9
|
* Device Manager class
|
|
@@ -118,6 +119,77 @@ export declare class DeviceManager extends EventEmitter<DeviceManagerEvents> {
|
|
|
118
119
|
* Parse recording state from BLE data
|
|
119
120
|
*/
|
|
120
121
|
private parseRecordingState;
|
|
122
|
+
/**
|
|
123
|
+
* Configure WiFi credentials on device via BLE.
|
|
124
|
+
* Requires a WiFi configuration grant from backend.
|
|
125
|
+
*
|
|
126
|
+
* @param deviceId - Connected device ID
|
|
127
|
+
* @param credentials - WiFi network credentials
|
|
128
|
+
* @param grant - WiFi config grant from backend
|
|
129
|
+
* @returns Configuration result
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* // 1. Get grant from backend
|
|
134
|
+
* const grant = await api.createWiFiConfigGrant(deviceId);
|
|
135
|
+
*
|
|
136
|
+
* // 2. Configure device via BLE
|
|
137
|
+
* const result = await deviceManager.configureWiFi(
|
|
138
|
+
* deviceId,
|
|
139
|
+
* { ssid: 'MyNetwork', password: 'password123', securityType: 'WPA2' },
|
|
140
|
+
* grant
|
|
141
|
+
* );
|
|
142
|
+
*
|
|
143
|
+
* if (result.success) {
|
|
144
|
+
* console.log('WiFi configured successfully');
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
configureWiFi(deviceId: string, credentials: WiFiCredentials, grant: WiFiConfigGrant): Promise<WiFiConfigResult>;
|
|
149
|
+
/**
|
|
150
|
+
* Get WiFi connection status from device.
|
|
151
|
+
*
|
|
152
|
+
* @param deviceId - Connected device ID
|
|
153
|
+
* @returns WiFi status information
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const status = await deviceManager.getWiFiStatus(deviceId);
|
|
158
|
+
* console.log('WiFi status:', status.status);
|
|
159
|
+
* if (status.status === 'connected') {
|
|
160
|
+
* console.log('Connected to:', status.ssid);
|
|
161
|
+
* console.log('Signal strength:', status.signalStrength);
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
getWiFiStatus(deviceId: string): Promise<WiFiStatusInfo>;
|
|
166
|
+
/**
|
|
167
|
+
* Subscribe to WiFi status updates from device.
|
|
168
|
+
*
|
|
169
|
+
* @param deviceId - Connected device ID
|
|
170
|
+
* @param callback - Callback function for status updates
|
|
171
|
+
* @returns Subscription object (call .remove() to unsubscribe)
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const subscription = deviceManager.subscribeToWiFiStatus(deviceId, (status) => {
|
|
176
|
+
* console.log('WiFi status update:', status.status);
|
|
177
|
+
* if (status.status === 'connected') {
|
|
178
|
+
* console.log('Connected to:', status.ssid);
|
|
179
|
+
* } else if (status.status === 'failed') {
|
|
180
|
+
* console.error('Connection failed:', status.lastError);
|
|
181
|
+
* }
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* // Later: unsubscribe
|
|
185
|
+
* subscription.remove();
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
subscribeToWiFiStatus(deviceId: string, callback: (status: WiFiStatusInfo) => void): Subscription;
|
|
189
|
+
/**
|
|
190
|
+
* Wait for WiFi configuration result from device.
|
|
191
|
+
*/
|
|
192
|
+
private waitForWiFiConfigResult;
|
|
121
193
|
/**
|
|
122
194
|
* Clean up resources
|
|
123
195
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceManager.d.ts","sourceRoot":"","sources":["../../../../src/managers/DeviceManager.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"DeviceManager.d.ts","sourceRoot":"","sources":["../../../../src/managers/DeviceManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -55,6 +55,19 @@ export interface DiscoveredDevice {
|
|
|
55
55
|
/** Timestamp when discovered */
|
|
56
56
|
discoveredAt: Date;
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Device capabilities (bitmask)
|
|
60
|
+
*/
|
|
61
|
+
export interface DeviceCapabilities {
|
|
62
|
+
/** Supports Bluetooth Sync (BLE transfer) */
|
|
63
|
+
bleSync: boolean;
|
|
64
|
+
/** Supports WiFi Upload */
|
|
65
|
+
wifiUpload: boolean;
|
|
66
|
+
/** Supports Cellular Upload (4G/LTE) */
|
|
67
|
+
lteUpload: boolean;
|
|
68
|
+
/** Supports Remote Recording Control */
|
|
69
|
+
remoteRecord: boolean;
|
|
70
|
+
}
|
|
58
71
|
/**
|
|
59
72
|
* Device after successful BLE connection
|
|
60
73
|
*/
|
|
@@ -75,6 +88,8 @@ export interface ConnectedDevice {
|
|
|
75
88
|
connectionState: ConnectionState;
|
|
76
89
|
/** Negotiated MTU size */
|
|
77
90
|
mtu: number;
|
|
91
|
+
/** Device capabilities */
|
|
92
|
+
capabilities?: DeviceCapabilities;
|
|
78
93
|
}
|
|
79
94
|
/**
|
|
80
95
|
* Device status information
|
|
@@ -211,4 +226,54 @@ export interface RecordingState {
|
|
|
211
226
|
/** Who initiated the recording */
|
|
212
227
|
initiatedBy?: 'local' | 'remote';
|
|
213
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* WiFi security type
|
|
231
|
+
*/
|
|
232
|
+
export type WiFiSecurityType = 'WPA2' | 'WPA3' | 'WEP' | 'OPEN';
|
|
233
|
+
/**
|
|
234
|
+
* WiFi connection status
|
|
235
|
+
*/
|
|
236
|
+
export type WiFiStatus = 'idle' | 'connecting' | 'connected' | 'failed' | 'disconnected';
|
|
237
|
+
/**
|
|
238
|
+
* WiFi configuration grant from backend
|
|
239
|
+
*/
|
|
240
|
+
export interface WiFiConfigGrant {
|
|
241
|
+
/** Grant blob (JWT token) */
|
|
242
|
+
grantBlob: string;
|
|
243
|
+
/** Expiration timestamp */
|
|
244
|
+
expiresAt: Date;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* WiFi credentials to configure
|
|
248
|
+
*/
|
|
249
|
+
export interface WiFiCredentials {
|
|
250
|
+
/** WiFi network SSID */
|
|
251
|
+
ssid: string;
|
|
252
|
+
/** WiFi password */
|
|
253
|
+
password: string;
|
|
254
|
+
/** Security type (default: WPA2) */
|
|
255
|
+
securityType?: WiFiSecurityType;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* WiFi configuration result from device
|
|
259
|
+
*/
|
|
260
|
+
export interface WiFiConfigResult {
|
|
261
|
+
/** Whether configuration was successful */
|
|
262
|
+
success: boolean;
|
|
263
|
+
/** Error code if failed */
|
|
264
|
+
error?: 'invalid_grant' | 'grant_expired' | 'decryption_error' | 'storage_error' | 'unknown';
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* WiFi status information from device
|
|
268
|
+
*/
|
|
269
|
+
export interface WiFiStatusInfo {
|
|
270
|
+
/** Current WiFi connection status */
|
|
271
|
+
status: WiFiStatus;
|
|
272
|
+
/** Connected SSID (if connected) */
|
|
273
|
+
ssid?: string;
|
|
274
|
+
/** Signal strength (0-100) */
|
|
275
|
+
signalStrength?: number;
|
|
276
|
+
/** Last connection error (if failed) */
|
|
277
|
+
lastError?: string;
|
|
278
|
+
}
|
|
214
279
|
//# sourceMappingURL=Device.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Device.d.ts","sourceRoot":"","sources":["../../../../src/models/Device.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,YAAY,GACZ,SAAS,GACT,aAAa,GACb,WAAW,GACX,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,WAAW,GACX,SAAS,GACT,WAAW,GACX,UAAU,GACV,YAAY,GACZ,aAAa,GACb,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,UAAU,EAAE,UAAU,CAAC;IACvB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,UAAU,CAAC;IAC9B,gCAAgC;IAChC,YAAY,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,uBAAuB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,+BAA+B;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Device.d.ts","sourceRoot":"","sources":["../../../../src/models/Device.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,YAAY,GACZ,SAAS,GACT,aAAa,GACb,WAAW,GACX,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,WAAW,GACX,SAAS,GACT,WAAW,GACX,UAAU,GACV,YAAY,GACZ,aAAa,GACb,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,UAAU,EAAE,UAAU,CAAC;IACvB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,UAAU,CAAC;IAC9B,gCAAgC;IAChC,YAAY,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,uBAAuB;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,+BAA+B;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gCAAgC;IAChC,KAAK,EAAE,WAAW,CAAC;IACnB,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0BAA0B;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,8BAA8B;IAC9B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,GAAG,eAAe,GAAG,aAAa,GAAG,SAAS,CAAC;CACvE;AAMD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,SAAS,GACT,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,MAAM,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAClC;AAMD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEzF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,eAAe,GAAG,eAAe,GAAG,kBAAkB,GAAG,eAAe,GAAG,SAAS,CAAC;CAC9F;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic utilities for WiFi Upload configuration
|
|
3
|
+
*
|
|
4
|
+
* NOTE: This module requires react-native-quick-crypto to be installed.
|
|
5
|
+
* Add to your app: npm install react-native-quick-crypto
|
|
6
|
+
*/
|
|
7
|
+
import { Buffer } from 'buffer';
|
|
8
|
+
/**
|
|
9
|
+
* Derive K_session from WiFi config grant.
|
|
10
|
+
* K_session is used by device and app to encrypt/decrypt WiFi credentials in transit.
|
|
11
|
+
*
|
|
12
|
+
* Derivation: K_session = HMAC-SHA256(grant_blob, "BOTA_WIFI_SESSION_V1")
|
|
13
|
+
*
|
|
14
|
+
* @param grantBlob - Base64-encoded JWT grant from backend
|
|
15
|
+
* @returns 32-byte K_session as hex string
|
|
16
|
+
*/
|
|
17
|
+
export declare function deriveSessionKey(grantBlob: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Encrypt WiFi credentials for BLE transmission using ChaCha20-Poly1305.
|
|
20
|
+
*
|
|
21
|
+
* Format sent to device:
|
|
22
|
+
* - 12 bytes: nonce (random)
|
|
23
|
+
* - N bytes: encrypted SSID
|
|
24
|
+
* - 16 bytes: auth tag for SSID
|
|
25
|
+
* - M bytes: encrypted password
|
|
26
|
+
* - 16 bytes: auth tag for password
|
|
27
|
+
*
|
|
28
|
+
* @param ssid - WiFi network SSID
|
|
29
|
+
* @param password - WiFi password
|
|
30
|
+
* @param sessionKey - K_session derived from grant (hex string)
|
|
31
|
+
* @returns Encrypted payload ready for BLE transmission
|
|
32
|
+
*/
|
|
33
|
+
export declare function encryptWiFiCredentials(ssid: string, password: string, sessionKey: string): {
|
|
34
|
+
nonce: Buffer;
|
|
35
|
+
ssidEncrypted: Buffer;
|
|
36
|
+
ssidAuthTag: Buffer;
|
|
37
|
+
passwordEncrypted: Buffer;
|
|
38
|
+
passwordAuthTag: Buffer;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Decrypt WiFi credentials received from device (if needed for verification).
|
|
42
|
+
*
|
|
43
|
+
* @param encrypted - Encrypted SSID or password
|
|
44
|
+
* @param nonce - 12-byte nonce
|
|
45
|
+
* @param authTag - 16-byte authentication tag
|
|
46
|
+
* @param sessionKey - K_session derived from grant (hex string)
|
|
47
|
+
* @param aad - Additional authenticated data (optional, use 'password' for password field)
|
|
48
|
+
* @returns Decrypted plaintext
|
|
49
|
+
*/
|
|
50
|
+
export declare function decryptWiFiCredential(encrypted: Buffer, nonce: Buffer, authTag: Buffer, sessionKey: string, aad?: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Format encrypted WiFi credentials for BLE transmission.
|
|
53
|
+
*
|
|
54
|
+
* Packet format:
|
|
55
|
+
* [nonce (12 bytes)][ssid_encrypted (N bytes)][ssid_tag (16 bytes)]
|
|
56
|
+
* [password_encrypted (M bytes)][password_tag (16 bytes)]
|
|
57
|
+
*
|
|
58
|
+
* @param encrypted - Result from encryptWiFiCredentials
|
|
59
|
+
* @returns Single buffer ready for BLE write
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatWiFiCredentialPacket(encrypted: {
|
|
62
|
+
nonce: Buffer;
|
|
63
|
+
ssidEncrypted: Buffer;
|
|
64
|
+
ssidAuthTag: Buffer;
|
|
65
|
+
passwordEncrypted: Buffer;
|
|
66
|
+
passwordAuthTag: Buffer;
|
|
67
|
+
}): Buffer;
|
|
68
|
+
/**
|
|
69
|
+
* Parse encrypted WiFi credential packet received from device.
|
|
70
|
+
*
|
|
71
|
+
* @param packet - Buffer received from BLE
|
|
72
|
+
* @param ssidLength - Expected SSID encrypted length
|
|
73
|
+
* @param passwordLength - Expected password encrypted length
|
|
74
|
+
* @returns Parsed components
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseWiFiCredentialPacket(packet: Buffer, ssidLength: number, passwordLength: number): {
|
|
77
|
+
nonce: Buffer;
|
|
78
|
+
ssidEncrypted: Buffer;
|
|
79
|
+
ssidAuthTag: Buffer;
|
|
80
|
+
passwordEncrypted: Buffer;
|
|
81
|
+
passwordAuthTag: Buffer;
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAoBhC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAsCA;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAuBR;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAyBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bota-dev/react-native-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Bota React Native SDK for BLE device communication",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"react": ">=18.0.0",
|
|
48
48
|
"react-native": ">=0.72.0",
|
|
49
49
|
"react-native-ble-plx": ">=3.0.0",
|
|
50
|
-
"@react-native-async-storage/async-storage": ">=1.21.0"
|
|
50
|
+
"@react-native-async-storage/async-storage": ">=1.21.0",
|
|
51
|
+
"react-native-quick-crypto": ">=0.7.0"
|
|
51
52
|
},
|
|
52
53
|
"peerDependenciesMeta": {
|
|
53
54
|
"react-native-ble-plx": {
|
|
@@ -55,6 +56,9 @@
|
|
|
55
56
|
},
|
|
56
57
|
"@react-native-async-storage/async-storage": {
|
|
57
58
|
"optional": false
|
|
59
|
+
},
|
|
60
|
+
"react-native-quick-crypto": {
|
|
61
|
+
"optional": true
|
|
58
62
|
}
|
|
59
63
|
},
|
|
60
64
|
"dependencies": {
|
package/src/ble/constants.ts
CHANGED
|
@@ -13,6 +13,7 @@ export const SERVICE_BOTA_AUDIO = 'B07A0001-0000-1000-8000-00805F9B34FB';
|
|
|
13
13
|
export const SERVICE_BOTA_CONTROL = 'B07A0002-0000-1000-8000-00805F9B34FB';
|
|
14
14
|
export const SERVICE_BOTA_PROVISIONING = 'B07A0003-0000-1000-8000-00805F9B34FB';
|
|
15
15
|
export const SERVICE_BOTA_STORAGE = 'B07A0004-0000-1000-8000-00805F9B34FB';
|
|
16
|
+
export const SERVICE_BOTA_WIFI_CONFIG = 'B07A0006-0000-1000-8000-00805F9B34FB';
|
|
16
17
|
|
|
17
18
|
// Device Information Service Characteristics (0x180A)
|
|
18
19
|
export const CHAR_MANUFACTURER_NAME = '2A29';
|
|
@@ -50,6 +51,11 @@ export const CHAR_RECORDING_TRANSFER = 'B07A0004-0003-1000-8000-00805F9B34FB';
|
|
|
50
51
|
export const CHAR_TRANSFER_CONTROL = 'B07A0004-0004-1000-8000-00805F9B34FB';
|
|
51
52
|
export const CHAR_TRANSFER_STATUS = 'B07A0004-0005-1000-8000-00805F9B34FB';
|
|
52
53
|
|
|
54
|
+
// Bota WiFi Config Service Characteristics (B07A0006)
|
|
55
|
+
export const CHAR_WIFI_GRANT = 'B07A0006-0001-1000-8000-00805F9B34FB';
|
|
56
|
+
export const CHAR_WIFI_CREDENTIAL = 'B07A0006-0002-1000-8000-00805F9B34FB';
|
|
57
|
+
export const CHAR_WIFI_STATUS = 'B07A0006-0003-1000-8000-00805F9B34FB';
|
|
58
|
+
|
|
53
59
|
// Device name prefixes for scanning
|
|
54
60
|
export const DEVICE_NAME_PREFIX = 'Bota-';
|
|
55
61
|
export const DEVICE_NAME_PREFIX_PIN = 'Bota-Pin-';
|
|
@@ -68,18 +74,38 @@ export const DEVICE_TYPE_PIN = 0x01;
|
|
|
68
74
|
export const DEVICE_TYPE_PIN_4G = 0x02;
|
|
69
75
|
export const DEVICE_TYPE_NOTE = 0x03;
|
|
70
76
|
|
|
77
|
+
// Device capability flags (bitmask)
|
|
78
|
+
export const CAP_BLE_SYNC = 0x01;
|
|
79
|
+
export const CAP_WIFI_UPLOAD = 0x02;
|
|
80
|
+
export const CAP_LTE_UPLOAD = 0x04;
|
|
81
|
+
export const CAP_REMOTE_RECORD = 0x08;
|
|
82
|
+
|
|
71
83
|
// Pairing state values
|
|
72
84
|
export const PAIRING_STATE_UNPAIRED = 0x00;
|
|
73
85
|
export const PAIRING_STATE_PAIRING = 0x01;
|
|
74
86
|
export const PAIRING_STATE_PAIRED = 0x02;
|
|
75
87
|
export const PAIRING_STATE_ERROR = 0x03;
|
|
76
88
|
|
|
89
|
+
// WiFi status values
|
|
90
|
+
export const WIFI_STATUS_IDLE = 0x00;
|
|
91
|
+
export const WIFI_STATUS_CONNECTING = 0x01;
|
|
92
|
+
export const WIFI_STATUS_CONNECTED = 0x02;
|
|
93
|
+
export const WIFI_STATUS_FAILED = 0x03;
|
|
94
|
+
export const WIFI_STATUS_DISCONNECTED = 0x04;
|
|
95
|
+
|
|
77
96
|
// Provisioning result codes
|
|
78
97
|
export const PROVISIONING_SUCCESS = 0x00;
|
|
79
98
|
export const PROVISIONING_INVALID_TOKEN = 0x01;
|
|
80
99
|
export const PROVISIONING_STORAGE_ERROR = 0x02;
|
|
81
100
|
export const PROVISIONING_CHUNK_ERROR = 0x03;
|
|
82
101
|
|
|
102
|
+
// WiFi configuration result codes
|
|
103
|
+
export const WIFI_CONFIG_SUCCESS = 0x00;
|
|
104
|
+
export const WIFI_CONFIG_INVALID_GRANT = 0x01;
|
|
105
|
+
export const WIFI_CONFIG_GRANT_EXPIRED = 0x02;
|
|
106
|
+
export const WIFI_CONFIG_DECRYPTION_ERROR = 0x03;
|
|
107
|
+
export const WIFI_CONFIG_STORAGE_ERROR = 0x04;
|
|
108
|
+
|
|
83
109
|
// API endpoint values
|
|
84
110
|
export const API_ENDPOINT_PRODUCTION = 0x00;
|
|
85
111
|
export const API_ENDPOINT_SANDBOX = 0x01;
|
package/src/ble/parsers.ts
CHANGED
|
@@ -11,6 +11,10 @@ import type {
|
|
|
11
11
|
DeviceStatus,
|
|
12
12
|
DeviceFlags,
|
|
13
13
|
StorageInfo,
|
|
14
|
+
DeviceCapabilities,
|
|
15
|
+
WiFiStatus,
|
|
16
|
+
WiFiStatusInfo,
|
|
17
|
+
WiFiConfigResult,
|
|
14
18
|
} from '../models/Device';
|
|
15
19
|
import type { DeviceRecording, AudioCodec, TransferPacket } from '../models/Recording';
|
|
16
20
|
import {
|
|
@@ -48,6 +52,20 @@ import {
|
|
|
48
52
|
PACKET_TYPE_DATA,
|
|
49
53
|
PACKET_TYPE_EOF,
|
|
50
54
|
PACKET_TYPE_ERROR,
|
|
55
|
+
CAP_BLE_SYNC,
|
|
56
|
+
CAP_WIFI_UPLOAD,
|
|
57
|
+
CAP_LTE_UPLOAD,
|
|
58
|
+
CAP_REMOTE_RECORD,
|
|
59
|
+
WIFI_STATUS_IDLE,
|
|
60
|
+
WIFI_STATUS_CONNECTING,
|
|
61
|
+
WIFI_STATUS_CONNECTED,
|
|
62
|
+
WIFI_STATUS_FAILED,
|
|
63
|
+
WIFI_STATUS_DISCONNECTED,
|
|
64
|
+
WIFI_CONFIG_SUCCESS,
|
|
65
|
+
WIFI_CONFIG_INVALID_GRANT,
|
|
66
|
+
WIFI_CONFIG_GRANT_EXPIRED,
|
|
67
|
+
WIFI_CONFIG_DECRYPTION_ERROR,
|
|
68
|
+
WIFI_CONFIG_STORAGE_ERROR,
|
|
51
69
|
} from './constants';
|
|
52
70
|
|
|
53
71
|
/**
|
|
@@ -393,3 +411,116 @@ export function createTransferCommand(
|
|
|
393
411
|
|
|
394
412
|
return Buffer.from([cmdByte]);
|
|
395
413
|
}
|
|
414
|
+
|
|
415
|
+
// ============================================================================
|
|
416
|
+
// WiFi Upload Configuration Parsers
|
|
417
|
+
// ============================================================================
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Parse device capabilities from byte value
|
|
421
|
+
*/
|
|
422
|
+
export function parseDeviceCapabilities(byte: number): DeviceCapabilities {
|
|
423
|
+
return {
|
|
424
|
+
bleSync: (byte & CAP_BLE_SYNC) !== 0,
|
|
425
|
+
wifiUpload: (byte & CAP_WIFI_UPLOAD) !== 0,
|
|
426
|
+
lteUpload: (byte & CAP_LTE_UPLOAD) !== 0,
|
|
427
|
+
remoteRecord: (byte & CAP_REMOTE_RECORD) !== 0,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Parse WiFi status from byte value
|
|
433
|
+
*/
|
|
434
|
+
export function parseWiFiStatus(byte: number): WiFiStatus {
|
|
435
|
+
switch (byte) {
|
|
436
|
+
case WIFI_STATUS_IDLE:
|
|
437
|
+
return 'idle';
|
|
438
|
+
case WIFI_STATUS_CONNECTING:
|
|
439
|
+
return 'connecting';
|
|
440
|
+
case WIFI_STATUS_CONNECTED:
|
|
441
|
+
return 'connected';
|
|
442
|
+
case WIFI_STATUS_FAILED:
|
|
443
|
+
return 'failed';
|
|
444
|
+
case WIFI_STATUS_DISCONNECTED:
|
|
445
|
+
return 'disconnected';
|
|
446
|
+
default:
|
|
447
|
+
return 'idle';
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Parse WiFi status information from characteristic value
|
|
453
|
+
*
|
|
454
|
+
* Format:
|
|
455
|
+
* Byte 0: Status (0x00=idle, 0x01=connecting, 0x02=connected, 0x03=failed, 0x04=disconnected)
|
|
456
|
+
* Byte 1: Signal strength (0-100)
|
|
457
|
+
* Byte 2: SSID length
|
|
458
|
+
* Bytes 3-34: SSID (max 32 bytes)
|
|
459
|
+
* Bytes 35+: Error message (if status=failed)
|
|
460
|
+
*/
|
|
461
|
+
export function parseWiFiStatusInfo(data: Buffer): WiFiStatusInfo {
|
|
462
|
+
if (data.length < 3) {
|
|
463
|
+
throw new Error(`Invalid WiFi status data length: ${data.length}`);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const status = parseWiFiStatus(data.readUInt8(0));
|
|
467
|
+
const signalStrength = data.readUInt8(1);
|
|
468
|
+
const ssidLength = data.readUInt8(2);
|
|
469
|
+
|
|
470
|
+
let ssid: string | undefined;
|
|
471
|
+
let lastError: string | undefined;
|
|
472
|
+
|
|
473
|
+
if (ssidLength > 0 && data.length >= 3 + ssidLength) {
|
|
474
|
+
ssid = data.slice(3, 3 + ssidLength).toString('utf-8');
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (status === 'failed' && data.length > 3 + ssidLength) {
|
|
478
|
+
lastError = data.slice(3 + ssidLength).toString('utf-8');
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return {
|
|
482
|
+
status,
|
|
483
|
+
signalStrength: signalStrength > 0 ? signalStrength : undefined,
|
|
484
|
+
ssid,
|
|
485
|
+
lastError,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Parse WiFi configuration result from characteristic value
|
|
491
|
+
*
|
|
492
|
+
* Format:
|
|
493
|
+
* Byte 0: Result code (0x00=success, 0x01=invalid_grant, 0x02=grant_expired, 0x03=decryption_error, 0x04=storage_error)
|
|
494
|
+
*/
|
|
495
|
+
export function parseWiFiConfigResult(data: Buffer): WiFiConfigResult {
|
|
496
|
+
if (data.length < 1) {
|
|
497
|
+
throw new Error(`Invalid WiFi config result length: ${data.length}`);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const code = data.readUInt8(0);
|
|
501
|
+
|
|
502
|
+
switch (code) {
|
|
503
|
+
case WIFI_CONFIG_SUCCESS:
|
|
504
|
+
return { success: true };
|
|
505
|
+
case WIFI_CONFIG_INVALID_GRANT:
|
|
506
|
+
return { success: false, error: 'invalid_grant' };
|
|
507
|
+
case WIFI_CONFIG_GRANT_EXPIRED:
|
|
508
|
+
return { success: false, error: 'grant_expired' };
|
|
509
|
+
case WIFI_CONFIG_DECRYPTION_ERROR:
|
|
510
|
+
return { success: false, error: 'decryption_error' };
|
|
511
|
+
case WIFI_CONFIG_STORAGE_ERROR:
|
|
512
|
+
return { success: false, error: 'storage_error' };
|
|
513
|
+
default:
|
|
514
|
+
return { success: false, error: 'unknown' };
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Create WiFi grant submission packet
|
|
520
|
+
*
|
|
521
|
+
* Format:
|
|
522
|
+
* Bytes 0-N: Grant blob (JWT token as UTF-8 string)
|
|
523
|
+
*/
|
|
524
|
+
export function createWiFiGrantPacket(grantBlob: string): Buffer {
|
|
525
|
+
return Buffer.from(grantBlob, 'utf-8');
|
|
526
|
+
}
|