Comparing version 0.0.6 to 0.0.7
@@ -6,13 +6,46 @@ /** | ||
var pdu = require('../../util/pdu.js'); | ||
/** | ||
* List of all known licensees, expect frequent updates. | ||
* Kindly respect ascending order of UUIDs to facilitate verify-before-update! | ||
*/ | ||
var licenseeNames = { | ||
"b9407f30f5f8466eaff925556b57fe6d": "Estimote", | ||
"8deefbb9f7384297804096668bb44281": "Roximity", | ||
"f7826da64fa24e988024bc5b71e0893e": "Kontakt.io", | ||
"2f234454cf6d4a0fadf2f4911ba9ffa6": "Radius Networks", | ||
"f0018b9b75094c31a9051a27d39c003c": "LocosLab", | ||
"3d4f13b4d1fd404980e5d3edcc840b69": "Orange S.A.", | ||
"8deefbb9f7384297804096668bb44281": "Roximity", | ||
"b9407f30f5f8466eaff925556b57fe6d": "Estimote", | ||
"dab59c4fa4d6ee286bfe8e0000bbc2bb": "eNote", | ||
"e2c56db5dffb48d2b060d0f5a71096e0": "Bright Beacon", | ||
"dab59c4fa4d6ee286bfe8e0000bbc2bb": "eNote" | ||
"f0018b9b75094c31a9051a27d39c003c": "LocosLab", | ||
"f7826da64fa24e988024bc5b71e0893e": "Kontakt.io" | ||
}; | ||
/** | ||
* Parse Apple iBeacon manufacturer specific data. | ||
* @param {Object} advertiserData The object containing all parsed data. | ||
*/ | ||
function process(advertiserData) { | ||
var iBeacon = {}; | ||
var data = advertiserData.manufacturerSpecificData.data; | ||
iBeacon.uuid = data.substr(4,32); | ||
iBeacon.major = data.substr(36,4); | ||
iBeacon.minor = data.substr(40,4); | ||
iBeacon.txPower = pdu.convertTxPower(data.substr(44,2)); | ||
var licenseeName = licenseeNames[iBeacon.uuid]; | ||
if(typeof licenseeName === 'undefined') { | ||
licenseeName = 'Unknown'; | ||
} | ||
iBeacon.licenseeName = licenseeName; | ||
advertiserData.manufacturerSpecificData.iBeacon = iBeacon; | ||
} | ||
module.exports.licenseeNames = licenseeNames; | ||
module.exports.process = process; |
@@ -7,4 +7,6 @@ /** | ||
var pdu = require('../../common/util/pdu.js'); | ||
var companyIdentifierCodes = require('../../common/assignednumbers/companyidentifiercodes.js'); | ||
var ibeacon = require('../../common/manufacturers/apple/ibeacon.js'); | ||
var companyIdentifierCodes = | ||
require('../../common/assignednumbers/companyidentifiercodes.js'); | ||
var apple = require('../../common/manufacturers/apple/index.js'); | ||
var sticknfind = require('../../common/manufacturers/sticknfind/index.js'); | ||
@@ -34,115 +36,16 @@ | ||
// Apple proprietary data | ||
if(companyIdentifierCode === '004c') { | ||
var appleType = data.substr(0,2); | ||
switch(appleType) { | ||
case '02': | ||
processIBeacon(data, advertiserData); | ||
break; | ||
case '09': | ||
// TODO: determine what this is and process it | ||
break; | ||
default: | ||
} | ||
// Interpret the manufacturer specific data, if possible | ||
// Kindly respect ascending order of company identifier codes | ||
switch(companyIdentifierCode) { | ||
case '004c': | ||
apple.process(advertiserData); | ||
break; | ||
case '00f9': | ||
sticknfind.process(advertiserData); | ||
break; | ||
default: | ||
} | ||
// StickNFind proprietary data | ||
if(companyIdentifierCode === '00f9') { | ||
var packetType = data.substr(0,2); | ||
switch(packetType) { | ||
case '01': | ||
processSnFSingle(data, advertiserData); | ||
break; | ||
case '42': | ||
processSnSMotion(data, advertiserData); | ||
break; | ||
default: | ||
} | ||
} | ||
} | ||
/** | ||
* Parse Apple iBeacon manufacturer specific data. | ||
* @param {string} data The manufacturer-specific data as hex string. | ||
* @param {Object} advertiserData The object containing all parsed data. | ||
*/ | ||
function processIBeacon(data, advertiserData) { | ||
var iBeacon = {}; | ||
iBeacon.uuid = data.substr(4,32); | ||
iBeacon.major = data.substr(36,4); | ||
iBeacon.minor = data.substr(40,4); | ||
iBeacon.txPower = pdu.convertTxPower(data.substr(44,2)); | ||
var licenseeName = ibeacon.licenseeNames[iBeacon.uuid]; | ||
if(typeof licenseeName === 'undefined') { | ||
licenseeName = 'Unknown'; | ||
} | ||
iBeacon.licenseeName = licenseeName; | ||
advertiserData.manufacturerSpecificData.iBeacon = iBeacon; | ||
} | ||
/** | ||
* Parse StickNFind 'single payload' manufacturer specific data. | ||
* @param {string} data The manufacturer-specific data as hex string. | ||
* @param {Object} advertiserData The object containing all parsed data. | ||
*/ | ||
function processSnFSingle(data, advertiserData) { | ||
var snfBeacon = {}; | ||
snfBeacon.type = 'V2 Single Payload'; | ||
snfBeacon.id = pdu.reverseBytes(data.substr(2,16)); | ||
snfBeacon.time = parseInt(pdu.reverseBytes(data.substr(18,8)),16); | ||
snfBeacon.scanCount = parseInt(data.substr(26,2),16) / 4; | ||
snfBeacon.batteryVoltage = data.substr(28,2); | ||
snfBeacon.temperature = parseInt(data.substr(30,2),16); | ||
if(snfBeacon.temperature > 127) { | ||
snfBeacon.temperature = 127 - snfBeacon.temperature; | ||
} | ||
snfBeacon.temperature += (parseInt(data.substr(26,2),16) % 4) / 4; | ||
snfBeacon.calibration = data.substr(32,2); | ||
snfBeacon.checksum = data.substr(34,6); | ||
advertiserData.manufacturerSpecificData.snfBeacon = snfBeacon; | ||
} | ||
/** | ||
* Parse StickNSense 'motion' manufacturer specific data. | ||
* @param {string} data The manufacturer-specific data as hex string. | ||
* @param {Object} advertiserData The object containing all parsed data. | ||
*/ | ||
function processSnSMotion(data, advertiserData) { | ||
var snfBeacon = {}; | ||
snfBeacon.type = 'SnS Motion'; | ||
snfBeacon.timestamp = parseInt(pdu.reverseBytes(data.substr(2,8)),16); | ||
snfBeacon.temperature = parseInt(data.substr(10,2),16); | ||
if(snfBeacon.temperature > 127) { | ||
snfBeacon.temperature = 127 - snfBeacon.temperature; | ||
} | ||
snfBeacon.temperature = snfBeacon.temperature / 2; | ||
snfBeacon.temperature += (parseInt(data.substr(41,1),16)) / 4; | ||
snfBeacon.batteryVoltage = data.substr(12,2); | ||
snfBeacon.eventCounters = []; | ||
snfBeacon.eventCounters.push(data.substr(26,1) + data.substr(14,2)); | ||
snfBeacon.eventCounters.push(data.substr(27,1) + data.substr(16,2)); | ||
snfBeacon.eventCounters.push(data.substr(28,1) + data.substr(18,2)); | ||
snfBeacon.eventCounters.push(data.substr(29,1) + data.substr(20,2)); | ||
snfBeacon.eventCounters.push(data.substr(30,1) + data.substr(22,2)); | ||
snfBeacon.eventCounters.push(data.substr(31,1) + data.substr(24,2)); | ||
for(var cCounter = 0; cCounter < 6; cCounter++) { | ||
var hexStringCount = snfBeacon.eventCounters[cCounter]; | ||
snfBeacon.eventCounters[cCounter] = parseInt(hexStringCount,16); | ||
} | ||
snfBeacon.accelerationX = parseInt((data.substr(32,2) + | ||
data.substr(38,1)), 16); | ||
snfBeacon.accelerationY = parseInt((data.substr(34,2) + | ||
data.substr(39,1)), 16); | ||
snfBeacon.accelerationZ = parseInt((data.substr(36,2) + | ||
data.substr(40,1)), 16); | ||
advertiserData.manufacturerSpecificData.snfBeacon = snfBeacon; | ||
} | ||
module.exports.process = process; |
@@ -13,3 +13,3 @@ { | ||
], | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"engines": { | ||
@@ -16,0 +16,0 @@ "node": "^0.10.0" |
177
README.md
@@ -72,3 +72,10 @@ advlib | ||
Complementary to the packet processing hierarchy above is a _common_ folder which contains supporting functions and lookups that are subject to frequent evolution: | ||
* [Common](#common) | ||
* [Assigned Numbers](#assigned-numbers) | ||
* [Manufacturers](#manufacturers) | ||
* [Utilities](#util) | ||
### Header | ||
@@ -311,41 +318,4 @@ | ||
##### iBeacon | ||
The proprietary data of some manufacturers can be further processed. The data for those supported will automatically be processed. See the [Manufacturers](#manufacturers) section for the list of all supported manufacturers. | ||
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", | ||
licenseeName: "Estimote" | ||
} | ||
} | ||
##### StickNFind | ||
A specific case of manufacturer specific data is that of StickNFind. The following proprietary payloads are supported: | ||
- V2 Single Payload | ||
- SNS Motion | ||
#### TX Power Level | ||
@@ -692,2 +662,131 @@ | ||
### Common | ||
Supporting functions and lookups that are subject to frequent evolution are: | ||
* [Assigned Numbers](#assigned-numbers) | ||
* [Manufacturers](#manufacturers) | ||
* [Utilities](#utilities) | ||
#### Assigned Numbers | ||
The Bluetooth SIG maintains a [list of assigned numbers](https://www.bluetooth.org/en-us/specification/assigned-numbers). The advlib currently implements [16-bit UUIDs for Members](#member-services) and [Company Identifiers](#company-identifiers). | ||
##### Company Identifiers | ||
The Bluetooth SIG maintains a [list of company identifiers](https://www.bluetooth.org/en-us/specification/assigned-numbers/company-identifiers). Look up a company name from its 16-bit code. | ||
advlib.ble.common.companyidentifiercodes.companyNames[companyCode]; | ||
For example: | ||
advlib.ble.common.companyidentifiercodes.companyNames['000d']; | ||
would yield: | ||
"Texas Instruments Inc." | ||
##### Member Services | ||
The Bluetooth SIG maintains a list of 16-bit UUIDs for Members, for members. In other words, this list is accessible to members. Look up a company name from its 16-bit service UUID. | ||
advlib.ble.common.memberservices.companyNames[uuid]; | ||
For example: | ||
advlib.ble.common.memberservices.companyNames['feed']; | ||
would yield: | ||
"Tile, Inc." | ||
#### Manufacturers | ||
All functions and lookups which represent manufacturer-proprietary data contained in the [Manufacturer Specific Data](#manufacturer-specific-data) data type are included here. Each manufacturer is contained in a separate subfolder. | ||
##### Apple | ||
Process Apple-proprietary data from a packet's contained advertiser data. | ||
advlib.ble.common.manufacturers.apple.process(advData); | ||
The first byte of the proprietary data specifies the type: | ||
| Type (Hex String) | Description | | ||
|------------------:|:------------------------------| | ||
| 02 | [iBeacon](#ibeacon) | | ||
| 09 | AppleTV & ??? | | ||
###### iBeacon | ||
A specific case of Apple-proprietary data is the iBeacon. Look up a licensee name from its 128-bit iBeacon UUID. | ||
advlib.ble.common.manufacturers.apple.ibeacon.licenseeNames[uuid]; | ||
For example: | ||
advlib.ble.common.manufacturers.apple.ibeacon.licenseeNames['f7826da64fa24e988024bc5b71e0893e']; | ||
would yield: | ||
"Kontakt.io" | ||
Process an iBeacon packet from the contained advertiser data. | ||
advlib.ble.common.manufacturers.apple.ibeacon.process(advData); | ||
This is best illustrated with an example using the following input: | ||
advData: { | ||
manufacturerSpecificData: { | ||
companyIdentifierCode: "008c", | ||
data: "0215b9407f30f5f8466eaff925556b57fe6d294c903974" | ||
} | ||
} | ||
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", | ||
licenseeName: "Estimote" | ||
} | ||
} | ||
##### StickNFind | ||
Process StickNFind-proprietary data from a packet's contained advertiser data. | ||
advlib.ble.common.manufacturers.sticknfind.process(advData); | ||
The first byte of the proprietary data specifies the type: | ||
| Type (Hex String) | Description | | ||
|------------------:|:------------------------------| | ||
| 01 | StickNFind Single | | ||
| 42 | StickNSense Motion | | ||
#### Utilities | ||
##### PDU | ||
More info to come. | ||
reelyActive RFID Library | ||
@@ -704,3 +803,3 @@ ------------------------ | ||
This is an active work in progress. Expect regular changes and updates, as well as improved documentation! | ||
This is an active work in progress. Expect regular changes and updates, as well as improved documentation! If you'd like to contribute, kindly read our [Node.js style guide](https://github.com/reelyactive/node-style-guide) and [contact us](http://context.reelyactive.com/contact.html) or make a pull request. | ||
@@ -707,0 +806,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
250904
135
3959
821