New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ble-packet

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ble-packet

ble-packet is a framer and parser for BLE attributes on node.js

  • 0.2.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
89
increased by7.23%
Maintainers
1
Weekly downloads
 
Created
Source

ble-packet

ble-packet is a framer and parser for BLE attributes on node.js

NPM

Build Status npm npm

Table of Contents

  1. Overview
    1.1 GATT Specifications
    1.2 Installation
    1.3 Usage
  2. APIs: frame(), and parse()
  3. Appendix
    3.1 GATT Characteristics
    3.2 GATT Declarations
    3.3 GATT Descriptors
    3.4 BIPSO Characteristics
  4. License

1. Overview

The ble-packet is the packet builder and parser used for process BLE attributes if they are GATT Specifications-defined ones or BIPSO Specifications-defined ones.


1.1 GATT Specifications

In BLE, an attributes is the smallest data entity defined by GATT (Generic Attributes). Attributes are used to describe the hierarchical data organization, such as Services and Characteristics, and pieces of the user data. A Service conceptually groups all the related Characteristics together, and each Characteristic always contain at least two attributes: Characteristic Declaration and Characteristic Value.


1.2 Installation

$ npm install ble-packet --save


1.3 Usage

Require the module:

var blePacket = require('ble-packet');

Using .frame() and .parse() methods to build and parse BLE attributes is quite simple. Here are some quick examples:

  • Build a Characteristic raw buffer
var connParamsVal = {
        minConnInterval: 100,
        maxConnInterval: 500,
        latency: 0,
        timeout: 2000
    },
    charBuf = blePacket.frame('0x2a04', connParamsVal);
  • Parse a Characteristic raw packet into an object
var charPacket = new Buffer([ 0x00, 0x00, 0x02, ... ]);

blePacket.parse('0x2a04', charPacket, function (err, result) {
    if (!err)
        console.log(result);  // The parsed result
});

2. APIs


.frame(uuid, value)

Generate the raw packet of a GATT-defined or BIPSO-defined attribute value.

Arguments:

  1. uuid (String | Number): UUID defined in GATT Specifications or BIPSO Specification.
  2. value (Object): A GATT-defined or BIPSO-defined attribute value.

Returns

  • (Buffer): Raw buffer of given BLE attribute.

Example:

var dayDateUuid = '0x2a0a',
    dayDateVal = {
        year: 1945,
        month: 7,
        day: 19,
        hours: 9,
        minutes: 0,
        seconds: 0,
        dayOfWeek: 2
    }

blePacket.frame(dayDateUuid, dayDateVal);   // <Buffer 99 07 07 13 09 00 00 02>

.parse(uuid, buf, callback)

Parse a raw buffer into a GATT-defined or BIPSO-defined attribute value.

Arguments:

  1. uuid (String | Number): UUID defined in GATT Specifications or BIPSO Specification.
  2. buf (Buffer): Raw buffer to be parsed.
  3. callback (Function): function(err, result) {...}. Get called when the raw buffer is parsed.

Returns

  • (None)

Example:

var dayDateUuid = '0x2a0a',
    rawBuf = new Buffer([ 153, 7, 07, 19, 09, 00, 00, 02 ]);

blePacket.parse(dayDateUuid, rawBuf, function(err, result) {
    if (err)
        console.log(err);
    else
        console.log(result);

    // Result object
    // {
    //     year: 1945,
    //     month: 7,
    //     day: 19,
    //     hours: 9,
    //     minutes: 0,
    //     seconds: 0,
    //     dayOfWeek: 2
    // }
});

3. Appendix

