From 9879cfa171b79698ba2503a0f72e07e6b61c8259 Mon Sep 17 00:00:00 2001 From: Roman Lupol Date: Sun, 24 Jan 2021 17:25:29 +0100 Subject: [PATCH] writeValue - options improvements (#20) * improved write value options and added type param * updated readme for writeValue * WriteValue method improved for backward compatible --- README.md | 2 +- src/GattCharacteristic.js | 15 ++++++++++----- src/index.d.ts | 7 ++++++- test/GattCharacteristic.spec.js | 19 ++++++++++++++++++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 48f600b..4a7e619 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ const {bluetooth, destroy} = createBluetooth() | `Promise getFlags()` | Defines how the characteristic value can be used. | | `Promise isNotifying()` | True, if notifications or indications on this characteristic are currently enabled. | | `Promise readValue(Number offset = 0)` | Issues a request to read the value of the characteristic and returns the value if the operation was successful. | -| `Promise writeValue(Buffer buffer, Number offset = 0)` | Issues a request to write the value of the characteristic. | +| `Promise writeValue(Buffer buffer, Number | WriteValueOptions options = {})` | Issues a request to write the value of the characteristic. Default options `{ offset: 0, type: 'reliable' }`. | | `Promise startNotifications()` | Starts a notification session from this characteristic if it supports value notifications or indications. | | `Promise stopNotifications()` | This method will cancel any previous StartNotify transaction. | | `Promise toString()` | User friendly characteristic name. | diff --git a/src/GattCharacteristic.js b/src/GattCharacteristic.js index 8a7edaf..b101e54 100644 --- a/src/GattCharacteristic.js +++ b/src/GattCharacteristic.js @@ -33,16 +33,21 @@ class GattCharacteristic extends EventEmitter { return Buffer.from(payload) } - async writeValue (value, offset = 0) { + async writeValue (value, optionsOrOffset = {}) { if (!Buffer.isBuffer(value)) { throw new Error('Only buffers can be wrote') } - const options = { - offset: buildTypedValue('uint16', offset), - type: buildTypedValue('string', 'reliable') + + const options = typeof optionsOrOffset === 'number' ? { offset: optionsOrOffset } : optionsOrOffset + const mergedOptions = Object.assign({ offset: 0, type: 'reliable' }, options) + + const callOptions = { + offset: buildTypedValue('uint16', mergedOptions.offset), + type: buildTypedValue('string', mergedOptions.type) } + const { data } = value.toJSON() - await this.helper.callMethod('WriteValue', data, options) + await this.helper.callMethod('WriteValue', data, callOptions) } async startNotifications () { diff --git a/src/index.d.ts b/src/index.d.ts index 7df0863..06f51da 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -6,7 +6,7 @@ declare namespace NodeBle { getFlags(): Promise; isNotifying(): Promise; readValue(offset?: number): Promise; - writeValue(buffer: Buffer, offset?: number): Promise; + writeValue(buffer: Buffer, optionsOrOffset?: number | WriteValueOptions): Promise; startNotifications(): Promise; stopNotifications(): Promise; toString(): Promise; @@ -75,6 +75,11 @@ declare namespace NodeBle { destroy(): void; bluetooth: Bluetooth; }; + + interface WriteValueOptions { + offset?: number; + type?: 'reliable' | 'request' | 'command'; + } } export = NodeBle; diff --git a/test/GattCharacteristic.spec.js b/test/GattCharacteristic.spec.js index 4237e7b..5751287 100644 --- a/test/GattCharacteristic.spec.js +++ b/test/GattCharacteristic.spec.js @@ -16,6 +16,7 @@ jest.doMock('../src/BusHelper', () => { } } }) +const buildTypedValue = require('../src/buildTypedValue') const GattCharacteristic = require('../src/GattCharacteristic') const dbus = Symbol('dbus') @@ -35,10 +36,26 @@ test('props', async () => { test('read/write', async () => { const characteristic = new GattCharacteristic(dbus, 'hci0', 'dev_00_00_00_00_00_00', 'characteristic0006', 'char008') + const writeValueOptions = (offset = 0, type = 'reliable') => { + return { offset: buildTypedValue('uint16', offset), type: buildTypedValue('string', type) } + } await expect(characteristic.writeValue('not_a_buffer')).rejects.toThrow('Only buffers can be wrote') + + await expect(characteristic.writeValue(Buffer.from('hello'), 5)).resolves.toBeUndefined() + expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), writeValueOptions(5)) + await expect(characteristic.writeValue(Buffer.from('hello'))).resolves.toBeUndefined() - expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), expect.anything()) + expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), writeValueOptions()) + + await expect(characteristic.writeValue(Buffer.from('hello'), { type: 'command' })).resolves.toBeUndefined() + expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), writeValueOptions(0, 'command')) + + await expect(characteristic.writeValue(Buffer.from('hello'), { offset: 9, type: 'request' })).resolves.toBeUndefined() + expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), writeValueOptions(9, 'request')) + + await expect(characteristic.writeValue(Buffer.from('hello'), 'incorrect argument')).resolves.toBeUndefined() + expect(characteristic.helper.callMethod).toHaveBeenCalledWith('WriteValue', expect.anything(), writeValueOptions()) characteristic.helper.callMethod.mockResolvedValueOnce([255, 100, 0]) await expect(characteristic.readValue()).resolves.toEqual(Buffer.from([255, 100, 0]))