@neurodevs/ndx-native 6.0.1 → 6.1.0

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.
@@ -5,6 +5,7 @@ import LibndxAdapter, {
5
5
  Libndx,
6
6
  LibndxBindings,
7
7
  } from '../../impl/LibndxAdapter.js'
8
+ import type { NativePeripheral } from '../../impl/LibndxAdapter.js'
8
9
  import AbstractPackageTest from '../AbstractPackageTest.js'
9
10
  import FakeLibndx from '../../testDoubles/Libndx/FakeLibndx.js'
10
11
 
@@ -16,11 +17,13 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
16
17
 
17
18
  private static koffiLoadPath?: string
18
19
  private static koffiFuncSignatures?: string[]
20
+ private static koffiProtoCalls?: string[]
19
21
  private static koffiStructCalls?: { name: string; fields: object }[]
20
22
 
21
23
  private static readonly bleDeviceUuid = this.generateId()
22
24
  private static readonly bleCharacteristicUuid = this.generateId()
23
25
  private static readonly bleValueToWrite = this.generateId()
26
+ private static readonly bleRssiIntervalMs = Math.random()
24
27
 
25
28
  private static readonly ftdiSerialNumber = this.generateId()
26
29
 
@@ -34,6 +37,12 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
34
37
 
35
38
  private static readonly successfulResult = { status: 200 }
36
39
 
40
+ private static readonly bleNamePrefix = this.generateId()
41
+
42
+ private static readonly callsToDiscoverBle: {
43
+ namePrefix: string
44
+ onDiscovered: unknown
45
+ }[] = []
37
46
  private static readonly callsToCreateBle: string[][] = []
38
47
  private static readonly callsToStartBle: {
39
48
  uuid: string
@@ -41,7 +50,11 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
41
50
  charCallbacks: CharacteristicCallback[]
42
51
  }[] = []
43
52
  private static readonly callsToWriteBle: string[][] = []
44
- private static readonly callsToReadRssi: string[][] = []
53
+ private static readonly callsToSetBleRssiInterval: {
54
+ uuid: string
55
+ intervalMs: number
56
+ onRssi: unknown
57
+ }[] = []
45
58
  private static readonly callsToStopBle: string[][] = []
46
59
 
47
60
  private static readonly callsToCreateFtdi: string[][] = []
@@ -94,10 +107,11 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
94
107
  assert.isEqualDeep(
95
108
  this.koffiFuncSignatures,
96
109
  [
110
+ 'str discover_ble_uuid(str name_prefix, OnDiscoveredFn *on_discovered)',
97
111
  'str create_ble_backend(str config)',
98
112
  'str start_ble_backend(str uuid, OnConnectedFn *on_connected, CharCallback *callbacks, int num_callbacks)',
99
113
  'str write_ble_characteristic(str uuid, str charUuid, str value)',
100
- 'str read_ble_rssi(str uuid)',
114
+ 'str set_ble_rssi_interval(str uuid, int interval_ms, OnRssiFn *on_rssi)',
101
115
  'str stop_ble_backend(str uuid)',
102
116
  'str create_ftdi_backend(str config)',
103
117
  'str start_ftdi_backend(str serial)',
@@ -125,6 +139,69 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
125
139
  )
126
140
  }
127
141
 
