UNPKG

obniz

Version:

obniz sdk for javascript

214 lines (213 loc) 8.39 kB
"use strict"; /** * @packageDocumentation * * @ignore */ // var debug = require('debug')('gap'); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Gap = void 0; const bleHelper_1 = __importDefault(require("../../bleHelper")); /** * @ignore */ const debug = () => { // do nothing. }; const eventemitter3_1 = __importDefault(require("eventemitter3")); const hci_1 = require("../hci"); /** * @ignore */ class Gap extends eventemitter3_1.default { constructor(hci) { super(); this._hci = hci; this._advertiseState = null; } /** * @ignore * @private */ _reset() { this._advertiseState = null; } async startAdvertisingWait(name, serviceUuids) { debug('startAdvertising: name = ' + name + ', serviceUuids = ' + JSON.stringify(serviceUuids, null, 2)); let advertisementDataLength = 3; let scanDataLength = 0; const serviceUuids16bit = []; const serviceUuids128bit = []; let i = 0; if (name && name.length) { scanDataLength += 2 + name.length; } if (serviceUuids && serviceUuids.length) { for (i = 0; i < serviceUuids.length; i++) { const serviceUuid = bleHelper_1.default.hex2reversedBuffer(serviceUuids[i]); if (serviceUuid.length === 2) { serviceUuids16bit.push(serviceUuid); } else if (serviceUuid.length === 16) { serviceUuids128bit.push(serviceUuid); } } } if (serviceUuids16bit.length) { advertisementDataLength += 2 + 2 * serviceUuids16bit.length; } if (serviceUuids128bit.length) { advertisementDataLength += 2 + 16 * serviceUuids128bit.length; } const advertisementData = Buffer.alloc(advertisementDataLength); const scanData = Buffer.alloc(scanDataLength); // flags advertisementData.writeUInt8(2, 0); advertisementData.writeUInt8(0x01, 1); advertisementData.writeUInt8(0x06, 2); let advertisementDataOffset = 3; if (serviceUuids16bit.length) { advertisementData.writeUInt8(1 + 2 * serviceUuids16bit.length, advertisementDataOffset); advertisementDataOffset++; advertisementData.writeUInt8(0x03, advertisementDataOffset); advertisementDataOffset++; for (i = 0; i < serviceUuids16bit.length; i++) { serviceUuids16bit[i].copy(advertisementData, advertisementDataOffset); advertisementDataOffset += serviceUuids16bit[i].length; } } if (serviceUuids128bit.length) { advertisementData.writeUInt8(1 + 16 * serviceUuids128bit.length, advertisementDataOffset); advertisementDataOffset++; advertisementData.writeUInt8(0x06, advertisementDataOffset); advertisementDataOffset++; for (i = 0; i < serviceUuids128bit.length; i++) { serviceUuids128bit[i].copy(advertisementData, advertisementDataOffset); advertisementDataOffset += serviceUuids128bit[i].length; } } // name if (name && name.length) { const nameBuffer = Buffer.alloc(name); scanData.writeUInt8(1 + nameBuffer.length, 0); scanData.writeUInt8(0x08, 1); nameBuffer.copy(scanData, 2); } await this.startAdvertisingWithEIRDataWait(advertisementData, scanData); } async startAdvertisingIBeaconWait(data) { debug('startAdvertisingIBeacon: data = ' + data.toString('hex')); const dataLength = data.length; const manufacturerDataLength = 4 + dataLength; const advertisementDataLength = 5 + manufacturerDataLength; // let scanDataLength = 0; const advertisementData = Buffer.alloc(advertisementDataLength); const scanData = Buffer.alloc(0); // flags advertisementData.writeUInt8(2, 0); advertisementData.writeUInt8(0x01, 1); advertisementData.writeUInt8(0x06, 2); advertisementData.writeUInt8(manufacturerDataLength + 1, 3); advertisementData.writeUInt8(0xff, 4); advertisementData.writeUInt16LE(0x004c, 5); // Apple Company Identifier LE (16 bit) advertisementData.writeUInt8(0x02, 7); // type, 2 => iBeacon advertisementData.writeUInt8(dataLength, 8); data.copy(advertisementData, 9); await this.startAdvertisingWithEIRDataWait(advertisementData, scanData); } async setExtendedAdvertiseParametersWait(handle, eventProperties, primaryAdvertisingPhy, secondaryAdvertisingPhy, txPower) { await this._hci.setExtendedAdvertisingParametersWait(handle, eventProperties, primaryAdvertisingPhy, secondaryAdvertisingPhy, txPower); } async setExtendedAdvertisingDataWait(handle, data) { await this._hci.setExtendedAdvertisingDataWait(handle, data); } async setExtendedAdvertisingScanResponseDataWait(handle, data) { await this._hci.setExtendedAdvertisingScanResponseDataWait(handle, data); } async restartExtendedAdvertisingWait(handle) { this._advertiseState = 'restarting'; await this._hci.setExtendedAdvertisingEnableWait(true, [ { handle, duration: 0, events: 0, }, ]); } async stopExtendedAdvertisingWait(handle) { this._advertiseState = 'stopping'; await this._hci.setExtendedAdvertisingEnableWait(false, [ { handle, duration: 0, events: 0, }, ]); } async startExtendedAdvertisingWait(handle) { this._advertiseState = 'starting'; const status = await this._hci.setExtendedAdvertisingEnableWait(true, [ { handle, duration: 0, events: 0, }, ]); if (this._advertiseState === 'starting') { this._advertiseState = 'started'; if (status) { throw new Error(hci_1.Hci.STATUS_MAPPER[status] || 'Unknown (' + status + ')'); } } else if (this._advertiseState === 'stopping') { this._advertiseState = 'stopped'; } } async startAdvertisingWithEIRDataWait(advertisementData, scanData) { advertisementData = advertisementData || Buffer.alloc(0); scanData = scanData || Buffer.alloc(0); debug('startAdvertisingWithEIRData: advertisement data = ' + advertisementData.toString('hex') + ', scan data = ' + scanData.toString('hex')); if (advertisementData.length > 31) { throw new Error('Advertisement data is over maximum limit of 31 bytes'); } else if (scanData.length > 31) { throw new Error('Scan data is over maximum limit of 31 bytes'); } this._advertiseState = 'starting'; const p1 = this._hci.setScanResponseDataWait(scanData); const p2 = this._hci.setAdvertisingDataWait(advertisementData); await Promise.all([p1, p2]); const p3 = this._hci.setAdvertiseEnableWait(true); const p4 = this._hci.setScanResponseDataWait(scanData); const p5 = this._hci.setAdvertisingDataWait(advertisementData); await Promise.all([p3, p4, p5]); const status = await p3; if (this._advertiseState === 'starting') { this._advertiseState = 'started'; if (status) { throw new Error(hci_1.Hci.STATUS_MAPPER[status] || 'Unknown (' + status + ')'); } } else if (this._advertiseState === 'stopping') { this._advertiseState = 'stopped'; } } async restartAdvertisingWait() { this._advertiseState = 'restarting'; await this._hci.setAdvertiseEnableWait(true); } async stopAdvertisingWait() { this._advertiseState = 'stopping'; await this._hci.setAdvertiseEnableWait(false); } } exports.Gap = Gap;