3.1 GATT Characteristics

  • A Characteristic is a container of the user data. It is defined by

    • UUID: a 16-bit number defined by SIG to represent a attribute
    • Value: actual value of the user data which is a piece of bytes
  • Value is a logical value and ble-packet can parse it into an object according to particular rules. The following table gives the fields and their data types of a parsed object.

  • The 'flags' field tells how to parse the Value, and the rule is given with something like tempF(bit0) and tempC(!bit0).

    • tempF(bit0) means that if bit0 of 'flags' is 1, the field tempF will be picked and parsed.

    • tempC(!bit0) means that if bit0 of 'flags' is 0, the field tempC will be picked and parsed.

    • medicationL(bit4 & bit5) means that if bit4 and bit5 of 'flags' are both 1, the field medicationL will be picked and parsed.

    • Here is an example of the parsed result object of a Characteristic with UUID 0x2a1c

      {   // Result object of UUID 0x2a1c 
          flags: 2,       // bit0 = 0, bit1 = 1, bit2 = 0
          tempC: 21.5,    // tempC(!bit0)
          year: 2015,     // year(bit1)
          month: 12,      // month(bit1)
          day: 25,        // day(bit1)
          hours: 21,      // hours(bit1)
          minutes: 36,    // minutes(bit1) 
          seconds: 12     // seconds(bit1) 
      }
      

Note:

  • A field type of list(type) indicates that value of this field is an array and (type) tells the data type of each entry in it.
{   // Result object of UUID 0x2a22, Field type: list(uint8)
    bootKeyboardInputReport: [1, 2, 3]
}
  • ble-packet can not build and parse the packet comes with the following commands, since the input to each command is probably not an eligible Characteristic Value.
    • 'ATT_ReadBlobRsp', 'ATT_PrepareWriteReq', 'ATT_PrepareWriteRsp', 'GATT_WriteLongCharValue', 'GATT_ReliableWrites'
  • ble-packet can not build and parse the Characteristic Value comes with the following UUIDs, since there are fields with variable length, optional, or unknown.
    • '0x2a2a', '0x2a55', '0x2a5a', '0x2a63', '0x2a64', '0x2a66', '0x2a6b', '0x2aa4', '0x2aa7', '0x2aa9', '0x2aaa', '0x2aab', '0x2aac'