142
+ @test()
143
+ protected static async registersOnRssiProtoBeforeLoadingBindings() {
144
+ const onRssiProtoIdx = this.koffiProtoCalls!.findIndex((s) =>
145
+ s.includes('OnRssiFn')
146
+ )
147
+ const firstFuncIdx = this.koffiFuncSignatures!.findIndex((s) =>
148
+ s.includes('OnRssiFn')
149
+ )
150
+ assert.isAbove(
151
+ onRssiProtoIdx,
152
+ -1,
153
+ 'Did not register OnRssiFn proto before loading bindings!'
154
+ )
155
+ assert.isBelow(
156
+ onRssiProtoIdx,
157
+ firstFuncIdx + this.koffiProtoCalls!.length,
158
+ 'OnRssiFn proto must be registered before bindings are loaded!'
159
+ )
160
+ }
161
+
162
+ @test()
163
+ protected static async registersOnDiscoveredProtoBeforeLoadingBindings() {
164
+ const onDiscoveredProtoIdx = this.koffiProtoCalls!.findIndex((s) =>
165
+ s.includes('OnDiscoveredFn')
166
+ )
167
+ const firstFuncIdx = this.koffiFuncSignatures!.findIndex((s) =>
168
+ s.includes('OnDiscoveredFn')
169
+ )
170
+ assert.isAbove(
171
+ onDiscoveredProtoIdx,
172
+ -1,
173
+ 'Did not register OnDiscoveredFn proto before loading bindings!'
174
+ )
175
+ assert.isBelow(
176
+ onDiscoveredProtoIdx,
177
+ firstFuncIdx + this.koffiProtoCalls!.length,
178
+ 'OnDiscoveredFn proto must be registered before bindings are loaded!'
179
+ )
180
+ }
181
+
182
+ @test()
183
+ protected static async onConnectedReceivesPeripheral() {
184
+ let received: NativePeripheral | undefined = undefined
185
+
186
+ this.startBleBackend((peripheral: NativePeripheral) => {
187
+ received = peripheral
188
+ })
189
+
190
+ const peripheral = { uuid: this.generateId(), name: 'Muse-1234' }
191
+
192
+ const registeredOnConnected = this.callsToStartBle[0].onConnected as (
193
+ uuid: string,
194
+ name: string
195
+ ) => void
196
+ registeredOnConnected(peripheral.uuid, peripheral.name)
197
+
198
+ assert.isEqualDeep(
199
+ received,
200
+ peripheral,
201
+ 'onConnected was not called with the peripheral!'
202
+ )
203
+ }
204
+
128
205
  @test()
129
206
  protected static async getInstanceReturnsASingleton() {
130
207
  assert.isEqual(LibndxAdapter.getInstance(), LibndxAdapter.getInstance())
@@ -137,6 +214,53 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
137
214
  assert.isEqual(LibndxAdapter.getInstance(), fake)
138
215
  }
139
216
 
217
+ @test()
218
+ protected static async discoverBleUuidCallsBindingWithExpectedArgs() {
219
+ this.discoverBleUuid()
220
+
221
+ assert.isEqual(
222
+ this.callsToDiscoverBle[0].namePrefix,
223
+ this.bleNamePrefix,
224
+ 'discoverBleUuid did not pass expected namePrefix to binding!'
225
+ )
226
+
227
+ assert.isFunction(
228
+ this.callsToDiscoverBle[0].onDiscovered,
229
+ 'discoverBleUuid did not pass an onDiscovered callback to the binding!'
230
+ )
231
+ }
232
+
233
+ @test()
234
+ protected static async discoverBleUuidReturnsJson() {
235
+ const json = this.discoverBleUuid()
236
+
237
+ assert.isEqualDeep(
238
+ json,
239
+ this.successfulResult,
240
+ 'discoverBleUuid did not return a JSON string!'
241
+ )
242
+ }
243
+
244
+ @test()
245
+ protected static async discoverBleUuidInvokesOnDiscoveredWithUuid() {
246
+ let received: string | undefined
247
+
248
+ this.discoverBleUuid((uuid: string) => {
249
+ received = uuid
250
+ })
251
+
252
+ const discoveredUuid = this.generateId()
253
+ const registeredOnDiscovered = this.callsToDiscoverBle[0]
254
+ .onDiscovered as (uuid: string) => void
255
+ registeredOnDiscovered(discoveredUuid)
256
+
257
+ assert.isEqual(
258
+ received,
259
+ discoveredUuid,
260
+ 'onDiscovered was not invoked with discovered uuid!'
261
+ )
262
+ }
263
+
140
264
  @test()
141
265
  protected static async createBleBackendCallsBindingWithExpectedArgs() {
142
266
  this.createBleBackend()
@@ -216,27 +340,53 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
216
340
  }
217
341
 
218
342
  @test()
