Skip to content

imranj131/advlib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

advlib

Library for wireless advertising packet decoding. Currently supports the following protocols:

Installation

npm install advlib

Hello advlib

var advlib = require('advlib');

var rawHexPacket = '421655daba50e1fe0201050c097265656c79416374697665';
var processedPacket = advlib.ble.process(rawHexPacket);

console.log(JSON.stringify(processedPacket, null, " "));

The console output should appear as follows:

{
  type: "ADVA-48",
  value: "fee150bada55",
  advHeader: { 
    type: "ADV_NONCONNECT_IND",
    length: 22,
    txAdd: "random",
    rxAdd: "public" 
  },
  advData: {
    flags: [ "LE Limited Discoverable Mode", "BR/EDR Not Supported" ],
    completeLocalName: "reelyActive" 
  } 
}

Bluetooth Smart (BLE) Advertising Packet Library

Process a raw packet (as a hexadecimal string) with the following command:

advlib.ble.process(rawHexPacket);

The library is organised hierarchically so that the separate elements of a packet can be processed individually. Refer to the index below for details on each element:

Header

Process a 16-bit header (as a hexadecimal string) with the following command:

advlib.ble.header.process(rawHexHeader);

For reference, the 16-bit header is as follows (reading the hexadecimal string from left to right):

Bit(s) Function
15 RxAdd: 0 = public, 1 = random
14 TxAdd: 0 = public, 1 = random
13-12 Reserved for Future Use (RFU)
11-8 Type (see table below)
7-6 Reserved for Future Use (RFU)
5-0 Payload length in bytes

And the advertising packet types are as follows:

Type Packet Purpose
0 ADV_IND Connectable undirected advertising
1 ADV_DIRECT_IND Connectable directed advertising
2 ADV_NONCONN_IND Non-connectable undirected advertising
3 SCAN_REQ Scan for more info from advertiser
4 SCAN_RSP Response to scan request from scanner
5 CONNECT_REQ Request to connect
6 ADV_DISCOVER_IND Scannable undirected advertising

For example:

advlib.ble.header.process('4216');

would yield:

{
  rxAdd: "public",
  txAdd: "random",
  type: "ADV_NONCONNECT_IND",
  length: 22
}

Address

Process a 48-bit address (as a hexadecimal string) with the following command:

advlib.ble.address.process(rawHexAddress);

For reference, the 48-bit header is as follows (reading the hexadecimal string from left to right):

Bit(s) Address component
47-40 xx:xx:xx:xx:xx:##
39-32 xx:xx:xx:xx:##:xx
31-24 xx:xx:xx:##:xx:xx
23-16 xx:xx:##:xx:xx:xx
15-8 xx:##:xx:xx:xx:xx
7-0 ##:xx:xx:xx:xx:xx

This is best illustrated with an example:

advlib.ble.address.process('0123456789ab');

Would yield:

{
  type: "ADVA-48",
  value: "ab8967452301"
}

which can alternatively be represented as ab:89:67:45:23:01.

Data (Generic Access Profile)

Process GAP data (as a hexadecimal string) with the following command:

advlib.ble.data.process(rawHexData);

For reference, the structure of the data is as follows:

Byte(s) Data component
0 Length of the data in bytes (including type and data)
1 GAP Data Type (see table below)
2 to length Type-specifc data

The Generic Access Profile Data Types are listed on the Bluetooth GAP Assigned Numbers website. The following table lists the Data Types, their names and the section in this document in which they are described.

