UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

204 lines 8.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var constants_1 = require("./constants"); var utilities_1 = require("./utilities"); var iotile_common_1 = require("@iotile/iotile-common"); var Advertisement = /** @class */ (function () { function Advertisement(elements) { this.elements = elements; } Advertisement.prototype.containsService = function (service) { if (this.elements.serviceList == null) return false; return this.elements.serviceList.indexOf(service.toUpperCase()) > -1; }; Advertisement.prototype.hasManufacturerData = function (manu) { if (this.elements.manufacturerData == null) return false; return manu in this.elements.manufacturerData; }; Advertisement.prototype.getManufacturerData = function (manu) { if (this.elements.manufacturerData == null) return null; if (this.elements.manufacturerData[manu] == null) return null; return this.elements.manufacturerData[manu]; }; Advertisement.prototype.getServiceData = function (serviceUUID) { if (this.elements.serviceData == null) return null; return this.elements.serviceData[serviceUUID]; }; Advertisement.FromAndroid = function (data) { var i = 0; var advert = {}; var view = new DataView(data); while (i < data.byteLength) { var length_1 = view.getUint8(i); /* * Make sure we have all of the data that we claim to have. * the length encoded in each ad element does not include * the length byte itself. */ if ((i + length_1 + 1) >= data.byteLength) break; if (length_1 === 0) { /* * Do nothing, some advertisement pack null bytes at the end * of the advertisement so just ignore them and continue parsing. */ } else if (length_1 === 1) { /** * This just means there is no associated with this ad element, so * for now we ignore it since there are no ad elements we care about * that have no associated data. */ } else { var type = view.getUint8(i + 1); var dataLength = length_1 - 1; var elementData = data.slice(i + 2, i + 2 + dataLength); switch (type) { case constants_1.AdElementTypeCode.CompleteLocalName: case constants_1.AdElementTypeCode.ShortenedLocalName: /* * The contexts are utf-8 encoded string with the name of the device */ try { advert.localName = utilities_1.parseUTF8String(elementData); } catch (err) { /* * UTF-8 decoding errors are ignored, we just don't process the * local name. */ } break; case constants_1.AdElementTypeCode.Incomplete128BitUUIDList: /** * This should contain exactly one */ if (elementData.byteLength === 16) { var uuids = Advertisement.ParseUUID128List(elementData); if (uuids != null) advert.serviceList = uuids; } break; case constants_1.AdElementTypeCode.ManufacturerSpecificData: var manuData = Advertisement.ParseManufacturerData(elementData); if (manuData != null) { if (advert.manufacturerData != null) { Advertisement.MergeManufacturerData(advert.manufacturerData, manuData); } else { advert.manufacturerData = manuData; } } break; case constants_1.AdElementTypeCode.ServiceData: var uuid = Advertisement.ParseServiceUUIDFromData(elementData); if (uuid != null) { advert.serviceList = [uuid]; var serviceData = Advertisement.ParseServiceData(elementData, parseInt(uuid, 16)); if (serviceData != null) { if (advert.serviceData != null) { Advertisement.MergeServiceData(advert.serviceData, serviceData); } else { advert.serviceData = serviceData; } } } break; } } i += (length_1 + 1); } return new Advertisement(advert); }; Advertisement.FromIOS = function (data) { var _a; var advert = {}; if (data.kCBAdvDataLocalName != null) advert.localName = data.kCBAdvDataLocalName; if (data.kCBAdvDataManufacturerData != null) { var manuData = Advertisement.ParseManufacturerData(data.kCBAdvDataManufacturerData); if (manuData != null) { advert.manufacturerData = manuData; } } if (data.kCBAdvDataServiceData != null) { var UUID = Object.keys(data.kCBAdvDataServiceData)[0]; var serviceData = (_a = {}, _a[parseInt(UUID, 16)] = data.kCBAdvDataServiceData[UUID], _a); if (serviceData != null) { advert.serviceData = serviceData; advert.serviceList = [UUID]; } } if (data.kCBAdvDataServiceUUIDs != null && advert.serviceList == null) advert.serviceList = data.kCBAdvDataServiceUUIDs; return new Advertisement(advert); }; Advertisement.ParseManufacturerData = function (data) { //Make sure we received enough data for the manufacturer ID if (data.byteLength < 2) return null; var view = new DataView(data); var manuID = view.getUint16(0, true); var manuData = data.slice(2); var result = {}; result[manuID] = manuData; return result; }; Advertisement.ParseServiceData = function (data, serviceUUID) { //Make sure we received enough data for the service UUID if (data.byteLength < 2) return null; var serviceData = data.slice(2); var result = {}; result[serviceUUID] = serviceData; return result; }; Advertisement.MergeManufacturerData = function (orig, update) { for (var key in update) { if (key in orig) { var newSize = orig[key].byteLength + update[key].byteLength; var newBuffer = new ArrayBuffer(newSize); iotile_common_1.copyArrayBuffer(newBuffer, orig[key], 0, 0, orig[key].byteLength); iotile_common_1.copyArrayBuffer(newBuffer, update[key], 0, orig[key].byteLength, update[key].byteLength); } } }; Advertisement.MergeServiceData = function (orig, update) { for (var key in update) { if (key in orig) { var newSize = orig[key].byteLength + update[key].byteLength; var newBuffer = new ArrayBuffer(newSize); iotile_common_1.copyArrayBuffer(newBuffer, orig[key], 0, 0, orig[key].byteLength); iotile_common_1.copyArrayBuffer(newBuffer, update[key], 0, orig[key].byteLength, update[key].byteLength); } } }; Advertisement.ParseUUID128List = function (data) { if (data.byteLength % 16 !== 0) return null; var uuids = []; for (var i = 0; i < data.byteLength; i += 16) { var binUUID = data.slice(i, i + 16); var uuid = utilities_1.parseBinaryUUID(binUUID, true); uuids.push(uuid); } return uuids; }; Advertisement.ParseServiceUUIDFromData = function (data) { if (data.byteLength < 2) return null; var binUUID = data.slice(0, 2); var uuid = utilities_1.parseBinary16BitUUID(binUUID, true); return uuid; }; return Advertisement; }()); exports.Advertisement = Advertisement; //# sourceMappingURL=advertisement.js.map