219
- protected static async getRssiBleBackendCallsBindingWithExpectedArgs() {
220
- this.getRssiBleBackend()
343
+ protected static async setBleRssiIntervalCallsBindingWithExpectedArgs() {
344
+ this.setBleRssiInterval()
221
345
 
222
- assert.isEqual(
223
- this.callsToReadRssi[0][0],
224
- this.bleDeviceUuid,
225
- 'getRssiBleBackend did not call binding with expected args!'
346
+ const { uuid, intervalMs } = this.callsToSetBleRssiInterval[0]
347
+
348
+ assert.isEqualDeep(
349
+ { uuid, intervalMs },
350
+ {
351
+ uuid: this.bleDeviceUuid,
352
+ intervalMs: this.bleRssiIntervalMs,
353
+ },
354
+ 'setBleRssiInterval did not call binding with expected args!'
355
+ )
356
+
357
+ assert.isFunction(
358
+ this.callsToSetBleRssiInterval[0].onRssi,
359
+ 'setBleRssiInterval did not pass an onRssi callback to the binding!'
226
360
  )
227
361
  }
228
362
 
229
363
  @test()
230
- protected static async getRssiBleBackendReturnsJson() {
231
- const json = this.getRssiBleBackend()
364
+ protected static async setBleRssiIntervalReturnsJson() {
365
+ const json = this.setBleRssiInterval()
232
366
 
233
367
  assert.isEqualDeep(
234
368
  json,
235
369
  this.successfulResult,
236
- 'getRssiBleBackend did not return a JSON string!'
370
+ 'setBleRssiInterval did not return a JSON string!'
237
371
  )
238
372
  }
239
373
 
374
+ @test()
375
+ protected static async setBleRssiIntervalInvokesOnRssiWithRssiValue() {
376
+ let received: number | undefined
377
+
378
+ this.setBleRssiInterval((rssi: number) => {
379
+ received = rssi
380
+ })
381
+
382
+ const registeredOnRssi = this.callsToSetBleRssiInterval[0].onRssi as (
383
+ rssi: number
384
+ ) => void
385
+ registeredOnRssi(-72)
386
+
387
+ assert.isEqual(received, -72, 'onRssi was not invoked with rssi value!')
388
+ }
389
+
240
390
  @test()
241
391
  protected static async stopBleBackendCallsBindingWithExpectedArgs() {
242
392
  this.stopBleBackend()
@@ -325,16 +475,25 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
325
475
  )
326
476
  }
327
477
 
478
+ private static discoverBleUuid(onDiscovered?: (uuid: string) => void) {
479
+ return this.instance.discoverBleUuid({
480
+ namePrefix: this.bleNamePrefix,
481
+ onDiscovered: onDiscovered ?? (() => {}),
482
+ })
483
+ }
484
+
328
485
  private static createBleBackend() {
329
486
  return this.instance.createBleBackend({
330
487
  deviceUuid: this.bleDeviceUuid,
331
488
  })
332
489
  }
333
490
 
334
- private static startBleBackend() {
491
+ private static startBleBackend(
492
+ onConnected?: (peripheral: NativePeripheral) => void
493
+ ) {
335
494
  return this.instance.startBleBackend({
336
495
  deviceUuid: this.bleDeviceUuid,
337
- onConnected: () => {},
496
+ onConnected: onConnected || (() => {}),
338
497
  charCallbacks: this.charCallbacks,
339
498
  })
340
499
  }
@@ -353,9 +512,11 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
353
512
  })
354
513
  }
355
514
 