UUIDField NamesFiled types
0x2a00namestring
0x2a01categoryuint16
0x2a02flagboolean
0x2a03addraddr6
0x2a04minConnInterval, maxConnInterval, latency, timeoutuint16, uint16, uint16, uint16
0x2a05startHandle, endHandleuint16, uint16
0x2a06alertLeveluint8
0x2a07txPowerint8
0x2a08year, month, day, hours, minutes, secondsuint16, uint8, uint8, uint8, uint8, uint8
0x2a09dayOfWeekuint8
0x2a0ayear, month, day, hours, minutes, seconds, dayOfWeekuint16, uint8, uint8, uint8, uint8, uint8, uint8
0x2a0cyear, month, day, hours, minutes, seconds, dayOfWeek, fractions256uint16, uint8, uint8, uint8, uint8, uint8, uint8, uint8
0x2a0ddstOffsetuint8
0x2a0etimeZoneint8
0x2a0ftimeZone, dstOffsetint8, uint8
0x2a11year, month, day, hours, minutes, seconds, dstOffsetuint16, uint8, uint8, uint8, uint8, uint8, uint8
0x2a12accuracyuint8
0x2a13timeSourceuint8
0x2a14source, accuracy, daySinceUpdate, hourSinceUpdateuint8, uint8, uint8, uint8
0x2a16timeUpdateCtrluint8
0x2a17currentState, resultuint8, uint8
0x2a18flags, sequenceNum, year, month, day, hours, minutes, seconds, timeOffset(bit0), glucoseKg(bit1 & !bit2), glucoseMol(bit1 & bit2), type(bit2), sampleLocation(bit2), sensorStatus(bit3)uint8, uint16, uint16, uint8, uint8, uint8, uint8, uint8,
0x2a19leveluint8
0x2a1cflags, tempC(!bit0), tempF(bit0), year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), tempType(bit2)uint8, float, float, uint16, uint8, uint8, uint8, uint8, uint8, uint8
0x2a1dtempTextDescuint8
0x2a1eflags, tempC(!bit0), tempF(bit0), year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), tempType(bit2)uint8, float, float, uint16, uint8, uint8, uint8, uint8, uint8, uint8
0x2a21measureIntervaluint16
0x2a22bootKeyboardInputlist(uint8)
0x2a23manufacturerID, organizationallyUIDaddr5, addr3
0x2a24modelNumstring
0x2a25serialNumstring
0x2a26firmwareRevstring
0x2a27hardwareRevstring
0x2a28softwareRevstring
0x2a29manufacturerNamestring
0x2a2byear, month, day, hours, minutes, seconds, dayOfWeek, fractions256, adjustReasonuint16, uint8, uint8, uint8, uint8, uint8, uint8, uint8, uint8
0x2a2cmagneticDeclinationuint16
0x2a31scanRefreshuint8
0x2a32bootKeyboardOutputlist(uint8)
0x2a33bootMouseInputlist(uint8)
0x2a34flags, sequenceNum, extendedFlags(bit7), carbohydrateID(bit0), carbohydrate(bit0), meal(bit1), tester(bit1), health(bit2), exerciseDuration(bit3), exerciseIntensity(bit3), medicationID(bit4), medicationKg(bit4 & !bit5), medicationL(bit4 & bit5), hbA1c(bit6)uint8, uint16, uint8, uint8, sfloat, uint8, nibble, nibble, uint16, uint8, uint8, sfloat, sfloat, sfloat
0x2a35flags, systolicMmHg(!bit0), diastolicMmHg(!bit0), arterialPresMmHg(!bit0), systolicKpa(bit0), diastolicKpa(bit0), arterialPresKpa(bit0), year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), pulseRate(bit2), userID(bit3), status(bit4)uint8, sfloat, sfloat, sfloat, sfloat, sfloat, sfloat, uint16, uint8, uint8, uint8, uint8, uint8, sfloat, uint8, uint16
0x2a36flags, systolicMmHg(!bit0), diastolicMmHg(!bit0), arterialPresMmHg(!bit0), systolicKpa(bit0), diastolicKpa(bit0), arterialPresKpa(bit0), year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), pulseRate(bit2), userID(bit3), status(bit4)uint8, sfloat, sfloat, sfloat, sfloat, sfloat, sfloat, uint16, uint8, uint8, uint8, uint8, uint8, sfloat, uint8, uint16
0x2a37flags, heartRate8(!bit0), heartRate16(bit0), energyExpended(bit3), rrInterval(bit4)uint8, uint8, uint16, uint16, uint16
0x2a38bodySensorLocationuint8
0x2a39heartRateCtrluint8
0x2a3falertStatusuint8
0x2a40ringerCtrlPointuint8
0x2a41ringerSetuint8
0x2a42categoryIDBitMask0, categoryIDBitMask1uint8, uint8
0x2a43categoryIDuint8
0x2a44commID, categoryIDuint8, uint8
0x2a45categoryID, unreadCountuint8, uint8
0x2a46categoryID, newAlert, textStringInfouint8, uint8, string
0x2a47categoryIDBitMask0, categoryIDBitMask1uint8, uint8
0x2a48categoryIDBitMask0, categoryIDBitMask1uint8, uint8
0x2a49featureuint16
0x2a4abcdHID, bCountryCode, flagsuint16, uint8, uint8
0x2a4breportMaplist(uint8)
0x2a4chidCtrluint8
0x2a4dreportlist(uint8)
0x2a4eprotocolModeuint8
0x2a4fleScanInterval, leScanWindowuint16, uint16
0x2a50vendorIDSource, vendorID, productID, productVersionuint8, uint16, uint16, uint16
0x2a51featureuint16
0x2a52opcode, operanduint8, uint8, uint8
0x2a53flags, speed, cadence, strideLength(bit0), totalDist(bit1)uint8, uint16, uint8, uint16, uint32
0x2a54featureuint16
0x2a56digitaluint8
0x2a58analoguint16
0x2a5bflags, cumulativeWheelRev(bit0), lastWheelEventTime(bit0), cumulativeCrankRev(bit1), lastCrankEventTime(bit1)uint8, uint32, uint16, uint16, uint16
0x2a5cfeatureuint16
0x2a5dsensorLocationuint8
0x2a5eflags, spotCheckSpO2, spotCheckPr, year(bit0), month(bit0), day(bit0), hours(bit0), minutes(bit0), seconds(bit0), measureStatus(bit1), deviceAndSensorStatus(bit2), pulseAmpIndex(bit3)uint8, sfloat, sfloat, uint16, uint8, uint8, uint8, uint8, uint8, uint16, uint24, sfloat
0x2a5fflags, normalSpO2, normalPR, fastSpO2(bit0), fastPR(bit0), slowSpO2(bit1), slowPR(bit1), measureStatus(bit2), deviceAndSensorStatus(bit3), pulseAmpIndex(bit4)uint8, sfloat, sfloat, sfloat, sfloat, sfloat, sfloat, uint16, uint24, sfloat
0x2a65featureuint32
0x2a67flags, instantSpeed(bit0), totalDist(bit1), latitude(bit2), longitude(bit2), elevation(bit3), heading(bit4), rollingTime(bit5), year(bit6), month(bit6), day(bit6), hours(bit6), minutes(bit6), seconds(bit6)uint8, uint16, uint24, int32, int32, int24, uint16, uint8, uint16, uint8, uint8, uint8, uint8, uint8
0x2a68flags, bearing, heading, remainingDist(bit0), remainingVertDist(bit1), year(bit2), month(bit2), day(bit2), hours(bit2), minutes(bit2), seconds(bit2)uint8, uint16, uint16, uint24, int24, uint16, uint8, uint8, uint8, uint8, uint8
0x2a69flags, beaconsInSolution(bit0), beaconsInView(bit1), timeToFirstFix(bit2), ehpe(bit3), evpe(bit4), hdop(bit5), vdop(bit6)uint8, uint8, uint8, uint16, uint32, uint32, uint8, uint8
0x2a6afeatureuint32
0x2a6celevationint24
0x2a6dpressureuint32
0x2a6etempint16
0x2a6fhumidityuint16
0x2a70trueWindSpeeduint16
0x2a71trueWindDirectionuint16
0x2a72apparentWindSpeeduint16
0x2a73apparentWindDirectionuint16
0x2a74gustFactoruint8
0x2a75pollenConcuint24
0x2a76uvIndexuint8
0x2a77irradianceuint16
0x2a78rainfalluint16
0x2a79windChillint8
0x2a7aheatIndexint8
0x2a7bdewPointint8
0x2a7dflag, uuiduint16, uuid
0x2a7elowerLimituint8
0x2a7fthresholduint8
0x2a80ageuint8
0x2a81lowerLimituint8
0x2a82upperLimituint8
0x2a83thresholduint8
0x2a84upperLimituint8
0x2a85year, month, dayuint16, uint8, uint8
0x2a86year, month, dayuint16, uint8, uint8
0x2a87emailAddrstring
0x2a88lowerLimituint8
0x2a89upperLimituint8
0x2a8afirstNamestring
0x2a8bveryLightAndLight, lightAndModerate, moderateAndHard, hardAndMaxuint8, uint8, uint8, uint8
0x2a8cgenderuint8
0x2a8dheartRateMaxuint8
0x2a8eheightuint16
0x2a8fhipCircumferenceuint16
0x2a90lastNamestring
0x2a91maxHeartRateuint8
0x2a92restingHeartRateuint8
0x2a93sportTypeuint8
0x2a94lightAndModerate, moderateAndHarduint8, uint8
0x2a95fatburnAndFitnessuint8
0x2a96vo2Maxuint8
0x2a97waistCiruint16
0x2a98weightuint16
0x2a99changeIncrementuint32
0x2a9auserIndexuint8
0x2a9bfeatureuint32
0x2a9cflags, bodyFatPercent, year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), userID(bit2), basalMetabolism(bit3), musclePercent(bit4), muscleMassKg(!bit0 & bit5), muscleMassPounds(bit0 & bit5), fatFreeMassKg(!bit0 & bit6), fatFreeMassPounds(bit0 & bit6), softLeanMassKg(!bit0 & bit7), softLeanMassPounds(bit0 & bit7), bodyWaterMassKg(!bit0 & bit8), bodyWaterMassPounds(bit0 & bit8), impedance(bit9), weightKg(!bit0 & bit10), weightPounds(bit0 & bit10), heightMeters(!bit0 & bit11), heightInches(bit0 & bit11)uint16, uint16, uint16, uint8, uint8, uint8, uint8, uint8, uint8, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16, uint16
0x2a9dflags, weightSI(!bit0), weightImperial(bit0), year(bit1), month(bit1), day(bit1), hours(bit1), minutes(bit1), seconds(bit1), userID(bit2), bmi(bit3), heightSI(!bit0 & bit3), heightImperial(bit0 & bit3)uint8, uint16, uint16, uint16, uint8, uint8, uint8, uint8, uint8, uint8, uint16, uint16, uint16
0x2a9efeatureuint32
0x2a9fopcode, parameteruint8, buffer
0x2aa0xAxis, yAxisint16, int16
0x2aa1xAxis, yAxis, zAxisint16, int16, int16
0x2aa2languagestring
0x2aa3barometricPresTrenduint8
0x2aa5featureuint24
0x2aa6addrResolutionSupuint8
0x2aa8feature, type, sampleLocation, e2eCrcuint24, nibble, nibble, uint16
0x2aadindoorPositionuint8
0x2aaelatitudeint32
0x2aaflongitudeint32
0x2ab0localNorthCoordinateint16
0x2ab1localEastCoordinateint16
0x2ab2floorNumuint8
0x2ab3altitudeuint16
0x2ab4uncertaintyuint8
0x2ab5locationNamestring
0x2ab6uristring
0x2ab7httpHeadersstring
0x2ab8statusCode, dataStatusuint16, uint8
0x2ab9httpEntityBodystring
0x2abaopcodeuint8
0x2abbhttpsSecurityboolean
0x2abcopcode, organizationID, parameteruint8, uint8, buffer
0x2abdoacpFeatures, olcpFeaturesuint32, uint32
0x2abeobjectNamestring
0x2abfobjectTypeuuid

