npm stats
  • Search
  • About
  • Repo
  • Sponsor
  • more
    • Search
    • About
    • Repo
    • Sponsor

Made by Antonio Ramirez

bare-bluetooth

0.2.0

@GitHub Actions

npmHomeRepoSnykSocket
Downloads:11
$ npm install bare-bluetooth
DailyWeeklyMonthlyYearly

[!IMPORTANT] This module is experimental. The API is subject to change and may break at any time.

bare-bluetooth

Bluetooth bindings for Bare. Provides BLE central and peripheral roles, GATT services and characteristics, and L2CAP channels across Apple and Android platforms.

The module normalizes API differences between platforms so consumer code does not need platform conditionals. State strings, class names, and constants are unified.

npm i bare-bluetooth

Usage

The example below shows a peripheral advertising a single writable, notifying characteristic and a central that scans, connects, subscribes, and exchanges data with it.

Peripheral:

const { TextEncoder, TextDecoder } = require('bare-encoding')
const { Server, Service, Characteristic } = require('bare-bluetooth')

const SERVICE_UUID = '01230000-0000-1000-8000-00805F9B34FB'
const CHAR_UUID = '01230001-0000-1000-8000-00805F9B34FB'

const server = new Server()
let pingChar = null

server.on('stateChange', (state) => {
  if (state !== 'poweredOn') return

  pingChar = new Characteristic(CHAR_UUID, {
    write: true,
    notify: true
  })

  server.addService(new Service(SERVICE_UUID, [pingChar]))
})

server.on('serviceAdd', (uuid) => {
  server.startAdvertising({
    name: 'MyDevice',
    serviceUUIDs: [SERVICE_UUID]
  })
})

server.on('writeRequest', (requests) => {
  const request = requests[0]
  const message = new TextDecoder().decode(request.data)

  server.respondToRequest(request, Server.ATT_SUCCESS, null)
  server.updateValue(pingChar, new TextEncoder().encode('pong: ' + message))
})

Central:

const { TextEncoder, TextDecoder } = require('bare-encoding')
const { Central } = require('bare-bluetooth')

const SERVICE_UUID = '01230000-0000-1000-8000-00805F9B34FB'
const CHAR_UUID = '01230001-0000-1000-8000-00805F9B34FB'

const central = new Central()

central.on('stateChange', (state) => {
  if (state !== 'poweredOn') return

  central.startScan([SERVICE_UUID])
})

central.on('discover', (peripheral) => {
  central.stopScan()
  central.connect(peripheral)
})

central.on('connect', (peripheral) => {
  peripheral.on('servicesDiscover', (services) => {
    for (const service of services) {
      if (service.uuid === SERVICE_UUID) {
        peripheral.discoverCharacteristics(service)
      }
    }
  })

  peripheral.on('characteristicsDiscover', (service, characteristics) => {
    for (const characteristic of characteristics) {
      if (characteristic.uuid === CHAR_UUID) {
        peripheral.subscribe(characteristic)
      }
    }
  })

  peripheral.on('notifyState', (characteristic, isNotifying) => {
    if (isNotifying) {
      peripheral.write(characteristic, new TextEncoder().encode('ping'))
    }
  })

  peripheral.on('notify', (characteristic, data) => {
    console.log('received:', new TextDecoder().decode(data))
  })

  peripheral.discoverServices([SERVICE_UUID])
})

The Apple and Android repositories include runnable variants of this flow under examples/ping-pong/.

Platforms

The package resolves to a platform-specific implementation:

  • android resolves to bare-bluetooth-android
  • darwin and ios resolve to bare-bluetooth-apple

Types

BluetoothState

A string describing the current Bluetooth adapter state.

ValuePlatforms
'unknown'Apple
'resetting'Apple
'unsupported'Apple
'unauthorized'Apple
'poweredOff'Android, Apple
'poweredOn'Android, Apple
'turningOn'Android
'turningOff'Android

API

Central

const central = new Central()

Create a new BLE central manager. The central scans for and connects to peripherals.

Properties

PropertyTypeDescription
stateBluetoothStateCurrent Bluetooth adapter state

Methods

central.startScan([serviceUUIDs[, options]])

Start scanning for peripherals. If serviceUUIDs is provided, only peripherals advertising those services will be discovered.

options = {
  scanMode: null // Android only
}

Set scanMode to one of Central.SCAN_MODE_OPPORTUNISTIC, Central.SCAN_MODE_LOW_POWER, Central.SCAN_MODE_BALANCED, or Central.SCAN_MODE_LOW_LATENCY.

central.stopScan()

Stop scanning for peripherals.

central.connect(peripheral)

Connect to a DiscoveredPeripheral.

central.disconnect(peripheral)

Disconnect from a connected Peripheral.

central.destroy()

Destroy the central manager and release all resources.

Events