356
- private static getRssiBleBackend() {
357
- return this.instance.readBleRssi({
515
+ private static setBleRssiInterval(onRssi?: (rssi: number) => void) {
516
+ return this.instance.setBleRssiInterval({
358
517
  deviceUuid: this.bleDeviceUuid,
518
+ intervalMs: this.bleRssiIntervalMs,
519
+ onRssi: onRssi ?? (() => {}),
359
520
  })
360
521
  }
361
522
 
@@ -379,6 +540,13 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
379
540
 
380
541
  private static FakeBindings(): LibndxBindings {
381
542
  return {
543
+ discover_ble_uuid: (args: any) => {
544
+ this.callsToDiscoverBle.push({
545
+ namePrefix: args[0],
546
+ onDiscovered: args[1],
547
+ })
548
+ return JSON.stringify(this.successfulResult)
549
+ },
382
550
  create_ble_backend: (args) => {
383
551
  this.callsToCreateBle.push(args)
384
552
  return JSON.stringify(this.successfulResult)
@@ -395,8 +563,12 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
395
563
  this.callsToWriteBle.push(args)
396
564
  return JSON.stringify(this.successfulResult)
397
565
  },
398
- read_ble_rssi: (args) => {
399
- this.callsToReadRssi.push(args)
566
+ set_ble_rssi_interval: (args) => {
567
+ this.callsToSetBleRssiInterval.push({
568
+ uuid: args[0],
569
+ intervalMs: args[1],
570
+ onRssi: args[2],
571
+ })
400
572
  return JSON.stringify(this.successfulResult)
401
573
  },
402
574
  stop_ble_backend: (args) => {
@@ -419,10 +591,11 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
419
591
  }
420
592
 
421
593
  private static resetCallsToFakeBindings() {
594
+ this.callsToDiscoverBle.length = 0
422
595
  this.callsToCreateBle.length = 0
423
596
  this.callsToStartBle.length = 0
424
597
  this.callsToStopBle.length = 0
425
- this.callsToReadRssi.length = 0
598
+ this.callsToSetBleRssiInterval.length = 0
426
599
  this.callsToCreateFtdi.length = 0
427
600
  this.callsToStartFtdi.length = 0
428
601
  this.callsToStopFtdi.length = 0
@@ -431,6 +604,7 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
431
604
  private static clearAndFakeFfi() {
432
605
  delete this.koffiLoadPath
433
606
  this.koffiFuncSignatures = []
607
+ this.koffiProtoCalls = []
434
608
  this.koffiStructCalls = []
435
609
  LibndxAdapter.resetKoffiCache()
436
610
  this.fakeKoffiLoad()
@@ -449,7 +623,10 @@ export default class LibndxAdapterTest extends AbstractPackageTest {
449
623
  }
450
624
 
451
625
  private static fakeKoffiProto() {
452
- LibndxAdapter.koffiProto = (() => ({})) as any
626
+ LibndxAdapter.koffiProto = ((sig: string) => {
627
+ this.koffiProtoCalls!.push(sig)
628
+ return {} as any
629
+ }) as any
453
630
  }
454
631
 
455
632
  private static fakeKoffiStruct() {
@@ -10,40 +10,9 @@ export default class LibndxAdapter implements Libndx {
10
10
 
11
11
  private static charCallbackProto?: ReturnType<typeof koffi.proto>
12
12
  private static charCallbackStruct?: ReturnType<typeof koffi.struct>
13
+ private static onDiscoveredProto?: ReturnType<typeof koffi.proto>
13
14
  private static onConnectedProto?: ReturnType<typeof koffi.proto>
14
-
15
- private static getCharCallbackProto() {
16
- if (!this.charCallbackProto) {
17
- this.charCallbackProto = LibndxAdapter.koffiProto(
18
- 'void CharCallbackFn(uint8 *data, int length, double timestamp)'
19
- )
20
- }
21
- return this.charCallbackProto
22
- }
23
-
24
- private static getOnConnectedProto() {
25
- if (!this.onConnectedProto) {
26
- this.onConnectedProto = LibndxAdapter.koffiProto(
27
- 'void OnConnectedFn()'
28
- )
29
- }
30
- return this.onConnectedProto
31
- }
32
-
33
- private static getCharCallbackStruct() {
34
- if (!this.charCallbackStruct) {
35
- this.getCharCallbackProto()
36
- this.charCallbackStruct = LibndxAdapter.koffiStruct(
37
- 'CharCallback',
38
- {
39
- charUuid: 'str',
40
- charName: 'str',
41
- onData: LibndxAdapter.koffiPointer(this.charCallbackProto!),
42
- }
43
- )
44
- }
45
- return this.charCallbackStruct
46
- }
15
+ private static onRssiProto?: ReturnType<typeof koffi.proto>
47
16
 
48
17
  private static instance?: Libndx
49
18
 
@@ -77,7 +46,9 @@ export default class LibndxAdapter implements Libndx {
77
46
  public static resetKoffiCache() {
78
47
  delete this.charCallbackProto
79
48
  delete this.charCallbackStruct
49
+ delete this.onDiscoveredProto
80
50
  delete this.onConnectedProto
51
+ delete this.onRssiProto
81
52
  }
82
53
 
83
54
  private tryToLoadBindings() {
@@ -90,7 +61,9 @@ export default class LibndxAdapter implements Libndx {
90
61
 
91
62
  private defineBindings() {
92
63
  LibndxAdapter.getCharCallbackStruct()
64
+ LibndxAdapter.getOnDiscoveredProto()
93
65
  LibndxAdapter.getOnConnectedProto()
66
+ LibndxAdapter.getOnRssiProto()
94
67
  const lib = LibndxAdapter.koffiLoad(this.libndxPath)
95
68
 
96
69
  const wrap1 = (f: (a: string) => string) => (args: [string]) =>
@@ -106,7 +79,22 @@ export default class LibndxAdapter implements Libndx {
106
79
  (args: [string, unknown, unknown, number]) =>
107
80
  f(args[0], args[1], args[2], args[3])
108
81
 
82
+ const wrapSetBleRssiInterval =
83
+ (f: (a: string, b: number, c: unknown) => string) =>
84
+ (args: [string, number, unknown]) =>
85
+ f(args[0], args[1], args[2])
86
+
87
+ const wrapDiscoverBleUuid =
88
+ (f: (a: string, b: unknown) => string) =>
89
+ (args: [string, unknown]) =>
90
+ f(args[0], args[1])
91
+
109
92
  this.bindings = {
93
+ discover_ble_uuid: wrapDiscoverBleUuid(
94
+ lib.func(
95
+ 'str discover_ble_uuid(str name_prefix, OnDiscoveredFn *on_discovered)'
96
+ )
97
+ ),
110
98
  create_ble_backend: wrap1(
111
99
  lib.func('str create_ble_backend(str config)')
112
100
  ),
@@ -120,7 +108,11 @@ export default class LibndxAdapter implements Libndx {
120
108
  'str write_ble_characteristic(str uuid, str charUuid, str value)'
121
109
  )
122
110
  ),
123
- read_ble_rssi: wrap1(lib.func('str read_ble_rssi(str uuid)')),
111
+ set_ble_rssi_interval: wrapSetBleRssiInterval(
112
+ lib.func(
113
+ 'str set_ble_rssi_interval(str uuid, int interval_ms, OnRssiFn *on_rssi)'
114
+ )
115
+ ),
124
116
  stop_ble_backend: wrap1(lib.func('str stop_ble_backend(str uuid)')),
125
117
  create_ftdi_backend: wrap1(
126
118
  lib.func('str create_ftdi_backend(str config)')
@@ -158,6 +150,22 @@ export default class LibndxAdapter implements Libndx {
158
150
  )
159
151
  }
160
152
 
153
+ public discoverBleUuid(options: DiscoverBleUuidOptions) {
154
+ const { namePrefix, onDiscovered } = options
155
+
156
+ const registeredOnDiscovered = LibndxAdapter.koffiRegister(
157
+ onDiscovered,
158
+ LibndxAdapter.koffiPointer(LibndxAdapter.getOnDiscoveredProto()!)
159
+ )
160
+
161
+ return JSON.parse(
162
+ this.bindings.discover_ble_uuid([
163
+ namePrefix,
164
+ registeredOnDiscovered,
165
+ ])
166
+ )
167
+ }
168
+
161
169
  public createBleBackend(options: BleBackendOptions) {
162
170
  const { deviceUuid } = options
163
171
  const configJson = JSON.stringify({ uuid: deviceUuid })
@@ -169,7 +177,7 @@ export default class LibndxAdapter implements Libndx {
169
177
  const { deviceUuid, onConnected, charCallbacks } = options
170
178
 
171
179
  const registeredOnConnected = LibndxAdapter.koffiRegister(
172
- onConnected,
180
+ (uuid: string, name: string) => onConnected({ uuid, name }),
173
181
  LibndxAdapter.koffiPointer(LibndxAdapter.getOnConnectedProto()!)
174
182
  )
175
183
 
@@ -208,9 +216,21 @@ export default class LibndxAdapter implements Libndx {
208
216
  )
209
217
  }
210
218
 
211
- public readBleRssi(options: BleBackendOptions) {
212
- const { deviceUuid } = options
213
- return JSON.parse(this.bindings.read_ble_rssi([deviceUuid]))
219
+ public setBleRssiInterval(options: BleRssiOptions) {
220
+ const { deviceUuid, intervalMs, onRssi } = options
221
+
222
+ const registeredOnRssi = LibndxAdapter.koffiRegister(
223
+ onRssi,
224
+ LibndxAdapter.koffiPointer(LibndxAdapter.getOnRssiProto()!)
225
+ )
226
+
227
+ return JSON.parse(
228
+ this.bindings.set_ble_rssi_interval([
229
+ deviceUuid,
230
+ intervalMs,
231
+ registeredOnRssi,
232
+ ])
233
+ )
214
234
  }
215
235
 
216
236
  public stopBleBackend(options: BleBackendOptions) {
@@ -234,13 +254,65 @@ export default class LibndxAdapter implements Libndx {
234
254
  const { serialNumber } = options
235
255
  return JSON.parse(this.bindings.stop_ftdi_backend([serialNumber]))
236
256
  }
257
+
258
+ private static getCharCallbackProto() {
259
+ if (!this.charCallbackProto) {
260
+ this.charCallbackProto = LibndxAdapter.koffiProto(
261
+ 'void CharCallbackFn(uint8 *data, int length, double timestamp)'
262
+ )
263
+ }
264
+ return this.charCallbackProto
265
+ }
266
+
267
+ private static getOnConnectedProto() {
268
+ if (!this.onConnectedProto) {
269
+ this.onConnectedProto = LibndxAdapter.koffiProto(
270
+ 'void OnConnectedFn(str uuid, str name)'
271
+ )
272
+ }
273
+ return this.onConnectedProto
274
+ }
275
+
276
+ private static getOnRssiProto() {
277
+ if (!this.onRssiProto) {
278
+ this.onRssiProto = LibndxAdapter.koffiProto(
279
+ 'void OnRssiFn(int rssi)'
280
+ )
281
+ }
282
+ return this.onRssiProto
283
+ }
284
+
285
+ private static getOnDiscoveredProto() {
286
+ if (!this.onDiscoveredProto) {
287
+ this.onDiscoveredProto = LibndxAdapter.koffiProto(
288
+ 'void OnDiscoveredFn(str uuid)'
289
+ )
290
+ }
291
+ return this.onDiscoveredProto
292
+ }
293
+
294
+ private static getCharCallbackStruct() {
295
+ if (!this.charCallbackStruct) {
296
+ this.getCharCallbackProto()
297
+ this.charCallbackStruct = LibndxAdapter.koffiStruct(
298
+ 'CharCallback',
299
+ {
300
+ charUuid: 'str',
301
+ charName: 'str',
302
+ onData: LibndxAdapter.koffiPointer(this.charCallbackProto!),
303
+ }
304
+ )
305
+ }
306
+ return this.charCallbackStruct
307
+ }
237
308
  }
238
309
 
239
310
  export interface Libndx {
311
+ discoverBleUuid(options: DiscoverBleUuidOptions): NativeResult
240
312
  createBleBackend(options: BleBackendOptions): NativeResult
241
313
  startBleBackend(options: StartBleBackendOptions): NativeResult
242
314
  writeBleCharacteristic(options: WriteBleCharacteristicOptions): NativeResult
243
- readBleRssi(options: BleBackendOptions): NativeResult
315
+ setBleRssiInterval(options: BleRssiOptions): NativeResult
244
316
  stopBleBackend(options: BleBackendOptions): NativeResult
245
317
  createFtdiBackend(options: FtdiBackendOptions): NativeResult
246
318
  startFtdiBackend(options: FtdiBackendOptions): NativeResult
@@ -253,6 +325,11 @@ export interface LibndxAdapterOptions {
253
325
  libndxPath?: string
254
326
  }
255
327
 
328
+ export interface DiscoverBleUuidOptions {
329
+ namePrefix: string
330
+ onDiscovered: (uuid: string) => void
331
+ }
332
+
256
333
  export interface BleBackendOptions {
257
334
  deviceUuid: string
258
335
  }
@@ -262,6 +339,11 @@ export interface StartBleBackendOptions extends BleBackendOptions {
262
339
  charCallbacks: CharacteristicCallback[]
263
340
  }
264
341
 
342
+ export interface BleRssiOptions extends BleBackendOptions {
343
+ intervalMs: number
344
+ onRssi: (rssi: number) => void
345
+ }
346
+
265
347
  export interface WriteBleCharacteristicOptions {
266
348
  deviceUuid: string
267
349
  charUuid: string
@@ -279,10 +361,11 @@ export interface FtdiBackendOptions {
279
361
  }
280
362
 
281
363
  export interface LibndxBindings {
364
+ discover_ble_uuid(args: [string, unknown]): string
282
365
  create_ble_backend(args: [string]): string
283
366
  start_ble_backend(args: [string, unknown, unknown, number]): string
284
367
  write_ble_characteristic(args: [string, string, string]): string
285
- read_ble_rssi(args: [string]): string
368
+ set_ble_rssi_interval(args: [string, number, unknown]): string
286
369
  stop_ble_backend(args: [string]): string
287
370
  create_ftdi_backend(args: [string]): string
288
371
  start_ftdi_backend(args: [string]): string
@@ -1,9 +1,10 @@
1
- import fs from 'fs'
1
+ import fs from 'node:fs'
2
+
3
+ import { DataType, define, open } from 'ffi-rs'
2
4
  import {
3
5
  MangledNameExtractor,
4
6
  MangledNameMap,
5
7
  } from '@neurodevs/node-mangled-names'
6
- import { DataType, define, open } from 'ffi-rs'
7
8
 
8
9
  export default class LibxdfAdapter implements Libxdf {
9
10
  public static Class?: LibxdfConstructor
@@ -6,15 +6,19 @@ import {
6
6
  LibndxAdapterOptions,
7
7
  StartBleBackendOptions,
8
8
  NativeResult,
9
+ BleRssiOptions,
10
+ DiscoverBleUuidOptions,
9
11
  } from '../../impl/LibndxAdapter.js'
10
12
 
11
13
  export default class FakeLibndx implements Libndx {
12
14
  public static callsToConstructor: (LibndxAdapterOptions | undefined)[] = []
15
+ public static callsToDiscoverBleUuid: DiscoverBleUuidOptions[] = []
13
16
  public static callsToCreateBleBackend: BleBackendOptions[] = []
14
17
  public static callsToStartBleBackend: StartBleBackendOptions[] = []
15
- public static callsToWriteBleChar: WriteBleCharacteristicOptions[] = []
18
+ public static callsToWriteBleCharacteristic: WriteBleCharacteristicOptions[] =
19
+ []
16
20
  public static callsToStopBleBackend: BleBackendOptions[] = []
17
- public static callsToGetRssiBleBackend: BleBackendOptions[] = []
21
+ public static callsToSetBleRssiInterval: BleRssiOptions[] = []
18
22
  public static callsToCreateFtdiBackend: FtdiBackendOptions[] = []
19
23
  public static callsToStartFtdiBackend: FtdiBackendOptions[] = []
20
24
  public static callsToStopFtdiBackend: FtdiBackendOptions[] = []
@@ -25,6 +29,11 @@ export default class FakeLibndx implements Libndx {
25
29
  FakeLibndx.callsToConstructor.push(options)
26
30
  }
27
31
 
32
+ public discoverBleUuid(options: DiscoverBleUuidOptions) {
33
+ FakeLibndx.callsToDiscoverBleUuid.push(options)
34
+ return FakeLibndx.fakeResult
35
+ }
36
+
28
37
  public createBleBackend(options: BleBackendOptions) {
29
38
  FakeLibndx.callsToCreateBleBackend.push(options)
30
39
  return FakeLibndx.fakeResult
@@ -36,12 +45,12 @@ export default class FakeLibndx implements Libndx {
36
45
  }
37
46
 
38
47
  public writeBleCharacteristic(options: WriteBleCharacteristicOptions) {
39
- FakeLibndx.callsToWriteBleChar.push(options)
48
+ FakeLibndx.callsToWriteBleCharacteristic.push(options)
40
49
  return FakeLibndx.fakeResult
41
50
  }
42
51
 
43
- public readBleRssi(options: BleBackendOptions) {
44
- FakeLibndx.callsToGetRssiBleBackend.push(options)
52
+ public setBleRssiInterval(options: BleRssiOptions) {
53
+ FakeLibndx.callsToSetBleRssiInterval.push(options)
45
54
  return FakeLibndx.fakeResult
46
55
  }
47
56
 
@@ -67,11 +76,12 @@ export default class FakeLibndx implements Libndx {
67
76
 
68
77
  public static resetTestDouble() {
69
78
  FakeLibndx.callsToConstructor = []
79
+ FakeLibndx.callsToDiscoverBleUuid = []
70
80
  FakeLibndx.callsToCreateBleBackend = []
71
81
  FakeLibndx.callsToStartBleBackend = []
72
- FakeLibndx.callsToWriteBleChar = []
82
+ FakeLibndx.callsToWriteBleCharacteristic = []
73
83
  FakeLibndx.callsToStopBleBackend = []
74
- FakeLibndx.callsToGetRssiBleBackend = []
84
+ FakeLibndx.callsToSetBleRssiInterval = []
75
85
  FakeLibndx.callsToCreateFtdiBackend = []
76
86
  FakeLibndx.callsToStartFtdiBackend = []
77
87
  FakeLibndx.callsToStopFtdiBackend = []