3.2 GATT Declarations

  • A Declaration is an attribute to indicate the type of a GATT profile attribute. There are four types of GATT profile attributes defined by SIG, they are Primary Service(0x2800), Secondary Service(0x2801), Include(0x2802), and Characteristic(0x2803).
  • In ble-packet, a Declaration attribute can be parsed into an object with Field Names(keys) listed in the following table and Field types tells each data type of the corresponding field.
UUIDField NamesField types
0x2800uuiduuid
0x2801uuiduuid
0x2802serviceAttrHandle, endGroupHandle, uuiduint16, uint16, uuid
0x2803properties, handle, uuiduint8, uint16, uuid

3.3 GATT Descriptors

  • A Descriptor is an attribute that describes a Characteristic Value.
  • In ble-packet, a Descriptor will be parsed into an object with Field Names(keys) listed in the following table.

Note:

  • A field type of list(type) indicates that value of this field is an array and (type) tells the data type of each entry in it.
UUIDField NamesField types
0x2900propertiesuint16
0x2901userDescriptionstring
0x2902propertiesuint16
0x2903propertiesuint16
0x2904format, exponent, unit, namespace, descriptionuint8, int8, uint16, uint8, uint16
0x2905listOfHandleslist(uint16)
0x2907extReportRefuuid
0x2908reportID, reportTypeuint8, uint8
0x2909noOfDigitalsuint8
0x290acondition, analog(1,2,3), bitMask(4), analogInterval(5,6)uint8, uint16, uint8, uint32
0x290btriggerLogicuint8
0x290cflags, samplFunc, measurePeriod, updateInterval, application, measureUncertaintyuint16, uint8, uint24, uint24, uint8, uint8
0x290econdition, none(0), timeInterval(1,2), count(3)uint8, uint8, uint24, uint16
  • Note about the 'condition' field

    • The 'condition' field is used to pick which fields should be parsed into the result object.
    • For example, analogInterval(5,6) indicates that the result object will have analogInterval field if condition equals to 5 or 6.
    • Here is an example of the result object. (The Descriptor with UUID 0x290a may have fields: analog, bitMask, and analogInterval, and which one will be picked depends on the value of condition)
    {   // Result object of Descriptor with UUID 0x290a
        condition: 5,
        analogInterval: 3000    // analogInterval(5,6)
    }
    

3.4 BIPSO Characteristics

  • In BIPSO, an IPSO Smart Object will be mapped to a BLE Characteristic with a well-defined Characteristic Value.
  • Here is the document that show you all BIPSO-defined Characteristics.

4. License

The MIT License (MIT)

Copyright (c) 2016 Hedy Wang hedywings@gmail.com

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.

FAQs

Package last updated on 24 Aug 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc