@iotile/iotile-device
Version:
A typescript library for interfacing with IOTile BLE devices
204 lines • 8.92 kB
JavaScript
;
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