npm package: @particle/device-control-ble
Description: A library for controlling Particle devices over BLE
Author: Particle Industries, Inc.
Latest version: 0.2.6

# @particle/device-control-ble

A library for controlling Particle devices over BLE.


## Installation

```shell
npm install @particle/device-control-ble @particle/device-constants --save
```

_NOTE: `@particle/device-control-ble` declares `@particle/device-constants` as a [`peerDependency`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#peerdependencies) - this ensures your app only ever has one copy of that dependency_

<!-- private-module-note-start -->

<!-- private-module-note-end -->


## API
<!-- api-docs-start -->
<a name="BleControlRequestChannel"></a>

### BleControlRequestChannel
A class implementing the Device OS control request protocol for BLE.

**Kind**: global class  

* [BleControlRequestChannel](#BleControlRequestChannel)
    * [new BleControlRequestChannel(options)](#new_BleControlRequestChannel_new)
    * [.state](#BleControlRequestChannel+state) : <code>String</code>
    * [.open()](#BleControlRequestChannel+open) ⇒ <code>Promise</code>
    * [.close()](#BleControlRequestChannel+close)


* * *

<a name="new_BleControlRequestChannel_new"></a>

#### new BleControlRequestChannel(options)
Constructor.


| Param | Type | Default | Description |
| --- | --- | --- | --- |
| options | <code>Object</code> |  | Options. |
| options.stream | <code>Object</code> |  | Transport stream.        The stream object is expected to behave similarly to a Node's `stream.Duplex` in flowing        mode.        The only method of the `stream.Duplex` interface that has to be implemented by the stream        is `write()`. The method's callback argument and return value are not used. All writes        must be buffered by the stream.        The channel will add listeners for the following stream events: `data`, `end`, `finish`,        `close`, `error`. Half-closed streams are not supported, meaning that an `end` or a        `finish` event emitted by the stream will result in the channel being closed immediately. |
| options.secret | <code>String</code> \| <code>Uint8Array</code> |  | Device secret. |
| [options.concurrentRequests] | <code>Number</code> | <code>1</code> | Maximum number of requests that can be sent to        the device concurrently. Requests attempted to be sent above this limit will be queued. |
| [options.requestTimeout] | <code>Number</code> | <code>60000</code> | Default request timeout in milliseconds. |
| [options.handshakeTimeout] | <code>Number</code> | <code>10000</code> | Handshake timeout in milliseconds. |
| [options.env] | [<code>Env</code>](#Env) | <code>defaultEnv()</code> | Environment-specific functions. |


* * *

<a name="BleControlRequestChannel+state"></a>

#### bleControlRequestChannel.state : <code>String</code>
Channel state.

Possible values are `new`, `opening`, `open` and `closed`.

**Kind**: instance property of [<code>BleControlRequestChannel</code>](#BleControlRequestChannel)  

* * *

<a name="BleControlRequestChannel+open"></a>

#### bleControlRequestChannel.open() ⇒ <code>Promise</code>
Open the channel and initiate a handshake with the device.

An `open` event will be emitted when the channel is open. Requests can still be enqueued for
sending via `sendRequest()` while the channel is being opened.

The transport stream and the underlying BLE characteristics must be in a readable and writable
state by the time this method is called.

A closed channel cannot be reopened.

**Kind**: instance method of [<code>BleControlRequestChannel</code>](#BleControlRequestChannel)  

* * *

<a name="BleControlRequestChannel+close"></a>

#### bleControlRequestChannel.close()
Close the channel.

A `closed` event will be emitted when the channel is closed. All pending requests will be
rejected with an error.

**Kind**: instance method of [<code>BleControlRequestChannel</code>](#BleControlRequestChannel)  

* * *

<a name="BleCharacteristic"></a>

### BleCharacteristic
A base class for a BLE characteristic.

**Kind**: global class  
**Emits**: [<code>data</code>](#BleCharacteristic+event_data), [<code>error</code>](#BleCharacteristic+event_error)  

* [BleCharacteristic](#BleCharacteristic)
    * [.uuid](#BleCharacteristic+uuid) : <code>String</code>
    * [.read()](#BleCharacteristic+read) ⇒ <code>Promise.&lt;Uint8Array&gt;</code>
    * [.write(data, [options])](#BleCharacteristic+write) ⇒ <code>Promise</code>
    * [.enableNotifications()](#BleCharacteristic+enableNotifications) ⇒ <code>Promise</code>
    * [.disableNotifications()](#BleCharacteristic+disableNotifications) ⇒ <code>Promise</code>
    * ["data"](#BleCharacteristic+event_data)
    * ["error"](#BleCharacteristic+event_error)


* * *

<a name="BleCharacteristic+uuid"></a>

#### bleCharacteristic.uuid : <code>String</code>
Characteristic UUID.

**Kind**: instance property of [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleCharacteristic+read"></a>

#### bleCharacteristic.read() ⇒ <code>Promise.&lt;Uint8Array&gt;</code>
Read the current value of the characteristic.

**Kind**: instance method of [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleCharacteristic+write"></a>

#### bleCharacteristic.write(data, [options]) ⇒ <code>Promise</code>
Write to the characteristic.

**Kind**: instance method of [<code>BleCharacteristic</code>](#BleCharacteristic)  

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| data | <code>Uint8Array</code> |  | Data to write. |
| [options] | <code>Object</code> |  | Options. |
| [options.withoutResponse] | <code>Boolean</code> | <code>false</code> | Whether to write with or without a response. |


* * *

<a name="BleCharacteristic+enableNotifications"></a>

#### bleCharacteristic.enableNotifications() ⇒ <code>Promise</code>
Enable notifications for this characteristic.

**Kind**: instance method of [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleCharacteristic+disableNotifications"></a>

#### bleCharacteristic.disableNotifications() ⇒ <code>Promise</code>
Disable notifications for this characteristic.

**Kind**: instance method of [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleCharacteristic+event_data"></a>

#### "data"
An event emitted when the peripheral indicates that the characteristic has changed.

In order to start receiving these events, notifications for the characteristic need to be
enabled via [enableNotifications](#BleCharacteristic+enableNotifications).

**Kind**: event emitted by [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleCharacteristic+event_error"></a>

#### "error"
An event emitted when an error occurs.

**Kind**: event emitted by [<code>BleCharacteristic</code>](#BleCharacteristic)  

* * *

<a name="BleService"></a>

### BleService
A base class for a BLE service.

**Kind**: global class  

* [BleService](#BleService)
    * [.uuid](#BleService+uuid) : <code>String</code>
    * [.getCharacteristics()](#BleService+getCharacteristics) ⇒ <code>Promise.&lt;Array.&lt;BleCharacteristic&gt;&gt;</code>


* * *

<a name="BleService+uuid"></a>

#### bleService.uuid : <code>String</code>
Service UUID.

**Kind**: instance property of [<code>BleService</code>](#BleService)  

* * *

<a name="BleService+getCharacteristics"></a>

#### bleService.getCharacteristics() ⇒ <code>Promise.&lt;Array.&lt;BleCharacteristic&gt;&gt;</code>
Get the characteristics of this service.

**Kind**: instance method of [<code>BleService</code>](#BleService)  

* * *

<a name="BlePeripheral"></a>

### BlePeripheral
A base class for a BLE peripheral device.

**Kind**: global class  
**Emits**: [<code>connect</code>](#BlePeripheral+event_connect), [<code>disconnect</code>](#BlePeripheral+event_disconnect), [<code>error</code>](#BlePeripheral+event_error)  

* [BlePeripheral](#BlePeripheral)
    * [.name](#BlePeripheral+name) : <code>String</code>
    * [.manufacturerData](#BlePeripheral+manufacturerData) : <code>Uint8Array</code>
    * [.mtu](#BlePeripheral+mtu) : <code>Number</code>
    * [.connect()](#BlePeripheral+connect) ⇒ <code>Promise</code>
    * [.disconnect()](#BlePeripheral+disconnect) ⇒ <code>Promise</code>
    * [.getServices()](#BlePeripheral+getServices) ⇒ <code>Promise.&lt;Array.&lt;BleService&gt;&gt;</code>
    * ["connect"](#BlePeripheral+event_connect)
    * ["disconnect"](#BlePeripheral+event_disconnect)
    * ["error"](#BlePeripheral+event_error)


* * *

<a name="BlePeripheral+name"></a>

#### blePeripheral.name : <code>String</code>
Peripheral name.

**Kind**: instance property of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+manufacturerData"></a>

#### blePeripheral.manufacturerData : <code>Uint8Array</code>
Advertised manufacturer data.

If present, the manufacturer data is expected to start with a 2-byte company ID.

**Kind**: instance property of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+mtu"></a>

#### blePeripheral.mtu : <code>Number</code>
ATT MTU of the current established connection.

If defined, the value must be greater than or equal to 23, which is the minimum supported ATT
MTU.

**Kind**: instance property of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+connect"></a>

#### blePeripheral.connect() ⇒ <code>Promise</code>
Connect to the peripheral.

**Kind**: instance method of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+disconnect"></a>

#### blePeripheral.disconnect() ⇒ <code>Promise</code>
Disconnect from the peripheral.

**Kind**: instance method of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+getServices"></a>

#### blePeripheral.getServices() ⇒ <code>Promise.&lt;Array.&lt;BleService&gt;&gt;</code>
Get the services of this peripheral.

**Kind**: instance method of [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+event_connect"></a>

#### "connect"
An event emitted when the host has connected to the peripheral.

**Kind**: event emitted by [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+event_disconnect"></a>

#### "disconnect"
An event emitted when the host has disconnected from the peripheral.

**Kind**: event emitted by [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BlePeripheral+event_error"></a>

#### "error"
An event emitted when an error occurs.

**Kind**: event emitted by [<code>BlePeripheral</code>](#BlePeripheral)  

* * *

<a name="BleManager"></a>

### BleManager
A base class for a BLE manager.

**Kind**: global class  

* [BleManager](#BleManager)
    * [new BleManager()](#new_BleManager_new)
    * [.getDevices([options])](#BleManager+getDevices) ⇒ <code>Promise.&lt;Array.&lt;BlePeripheral&gt;&gt;</code>
    * [.destroy()](#BleManager+destroy) ⇒ <code>Promise</code>


* * *

<a name="new_BleManager_new"></a>

#### new BleManager()
Constructor.


* * *

<a name="BleManager+getDevices"></a>

#### bleManager.getDevices([options]) ⇒ <code>Promise.&lt;Array.&lt;BlePeripheral&gt;&gt;</code>
Scan for available peripherals.

If filtering options, such as `names` or `services`, are provided, a discovered peripheral will
only be reported by this method if it satisfies all of the filtering options.

Only one scan can be active at a time.

**Kind**: instance method of [<code>BleManager</code>](#BleManager)  
**Returns**: <code>Promise.&lt;Array.&lt;BlePeripheral&gt;&gt;</code> - Discovered peripherals.  

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> |  | Options. |
| [options.names] | <code>Array.&lt;(String\|RegExp)&gt;</code> |  | Peripheral names. |
| [options.services] | <code>Array.&lt;String&gt;</code> |  | Service UUIDs. |
| [options.count] | <code>Number</code> |  | Maximum number of peripherals to scan for. |
| [options.timeout] | <code>Number</code> | <code>5000</code> | Maximum duration of the scan in milliseconds. |


* * *

<a name="BleManager+destroy"></a>

#### bleManager.destroy() ⇒ <code>Promise</code>
Shut down the BLE manager.

Calling this method will interrupt the ongoing scan process and close all connections with
peripherals with an error.

**Kind**: instance method of [<code>BleManager</code>](#BleManager)  

* * *

<a name="Aes128Cipher"></a>

### Aes128Cipher
A base class for an AES-128 cipher operating in ECB mode.

**Kind**: global class  

* * *

<a name="Aes128Cipher+encryptBlock"></a>

#### aes128Cipher.encryptBlock(block) ⇒ <code>Promise.&lt;Uint8Array&gt;</code>
Encrypt a single block of data.

**Kind**: instance method of [<code>Aes128Cipher</code>](#Aes128Cipher)  
**Returns**: <code>Promise.&lt;Uint8Array&gt;</code> - Ciphertext block.  

| Param | Type | Description |
| --- | --- | --- |
| block | <code>Uint8Array</code> | Plaintext block. The block must be 16 bytes long. |


* * *

<a name="Env"></a>

### Env
A base class defining environment-specific functions used by the library.

**Kind**: global class  

* [Env](#Env)
    * [.createAes128Cipher(key)](#Env+createAes128Cipher) ⇒ [<code>Aes128Cipher</code>](#Aes128Cipher)
    * [.getRandomBytes(size)](#Env+getRandomBytes) ⇒ <code>Promise.&lt;Uint8Array&gt;</code>


* * *

<a name="Env+createAes128Cipher"></a>

#### env.createAes128Cipher(key) ⇒ [<code>Aes128Cipher</code>](#Aes128Cipher)
Create an AES-128 cipher operating in ECB mode.

**Kind**: instance method of [<code>Env</code>](#Env)  
**Returns**: [<code>Aes128Cipher</code>](#Aes128Cipher) - Cipher object.  

| Param | Type | Description |
| --- | --- | --- |
| key | <code>Uint8Array</code> | Encryption key. The key must be 16 bytes long. |


* * *

<a name="Env+getRandomBytes"></a>

#### env.getRandomBytes(size) ⇒ <code>Promise.&lt;Uint8Array&gt;</code>
Generate cryptographically strong random data.

**Kind**: instance method of [<code>Env</code>](#Env)  
**Returns**: <code>Promise.&lt;Uint8Array&gt;</code> - Random data.  

| Param | Type | Description |
| --- | --- | --- |
| size | <code>Number</code> | Number of bytes to generate. |


* * *

<a name="DEFAULT_BLE_SCAN_TIMEOUT"></a>

### DEFAULT\_BLE\_SCAN\_TIMEOUT
Default timeout of a BLE scan.

**Kind**: global constant  

* * *

<a name="defaultEnv"></a>

### defaultEnv() ⇒ [<code>Env</code>](#Env)
Get the default environment-specific functions.

**Kind**: global function  

* * *

<a name="Response"></a>

### Response ⇒ [<code>Promise.&lt;Response&gt;</code>](#Response)
Send a request to the device.

**Kind**: global typedef  

| Param | Type | Description |
| --- | --- | --- |
| type | <code>Number</code> | Request type. See system_control.h in Device OS for the list of defined        request types. |
| [data] | <code>Uint8Array</code> | Request payload data. |
| [options] | <code>Object</code> | Options. |
| [options.timeout] | <code>Number</code> | Request timeout in milliseconds. If not specified, the        default timeout configured at construction time will be used. |

**Properties**

| Name | Type | Description |
| --- | --- | --- |
| result | <code>Number</code> | Result code. See system_error.h in Device OS for the list of defined           result codes. |
| data | <code>Uint8Array</code> | Response payload data. |


* * *


<!-- api-docs-end -->

_NOTE: Unfortunately, docs have a nasty habit of falling out of date. When in doubt, check usage in [tests](./src/index.test.js)_