UNPKG

nativescript-akylas-bluetooth

Version:

Connect to and interact with Bluetooth LE peripherals

312 lines 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var android_main_1 = require("./android_main"); var common_1 = require("../common"); var DATA_TYPE_FLAGS = 0x01; var DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02; var DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03; var DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04; var DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05; var DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06; var DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07; var DATA_TYPE_LOCAL_NAME_SHORT = 0x08; var DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09; var DATA_TYPE_TX_POWER_LEVEL = 0x0a; var DATA_TYPE_SERVICE_DATA_16_BIT = 0x16; var DATA_TYPE_SERVICE_DATA_32_BIT = 0x20; var DATA_TYPE_SERVICE_DATA_128_BIT = 0x21; var DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xff; var BASE_UUID; function getBASE_UUID() { if (!BASE_UUID) { BASE_UUID = android.os.ParcelUuid.fromString('00000000-0000-1000-8000-00805F9B34FB'); } return BASE_UUID; } var UUID_BYTES_16_BIT = 2; var UUID_BYTES_32_BIT = 4; var UUID_BYTES_128_BIT = 16; function parseUuidFrom(uuidBytes) { if (uuidBytes == null) { throw new Error('uuidBytes cannot be null'); } var length = uuidBytes.length; if (length !== UUID_BYTES_16_BIT && length !== UUID_BYTES_32_BIT && length !== UUID_BYTES_128_BIT) { throw new Error('uuidBytes length invalid - ' + length); } if (length === UUID_BYTES_128_BIT) { var buf = java.nio.ByteBuffer.wrap(uuidBytes).order(java.nio.ByteOrder.LITTLE_ENDIAN); var msb_1 = buf.getLong(8); var lsb_1 = buf.getLong(0); return new java.util.UUID(msb_1, lsb_1).toString(); } var shortUuid; if (length === UUID_BYTES_16_BIT) { shortUuid = uuidBytes[0] & 0xff; shortUuid += (uuidBytes[1] & 0xff) << 8; } else { shortUuid = uuidBytes[0] & 0xff; shortUuid += (uuidBytes[1] & 0xff) << 8; shortUuid += (uuidBytes[2] & 0xff) << 16; shortUuid += (uuidBytes[3] & 0xff) << 24; } var msb = getBASE_UUID() .getUuid() .getMostSignificantBits() + (shortUuid << 32); var lsb = getBASE_UUID() .getUuid() .getLeastSignificantBits(); return new java.util.UUID(msb, lsb).toString(); } function parseServiceUuid(scanRecord, currentPos, dataLength, uuidLength, serviceUuids) { while (dataLength > 0) { var uuidBytes = extractBytes(scanRecord, currentPos, uuidLength); serviceUuids.push(parseUuidFrom(uuidBytes)); dataLength -= uuidLength; currentPos += uuidLength; } return currentPos; } function extractBytes(scanRecord, start, length) { return java.util.Arrays.copyOfRange(scanRecord, start, start + length); } var ScanRecord = (function () { function ScanRecord(serviceUuids, manufacturerData, serviceData, advertiseFlags, txPowerLevel, localName, bytes) { this.serviceUuids = serviceUuids; this.manufacturerData = manufacturerData; this.serviceData = serviceData; this.advertiseFlags = advertiseFlags; this.txPowerLevel = txPowerLevel; this.localName = localName; this.bytes = bytes; } ScanRecord.prototype.getManufacturerSpecificData = function () { return this.manufacturerData; }; ScanRecord.prototype.getBytes = function () { return this.bytes; }; ScanRecord.prototype.getAdvertiseFlags = function () { return this.advertiseFlags; }; ScanRecord.prototype.getServiceUuids = function () { return this.serviceUuids; }; ScanRecord.prototype.getServiceData = function () { return this.serviceData; }; ScanRecord.prototype.getDeviceName = function () { return this.localName; }; ScanRecord.prototype.getTxPowerLevel = function () { return this.txPowerLevel; }; return ScanRecord; }()); exports.ScanRecord = ScanRecord; function parseFromBytes(scanRecord) { if (scanRecord == null) { return null; } var currentPos = 0; var advertiseFlag = -1; var serviceUuids = []; var localName = null; var txPowerLevel = Number.MIN_VALUE; var manufacturerData = new android.util.SparseArray(); var serviceData = {}; try { while (currentPos < scanRecord.length) { var length_1 = scanRecord[currentPos++] & 0xff; if (length_1 === 0) { break; } var dataLength = length_1 - 1; var fieldType = scanRecord[currentPos++] & 0xff; switch (fieldType) { case DATA_TYPE_FLAGS: advertiseFlag = scanRecord[currentPos] & 0xff; break; case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL: case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE: parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_16_BIT, serviceUuids); break; case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL: case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE: parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_32_BIT, serviceUuids); break; case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL: case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE: parseServiceUuid(scanRecord, currentPos, dataLength, UUID_BYTES_128_BIT, serviceUuids); break; case DATA_TYPE_LOCAL_NAME_SHORT: case DATA_TYPE_LOCAL_NAME_COMPLETE: localName = String.fromCharCode.apply(String, extractBytes(scanRecord, currentPos, dataLength)); break; case DATA_TYPE_TX_POWER_LEVEL: txPowerLevel = scanRecord[currentPos]; break; case DATA_TYPE_SERVICE_DATA_16_BIT: case DATA_TYPE_SERVICE_DATA_32_BIT: case DATA_TYPE_SERVICE_DATA_128_BIT: var serviceUuidLength = UUID_BYTES_16_BIT; if (fieldType === DATA_TYPE_SERVICE_DATA_32_BIT) { serviceUuidLength = UUID_BYTES_32_BIT; } else if (fieldType === DATA_TYPE_SERVICE_DATA_128_BIT) { serviceUuidLength = UUID_BYTES_128_BIT; } var serviceDataUuidBytes = extractBytes(scanRecord, currentPos, serviceUuidLength); var serviceDataUuid = parseUuidFrom(serviceDataUuidBytes); var serviceDataArray = extractBytes(scanRecord, currentPos + serviceUuidLength, dataLength - serviceUuidLength); serviceData[serviceDataUuid] = serviceDataArray; break; case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA: var manufacturerId = ((scanRecord[currentPos + 1] & 0xff) << 8) + (scanRecord[currentPos] & 0xff); var manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2, dataLength - 2); manufacturerData.put(manufacturerId, manufacturerDataBytes); break; default: break; } currentPos += dataLength; } if (serviceUuids.length === 0) { serviceUuids = null; } return new ScanRecord(serviceUuids, manufacturerData, serviceData, advertiseFlag, txPowerLevel, localName, scanRecord); } catch (e) { return new ScanRecord(null, null, null, -1, Number.MIN_VALUE, null, scanRecord); } } var TNS_LeScanCallback = (function (_super) { __extends(TNS_LeScanCallback, _super); function TNS_LeScanCallback() { var _this = _super.call(this) || this; return global.__native(_this); } TNS_LeScanCallback.prototype.onLeScan = function (device, rssi, data) { common_1.CLog(common_1.CLogTypes.info, "TNS_LeScanCallback.onLeScan ---- device: " + device + ", rssi: " + rssi + ", scanRecord: " + data); var stateObject = this.owner.get().connections[device.getAddress()]; if (!stateObject) { stateObject = this.owner.get().connections[device.getAddress()] = { state: 'disconnected' }; var scanRecord = parseFromBytes(data); var advertismentData = new ScanAdvertisment(scanRecord); var payload = { type: 'scanResult', UUID: device.getAddress(), name: device.getName(), localName: advertismentData.localName, RSSI: rssi, state: 'disconnected', advertismentData: advertismentData, manufacturerId: advertismentData.manufacturerId }; this.onPeripheralDiscovered && this.onPeripheralDiscovered(payload); this.owner.get().sendEvent(android_main_1.Bluetooth.device_discovered_event, payload); } }; TNS_LeScanCallback.prototype.onInit = function (owner) { this.owner = owner; common_1.CLog(common_1.CLogTypes.info, "TNS_LeScanCallback.onInit ---- this.owner: " + this.owner); }; TNS_LeScanCallback = __decorate([ JavaProxy('com.nativescript.TNS_LeScanCallback'), __metadata("design:paramtypes", []) ], TNS_LeScanCallback); return TNS_LeScanCallback; }(android.bluetooth.BluetoothAdapter.LeScanCallback)); exports.TNS_LeScanCallback = TNS_LeScanCallback; var ScanAdvertisment = (function () { function ScanAdvertisment(scanRecord) { this.scanRecord = scanRecord; } Object.defineProperty(ScanAdvertisment.prototype, "manufacturerData", { get: function () { var data = this.scanRecord.getManufacturerSpecificData(); var size = data.size(); if (size > 0) { var mKey = data.keyAt(0); return android_main_1.byteArrayToBuffer(data.get(mKey)); } return undefined; }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "data", { get: function () { return android_main_1.byteArrayToBuffer(this.scanRecord.getBytes()); }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "manufacturerId", { get: function () { var data = this.scanRecord.getManufacturerSpecificData(); var size = data.size(); if (size > 0) { return data.keyAt(0); } return -1; }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "txPowerLevel", { get: function () { return this.scanRecord.getTxPowerLevel(); }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "localName", { get: function () { return this.scanRecord.getDeviceName(); }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "flags", { get: function () { return this.scanRecord.getAdvertiseFlags(); }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "uuids", { get: function () { var result = []; var serviceUuids = this.scanRecord.getServiceUuids(); for (var i = 0; i < serviceUuids.length; i++) { result.push(android_main_1.uuidToString(serviceUuids[i])); } return result; }, enumerable: true, configurable: true }); Object.defineProperty(ScanAdvertisment.prototype, "serviceData", { get: function () { var result = {}; var serviceData = this.scanRecord.getServiceData(); var keys = Object.keys(serviceData); var currentKey; for (var i = 0; i < keys.length; i++) { currentKey = keys[i]; result[android_main_1.uuidToString(currentKey)] = android_main_1.byteArrayToBuffer(serviceData[currentKey]); } return result; }, enumerable: true, configurable: true }); return ScanAdvertisment; }()); exports.ScanAdvertisment = ScanAdvertisment; //# sourceMappingURL=TNS_LeScanCallback.js.map