Data Type Data Type Name See advlib section
0x01 Flags Flags
0x02 Incomplete List of 16-bit UUIDs UUID
0x03 Complete List of 16-bit UUIDs UUID
0x04 Incomplete List of 32-bit UUIDs UUID
0x05 Complete List of 32-bit UUIDs UUID
0x06 Incomplete List of 128-bit UUIDs UUID
0x07 Complete List of 128-bit UUIDs UUID
0x08 Shortened Local Name Local Name
0x09 Complete Local Name Local Name
0x0a Tx Power Level Tx Power
0x0d Class of Device Generic Data
0x0e Simple Pairing Hash C-192 Generic Data
0x0f Simple Pairing Randomizer R-192 Generic Data
0x10 Security Manager TK Value Generic Data
0x11 Security Manager OOB Flags Generic Data
0x12 Slave Connection Interval Range SCIR
0x14 16-bit Solicitation UUIDs Solicitation
0x15 128-bit Solicitation UUIDs Solicitation
0x16 Service Data 16-bit UUID Service Data
0x17 Public Target Address Generic Data
0x18 Random Target Address Generic Data
0x19 Public Target Address Generic Data
0x1a Advertising Interval Generic Data
0x1b LE Bluetooth Device Address Generic Data
0x1c LE Bluetooth Role Generic Data
0x1d Simple Pairing Hash C-256 Generic Data
0x1e Simple Pairing Hash Randomizer C-256 Generic Data
0x1f 32-bit Solicitation UUIDs Solicitation
0x20 Service Data 32-bit UUID Service Data
0x21 Service Data 128-bit UUID Service Data
0x3d 3-D Information Data Generic Data
0xff Manufacturer Specific Data Mfr. Specific Data

UUID

Process a UUID assigned to the device with any of the following commands:

advlib.ble.data.gap.uuid.nonComplete16BitUUIDs(payload, cursor, advertiserData);
advlib.ble.data.gap.uuid.complete16BitUUIDs(payload, cursor, advertiserData);
advlib.ble.data.gap.uuid.nonComplete128BitUUIDs(payload, cursor, advertiserData);
advlib.ble.data.gap.uuid.complete128BitUUIDs(payload, cursor, advertiserData);

This is best illustrated with an example:

var payload = '16074449555520657669746341796c656572';
advlib.ble.data.gap.uuid.complete128BitUUIDs(payload, 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 16 Length, in bytes, of type and data
1 07 GAP Data Type for Complete 128-bit UUID
2 to 16 4449555520657669746341796c656572 reelyActive's 128-bit UUID

Which would add the following property to advData:

complete128BitUUIDs: "7265656c794163746976652055554944"

Local Name

Process the device's local name, complete or shortened, with the following commands, respectively:

advlib.ble.data.gap.localname.completeLocalName(payload, cursor, advertiserData);
advlib.ble.data.gap.localname.shortenedLocalName(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.localname.completeLocalName('12097265656c79416374697665', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 12 Length, in bytes, of type and data
1 09 GAP Data Type for Complete Local Name
2 to 12 7265656c79416374697665 ASCII representation of 'reelyActive'

Which would add the following property to advData:

completeLocalName: "reelyActive"

Flags

Process the flags with the following command:

advlib.ble.data.gap.flags.process(payload, cursor, advertiserData);

For reference, the flags are as follows:

Bit Description
0 LE Limited Discoverable Mode
1 LE General Discoverable Mode
2 BR/EDR Not Supported
3 Simultaneous LE and BR/EDR to Same Device Capable (Controller)
4 Simultaneous LE and BR/EDR to Same Device Capable (Host)
5 Reserved

This is best illustrated with an example:

advlib.ble.data.gap.flags.process('020104', 0, {});

For reference, the example payload is interpreted as follows:

Byte Hex String Description
0 02 Length, in bytes, of type and data
1 01 GAP Data Type for flags
2 04 See table above

Which would add the following property to advData:

flags: [ "BR/EDR Not Supported" ]

Manufacturer Specific Data

Process manufacturer specific data with the following command:

advlib.ble.data.gap.manufacturerspecificdata.process(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.manufacturerspecificdata.process('03ff8c00', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 03 Length, in bytes, of type and data
1 ff GAP Data Type for manufacturer specific data
2-3 8c00 Gimbal company identifier code (bytes reversed)

Which would add the following property to advData:

manufacturerSpecificData: {
  companyIdentifierCode: "008c",
  data: ""
}
iBeacon

A specific case of manufacturer specific data is the iBeacon:

var payload = '26ff4c000215b9407f30f5f8466eaff925556b57fe6d294c903974';
advlib.ble.data.gap.manufacturerspecificdata.process(payload, 0, {});

For reference, the iBeacon payload is interpreted as follows:

Byte(s) Hex String Description
0 26 Length, in bytes, of type and data
1 ff GAP Data Type for manufacturer specific data
2-3 4c00 Apple company identifier code (bytes reversed)
4-5 0215 Identifier code for iBeacon
6-21 b9407f30f5f8466eaff925556b57fe6d UUID (assigned by Apple)
21-22 294c Major
23-24 9039 Minor
25 74 TxPower (see TxPower section)

Which would add the following property to advData:

manufacturerSpecificData: {
  iBeacon: {
    uuid: "b9407f30f5f8466eaff925556b57fe6d",
    major: "294c",
    minor: "9039",
    txPower: "116dBm"
  }
}

TX Power Level

Process Tx Power Level with the following command:

advlib.ble.data.gap.txpower.process(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.txpower.process('020a7f', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 02 Length, in bytes, of type and data
1 0a GAP Data Type for TxPower
2 7f TxPower (see table below)

TxPower is a two's complement value which is interpreted as follows:

Hex String Power dBm
7f 127 dBm
00 0 dBm
ff -128 dBm

Which would add the following property to advData:

manufacturerSpecificData: {
  iBeacon: {
    txPower: "127dBm"
  }
}

Slave Connection Interval Range

Process the Slave Connection Interval Range with the following command:

advlib.ble.data.gap.slaveconnectionintervalrange.process(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.slaveconnectionintervalrange.process('061200060c80', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 06 Length, in bytes, of type and data
1 12 GAP Data Type for Slave Connection Interval Range
2-6 00060c80 Min and max intervals (see table below)

And the intervals are intepreted as follows:

Byte(s) Hex String Description
0-1 0006 Min interval = 6 x 1.25 ms = 7.5 ms
2-3 0c80 Max interval = 12128 x 1.25 ms = 15160 ms

Which would add the following property to advData:

slaveConnectionIntervalRange: "00060c80"

Service Solicitation

Process a Service Solicitation UUID with any of the following commands:

advlib.ble.data.gap.solicitation.solicitation16BitUUIDs(payload, cursor, advertiserData);
advlib.ble.data.gap.solicitation.solicitation128BitUUIDs(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.uuid.solicitation16BitUUIDs('0314d8fe', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 03 Length, in bytes, of type and data
1 14 GAP Data Type for 16-bit Service Solicitation UUID
2-3 d8fe Google's UriBeacon UUID (bytes reversed)

Which would add a property to advData as follows:

solicitation16BitUUIDs: "fed8"

Service Data

Process service data assigned to the device.

advlib.ble.data.gap.servicedata.process(payload, cursor, advertiserData);

This is best illustrated with an example:

advlib.ble.data.gap.servicedata.process('09160a181204eb150000', 0, {});

For reference, the example payload is interpreted as follows:

Byte(s) Hex String Description
0 09 Length, in bytes, of type and data
1 16 GAP Data Type for service data
2-3 0a18 UUID (bytes reversed)
4-9 1204eb150000 Service Data

Which would add the following property to advData:

serviceData: {
  uuid : "180a",
  data : "1204eb150000"
}

reelyActive RFID Library

Process a raw packet (as a hexadecimal string) with the following command:

advlib.reelyactive.process(rawHexPacket);

What's next?

This is an active work in progress. Expect regular changes and updates, as well as improved documentation!

License

MIT License

Copyright (c) 2015 reelyActive

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

Wireless Advertising Packet Decoding Library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published