EventArgumentsDescription
stateChangestate: BluetoothStateBluetooth adapter state changed
discoverperipheral: DiscoveredPeripheralA peripheral was found during scanning
connectperipheral: PeripheralConnection to a peripheral established
disconnectperipheral: Peripheral | nullA peripheral disconnected cleanly
errorerror: ErrorAn error occurred

Constants

ConstantDescription
Central.SCAN_MODE_OPPORTUNISTICScan using highest duty cycle when other apps are scanning (Android)
Central.SCAN_MODE_LOW_POWERLow power scan mode
Central.SCAN_MODE_BALANCEDBalanced scan mode
Central.SCAN_MODE_LOW_LATENCYLow latency scan mode

DiscoveredPeripheral

Represents a peripheral found during scanning. Emitted by the discover event on Central. Pass it directly to central.connect().

Properties

PropertyTypeDescription
idstringUnique identifier of the peripheral
namestring | nullAdvertised name, or null
rssinumberSignal strength in dBm
serviceData{ [uuid: string]: Uint8Array } | nullService data from advertisement, or null

Peripheral

Represents a connected peripheral. Obtained from the connect event on Central.

Properties

PropertyTypeDescription
idstringUnique identifier of the peripheral
namestring | nullAdvertised name, or null
serviceData{ [uuid: string]: Uint8Array } | nullService data, or null

Methods

peripheral.discoverServices([serviceUUIDs])

Discover services on the peripheral. On Apple, an optional serviceUUIDs array restricts discovery to those services. Android always discovers all services. Results are emitted via servicesDiscover.

peripheral.discoverCharacteristics(service[, characteristicUUIDs])

Discover characteristics for a Service. On Apple, an optional characteristicUUIDs array restricts discovery. Android always discovers all characteristics. Results are emitted via characteristicsDiscover.

peripheral.read(characteristic)

Read the value of a Characteristic. The result is emitted via read.

peripheral.write(characteristic, data[, withResponse])

Write data: Uint8Array to a Characteristic. If withResponse is true (the default), the write is confirmed by the peripheral.

peripheral.subscribe(characteristic)

Subscribe to notifications for a Characteristic.

peripheral.unsubscribe(characteristic)

Unsubscribe from notifications for a Characteristic.

peripheral.openL2CAPChannel(psm)

Open an L2CAP channel to the peripheral using the given psm: number. The result is emitted via channelOpen.

peripheral.requestMtu(mtu)

Request a new MTU size (mtu: number). The result is emitted via mtuChanged. No-op on Apple.

peripheral.destroy()

Destroy the peripheral instance and release resources.

Events

EventArgumentsDescription
servicesDiscoverservices: Service[]Services discovered
characteristicsDiscoverservice: Service | null, characteristics: Characteristic[]Characteristics discovered for a service
readcharacteristic: Characteristic, data: Uint8ArrayCharacteristic value read
writecharacteristic: CharacteristicCharacteristic write completed
notifycharacteristic: Characteristic, data: Uint8ArrayNotification received
notifyStatecharacteristic: Characteristic, isNotifying: booleanNotification state changed
channelOpenchannel: L2CAPChannelL2CAP channel opened
errorerror: ErrorAn error occurred
EventArgumentsPlatform
disconnect(none)Android
mtuChangedmtu: numberAndroid

Constants

ConstantValue
Peripheral.PROPERTY_READ0x02
Peripheral.PROPERTY_WRITE_WITHOUT_RESPONSE0x04
Peripheral.PROPERTY_WRITE0x08
Peripheral.PROPERTY_NOTIFY0x10
Peripheral.PROPERTY_INDICATE0x20

Server

const server = new Server()

Create a new BLE peripheral manager (server). The server advertises services and handles read/write requests from centrals.

Properties

PropertyTypeDescription
stateBluetoothStateCurrent Bluetooth adapter state

Methods

server.addService(service)

Add a Service to the GATT server. The serviceAdd event is emitted when the service has been registered.

server.startAdvertising([options])

Start advertising the server.

options = {
  name: null,
  serviceUUIDs: null,
  serviceData: null // Apple only
}

server.stopAdvertising()

Stop advertising.

server.respondToRequest(request, result[, data])

Respond to a ReadRequest or WriteRequest with the given ATT result: number code. Optionally include data: Uint8Array for read responses. Use the Server.ATT_* constants for result.

server.updateValue(characteristic, data)

Update the value of a Characteristic and notify subscribed centrals. data is a Uint8Array. Returns true if the update was sent successfully.

server.publishChannel([options])

Publish an L2CAP channel. The channelPublish event is emitted with the assigned PSM.

options = {
  encrypted: false
}

server.unpublishChannel(psm)

Unpublish a previously published L2CAP channel identified by psm: number.

server.destroy()

Destroy the server and release all resources.

Events

EventArgumentsDescription
stateChangestate: BluetoothStateBluetooth adapter state changed
serviceAdduuid: stringService registered
readRequestrequest: ReadRequestCentral read a characteristic
writeRequestrequests: WriteRequest[]Central wrote to a characteristic
subscribepeer: unknown, characteristicUuid: stringCentral subscribed to notifications
unsubscribepeer: unknown, characteristicUuid: stringCentral unsubscribed from notifications
errorerror: ErrorAn error occurred
channelPublishpsm: numberL2CAP channel published
channelOpenchannel: L2CAPChannelL2CAP channel opened by a central
EventArgumentsPlatform
connectingdeviceAddress: stringAndroid
connecteddeviceAddress: stringAndroid
disconnectingdeviceAddress: stringAndroid
disconnecteddeviceAddress: stringAndroid
notifySentdeviceAddress: string, status: numberAndroid
readyToUpdate(none)Apple

Constants

State

ConstantValue
Server.STATE_UNKNOWN0
Server.STATE_RESETTING1
Server.STATE_UNSUPPORTED2
Server.STATE_UNAUTHORIZED3
Server.STATE_POWERED_OFF4
Server.STATE_POWERED_ON5

Connection state (Android)

ConstantValue
Server.CONNECTION_STATE_DISCONNECTED0
Server.CONNECTION_STATE_CONNECTING1
Server.CONNECTION_STATE_CONNECTED2
Server.CONNECTION_STATE_DISCONNECTING3

Properties

ConstantValue
Server.PROPERTY_READ0x02
Server.PROPERTY_WRITE_WITHOUT_RESPONSE0x04
Server.PROPERTY_WRITE0x08
Server.PROPERTY_NOTIFY0x10
Server.PROPERTY_INDICATE0x20

Permissions

ConstantValue
Server.PERMISSION_READABLE0x01
Server.PERMISSION_WRITEABLE0x02
Server.PERMISSION_READ_ENCRYPTED0x04
Server.PERMISSION_WRITE_ENCRYPTED0x08

ATT result codes

ConstantValue
Server.ATT_SUCCESS0x00
Server.ATT_INVALID_HANDLE0x01
Server.ATT_READ_NOT_PERMITTED0x02
Server.ATT_WRITE_NOT_PERMITTED0x03
Server.ATT_INSUFFICIENT_RESOURCES0x11
Server.ATT_UNLIKELY_ERROR0x0E

ReadRequest

Represents a read request from a central. Emitted by the readRequest event on Server. Pass it directly to server.respondToRequest().

Properties

PropertyTypeDescription
characteristicUuidstringUUID of the characteristic being read
offsetnumberByte offset for the read

WriteRequest

Represents a write request from a central. Emitted as an array by the writeRequest event on Server. Pass it directly to server.respondToRequest().

Properties

PropertyTypeDescription
characteristicUuidstringUUID of the characteristic being written
offsetnumberByte offset for the write
dataUint8ArrayData being written
responseNeededbooleanWhether the central expects a response

L2CAPChannel

An L2CAP connection-oriented channel. Obtained through the channelOpen event on Server or Peripheral. Extends Duplex from bare-stream and supports standard readable and writable stream operations.

Properties

PropertyTypeDescription
psmnumberProtocol/Service Multiplexer number
peerstring | nullPeer identifier, or null

Service

const service = new Service(uuid[, characteristics[, options]])

Create a GATT service definition.

ParameterTypeDefaultDescription
uuidstringService UUID
characteristicsCharacteristic[][]Characteristics for this service
options.primarybooleantrueWhether this is a primary service

Properties

PropertyTypeDescription
uuidstringUUID of the service
characteristicsCharacteristic[]Characteristics belonging to the service
primarybooleanWhether this is a primary service

Characteristic

const characteristic = new Characteristic(uuid[, options])

Create a GATT characteristic definition.

ParameterTypeDefaultDescription
uuidstringCharacteristic UUID
options.readbooleanfalseEnable read property
options.writebooleanfalseEnable write property
options.writeWithoutResponsebooleanfalseEnable write-without-response property
options.notifybooleanfalseEnable notify property
options.indicatebooleanfalseEnable indicate property
options.permissionsnumber | nullnullExplicit permission bitmask. If null, inferred from properties
options.valueUint8Array | nullnullStatic value

Properties

PropertyTypeDescription
uuidstringUUID of the characteristic
propertiesnumberBitmask of characteristic properties
permissionsnumber | nullBitmask of permissions, or null if inferred
valueUint8Array | nullStatic value (read/write)

Constants

ConstantValue
Characteristic.PROPERTY_READ0x02
Characteristic.PROPERTY_WRITE_WITHOUT_RESPONSE0x04
Characteristic.PROPERTY_WRITE0x08
Characteristic.PROPERTY_NOTIFY0x10
Characteristic.PROPERTY_INDICATE0x20

License

Apache-2.0