obniz
Version:
obniz sdk for javascript
747 lines (746 loc) • 29.9 kB
JavaScript
"use strict";
/**
* @packageDocumentation
* @module ObnizCore
*/
/* eslint-disable rulesdir/non-ascii */
/* eslint-disable max-classes-per-file */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.iBeaconData = exports.iBeaconDataWithStrict = exports.iBeaconCompanyID = exports.ObnizPartsBlePairable = exports.ObnizPartsBleConnectable = exports.ObnizPartsBle = exports.checkEquals = exports.fixByRange = exports.uintToArrayWithBE = exports.uintToArray = exports.intBE = exports.uintBE = exports.int = exports.uint = exports.fixedPoint = exports.notMatchDeviceError = void 0;
const round_to_1 = __importDefault(require("round-to"));
const ObnizError_1 = require("./ObnizError");
const debugFlag = false;
const debug = (...objects) => {
if (!debugFlag)
return;
console.debug(...objects);
};
const ObnizPartsBleModeList = ['Beacon', 'Connectable', 'Pairing'];
exports.notMatchDeviceError = new Error('Is NOT target device.');
const fixedPoint = (value, integerBytes) => {
const positive = value[0] >> 7 === 0;
if (!positive) {
value = value.map((n, i) => (n ^ 0xff) + (i === value.length - 1 ? 1 : 0));
}
const val = (positive ? 1 : -1) *
((0, exports.uint)(value.slice(0, integerBytes)) +
(0, exports.uint)(value.slice(integerBytes)) /
(1 << (8 * (value.length - integerBytes))));
return val;
};
exports.fixedPoint = fixedPoint;
const uint = (value) => {
let val = 0;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_operators#bitwise_logical_operators
// eslint-disable-next-line prettier/prettier
value.forEach((v, i) => (val += v * (2 ** (i * 8))));
return val;
};
exports.uint = uint;
const int = (value) => {
const num = (0, exports.uint)(value);
return (num -
((num & (0x8 << (value.length * 8 - 4))) !== 0
? value.length && value.length >= 28
? 0x10000000 * 2 ** (value.length - 28)
: 0x1 << (value.length * 8)
: 0));
};
exports.int = int;
const uintBE = (value) => (0, exports.uint)(value.reverse());
exports.uintBE = uintBE;
const intBE = (value) => (0, exports.int)(value.reverse());
exports.intBE = intBE;
const uintToArray = (value, length = 2) => new Uint8Array(length)
.fill(0)
.map((v, i) => value % (1 << ((i + 1) * 8)) >> (i * 8));
exports.uintToArray = uintToArray;
const uintToArrayWithBE = (value, length = 2) => (0, exports.uintToArray)(value, length).reverse();
exports.uintToArrayWithBE = uintToArrayWithBE;
const fixByRange = (name, value, min, max) => {
if (value < min) {
console.warn(`Since ${name} ranges from ${min} to ${max}, ${min} is used.`);
return min;
}
if (value > max) {
console.warn(`Since ${name} ranges from ${min} to ${max}, ${max} is used.`);
return max;
}
return value;
};
exports.fixByRange = fixByRange;
const checkEquals = (base, target) => base.filter((v, i) => v !== target[i]).length === 0;
exports.checkEquals = checkEquals;
class ObnizPartsBle {
constructor(peripheral, mode) {
this._mode = mode;
this.peripheral = peripheral;
this.address = peripheral.address;
this.beaconData = this.peripheral.manufacturerSpecificData;
if (this.beaconData)
this.beaconData = this.beaconData.slice(2);
this.beaconDataInScanResponse = this.peripheral.manufacturerSpecificDataInScanResponse;
if (this.beaconDataInScanResponse)
this.beaconDataInScanResponse = this.beaconDataInScanResponse.slice(2);
this.serviceData = this.peripheral.serviceData;
if (this.serviceData)
this.serviceData = this.serviceData.slice(2);
}
/**
* Information of parts.
* name: PartsName
*/
static info() {
return { name: this.PartsName };
}
/**
* Available BLE modes (Beacon | Connectable | Pairing)
*
* 利用可能なBLEのモード (Beacon | Connectable | Pairing)
*/
static getAvailableBleMode() {
const availableBleMode = this
.AvailableBleMode;
return availableBleMode instanceof Array
? availableBleMode
: [availableBleMode];
}
static getServiceUuids(mode) {
const uuids = this.ServiceUuids instanceof Array ||
typeof this.ServiceUuids === 'string' ||
this.ServiceUuids === null ||
this.ServiceUuids === undefined
? this.ServiceUuids
: this.ServiceUuids[mode];
return typeof uuids === 'string' ? [uuids] : uuids;
}
/**
* @deprecated
*/
static isDevice(peripheral) {
return this.getDeviceMode(peripheral) !== null;
}
/**
* Get Peripheral Mode.
*
* ペリフェラルのモードを取得
*
* @param peripheral BleRemotePeripheral
* @returns If the corresponding device is that mode, it must be null if not applicable 該当するデバイスならばそのモード、該当しなければnull
*/
static getDeviceMode(peripheral) {
debug('getAvailableBleMode()', this.getAvailableBleMode());
for (const mode of this.getAvailableBleMode()) {
const check = this.isDeviceWithMode(peripheral, mode);
if (check) {
debug(`getDeviceMode(p) => ${mode}`, peripheral.address);
return mode;
}
}
debug('getDeviceMode(p) => null', peripheral.address);
return null;
}
/**
* Check if peripherals and modes match the library.
*
* ペリフェラルとモードがライブラリと合致するかチェック
*
* @param peripheral BleRemotePeripheral
* @param mode Beacon | Connectable | Pairing
* @returns Whether to match 合致するかどうか
*/
static isDeviceWithMode(peripheral, mode) {
var _a;
debug(`isDeviceWithMode(peripheral, ${mode})`);
if (!this.getAvailableBleMode().includes(mode))
return false;
if (this.Address) {
const defaultAddress = this.Address instanceof RegExp ? this.Address : this.Address[mode];
debug('defaultAddress', defaultAddress);
if (defaultAddress !== undefined &&
!defaultAddress.test(peripheral.address)) {
debug(`defaultAddress.test(${peripheral.address}) === false`);
return false;
}
}
if (this.LocalName) {
const defaultLocalName = this.LocalName instanceof RegExp
? this.LocalName
: this.LocalName[mode];
debug('defaultLocalName', defaultLocalName);
if (defaultLocalName !== undefined &&
!defaultLocalName.test((_a = peripheral.localName) !== null && _a !== void 0 ? _a : 'null')) {
debug(`defaultLocalName.test(${peripheral.localName} ?? 'null') === false`);
return false;
}
}
if (this.ServiceUuids) {
const defaultServiceUuids = this.getServiceUuids(mode);
debug('defaultServiceUuids', defaultServiceUuids);
if (defaultServiceUuids !== undefined) {
const uuids = peripheral.advertisementServiceUuids();
debug('uuids', uuids);
if (defaultServiceUuids === null && uuids.length !== 0)
return false;
if (defaultServiceUuids !== null && uuids.length === 0)
return false;
if (defaultServiceUuids !== null &&
defaultServiceUuids.some((u) => !uuids.includes(u.toLowerCase()))) {
debug('defaultServiceUuids.some((u) => !uuids.includes(u.toLowerCase())) === true');
return false;
}
}
}
if (!this.checkCustomData(mode, peripheral.address, peripheral.manufacturerSpecificData, this.BeaconDataLength, this.CompanyID, this.BeaconDataStruct)) {
debug('this.checkCustomData(mode, p.address, p.manufacturerSpecificData, this.BeaconDataLength, this.CompanyID, this.BeaconDataStruct) === false');
return false;
}
if (!this.checkCustomData(mode, peripheral.address, peripheral.manufacturerSpecificDataInScanResponse, this.BeaconDataLength_ScanResponse, this.CompanyID_ScanResponse, this.BeaconDataStruct, true)) {
debug('this.checkCustomData(mode, p.address, p.manufacturerSpecificDataInScanResponse, this.BeaconDataLength_ScanResponse, this.CompanyID_ScanResponse, this.BeaconDataStruct, true) === false');
return false;
}
if (!this.checkCustomData(mode, peripheral.address, peripheral.serviceData, this.ServiceDataLength, this.ServiceDataUUID, this.ServiceDataStruct)) {
debug('this.checkCustomData(mode, p.address, p.serviceData, this.ServiceDataLength, this.ServiceDataUUID, this.ServiceDataStruct) === false');
return false;
}
return true;
}
static checkCustomData(mode, address, rawData, dataLength, headID, dataStruct, inScanResponse = false) {
var _a, _b, _c;
debug(`checkCustomData(mode, address, ${rawData}, ${dataLength}, ${headID}, ${dataStruct}, ${inScanResponse})`);
const data = rawData ? new Uint8Array(rawData) : null;
if (headID !== undefined) {
const defHeadID = headID instanceof Array || headID === null || headID === undefined
? headID
: headID[mode];
if (defHeadID !== undefined) {
if (defHeadID === null && data !== null)
return false;
if (defHeadID !== null && data === null)
return false;
if (defHeadID !== null &&
data !== null &&
(defHeadID[0] !== data[0] || defHeadID[1] !== data[1]))
return false;
}
}
if (dataLength !== undefined) {
const defDataLength = typeof dataLength === 'number' ||
dataLength === null ||
dataLength === undefined
? dataLength
: dataLength[mode];
if (defDataLength !== undefined) {
if (defDataLength === null && data !== null)
return false;
if (defDataLength !== null && data === null)
return false;
if (defDataLength !== null &&
data !== null &&
data.length + 1 !== defDataLength)
return false;
}
}
if (typeof dataStruct === 'object' && dataStruct !== null) {
// ひとまずモードで選択してみる
const defDataStructByMode = dataStruct[mode];
// モードで選択した変数がオブジェクトまたはnullならばそのまま使い、そうでなければモードで選択せずに使用
const defDataStruct = (typeof defDataStructByMode === 'object'
? defDataStructByMode
: dataStruct);
if (defDataStruct !== undefined) {
// TODO: macAddress_ -> macAddress
if (defDataStruct && ((_a = defDataStruct.macAddress_) === null || _a === void 0 ? void 0 : _a.type) === 'check') {
defDataStruct.macAddress_ = Object.assign(Object.assign({}, defDataStruct.macAddress_), { data: new Array(6)
.fill(0)
.map((v, i) => parseInt(address.slice(i * 2, (i + 1) * 2), 16))
.reverse() });
}
if (defDataStruct === null && data === null) {
// OK
}
else if (defDataStruct !== null && data === null) {
// defDataStructではNULLであるべきかどうかを
// AdvertisementDataとScanResponseData別に明記できないため、判定をスキップ
}
else if (defDataStruct === null && data !== null) {
// どちらかが明示的に空なのに存在するため、ミスマッチ
return false;
}
else if (defDataStruct !== null && data !== null) {
// チェック対象となる設定を抽出
const configs = Object.values(defDataStruct).filter((config) => {
var _a;
return inScanResponse === ((_a = config.scanResponse) !== null && _a !== void 0 ? _a : false) &&
config.type === 'check';
});
for (const config of configs) {
// チェック対象となるバイト列
const targetData = data.slice(2 + config.index, 2 + config.index + ((_b = config.length) !== null && _b !== void 0 ? _b : 1));
if (typeof config.func === 'function') {
// funcが関数ならば、実行して確認
const result = config.func(targetData);
if (!result) {
return false;
}
}
else if (typeof config.data === 'number' ||
Array.isArray(config.data)) {
// dataに値や配列があれば、それらを比較
const baseData = typeof config.data === 'number'
? [config.data]
: (_c = config.data) !== null && _c !== void 0 ? _c : [];
if (!(0, exports.checkEquals)(baseData, targetData)) {
return false;
}
}
}
}
}
}
return true;
}
/**
* Form advertising data into an associative array.
*
* アドバタイジングデータを連想配列に成形
*
* @deprecated
*/
static getData(peripheral) {
const mode = this.getDeviceMode(peripheral);
if (!mode)
return null;
const lib = new this(peripheral, mode);
try {
return lib.getData();
}
catch (e) {
console.error(e);
return null;
}
}
get mode() {
return this._mode;
}
checkMode(force = false) {
if (this.mode && !force)
return this.mode;
const mode = this.staticClass.getDeviceMode(this.peripheral);
if (!mode)
throw exports.notMatchDeviceError;
return (this._mode = mode);
}
/**
* アドバタイジングデータを連想配列に成形
*
* 利用可能なモード: Beacon, Connectable(一部のみ)
*
* Form advertising data into an associative array
*
* Available modes: Beacon, Connectable(only part)
*/
getData() {
var _a;
this.checkMode();
const dataStruct = (_a = this.staticClass.BeaconDataStruct) !== null && _a !== void 0 ? _a : this.staticClass.ServiceDataStruct;
if (!dataStruct)
throw new Error('Data analysis is not defined.');
const data = this.staticClass.BeaconDataStruct
? this.beaconData
: this.staticClass.ServiceDataStruct
? this.serviceData
: null;
if (!data)
throw new Error('Manufacturer specific data is null.');
// ひとまずモードで選択してみる
const defDataStructByMode = dataStruct[this.mode];
// モードで選択した変数がオブジェクトまたはnullならばそのまま使い、そうでなければモードで選択せずに使用
const defDataStruct = (typeof defDataStructByMode === 'object'
? defDataStructByMode
: dataStruct);
if (defDataStruct === null)
throw new Error('Data analysis is not defined.');
return Object.fromEntries(Object.entries(defDataStruct)
.map(([name, config]) => {
var _a, _b, _c, _d;
if (config.type === 'check')
return [];
if (!(config.scanResponse ? this.beaconDataInScanResponse : data))
throw new Error('manufacturerSpecificData is null.');
const vals = ((_a = (config.scanResponse ? this.beaconDataInScanResponse : data)) !== null && _a !== void 0 ? _a : []).slice(config.index, config.index + ((_b = config.length) !== null && _b !== void 0 ? _b : 1));
if (config.type.indexOf('bool') === 0)
return [name, (vals[0] & parseInt(config.type.slice(4), 2)) > 0];
else if (config.type === 'string')
return [
name,
Buffer.from(vals.slice(0, vals.indexOf(0))).toString(),
];
else if (config.type === 'xyz') {
if (!config.length)
config.length = 6;
if (config.length % 6 !== 0)
return [];
else if (config.length === 6)
return [
name,
this.getTriaxial(vals, config.fixedIntegerBytes, config.round),
];
else
return [
name,
[...Array(config.length / 6).keys()].map((v) => this.getTriaxial(vals.slice(v * 6, (v + 1) * 6), config.fixedIntegerBytes, config.round)),
];
}
else if (config.type === 'custom')
if (!config.func)
return [];
else
return [name, config.func(vals, this.peripheral)];
else {
const base = (_c = config.base) !== null && _c !== void 0 ? _c : 0;
const multi = (_d = config.multiple) !== null && _d !== void 0 ? _d : 1;
const f = (d) => config.fixedIntegerBytes !== undefined
? (0, exports.fixedPoint)(d, config.fixedIntegerBytes)
: (config.type.indexOf('u') === 0 ? exports.uint : exports.int)(config.type.indexOf('BE') >= 0 ? d.reverse() : d);
const num = base + f(vals) * multi;
return [
name,
config.round !== undefined ? (0, round_to_1.default)(num, config.round) : num,
];
}
})
.filter((v) => v[0]));
}
getTriaxial(data, fixedIntegerBytes, round) {
const f = (d) => fixedIntegerBytes !== undefined
? (0, exports.fixedPoint)(d, fixedIntegerBytes)
: (0, exports.int)(d);
const ff = (d) => round !== undefined ? (0, round_to_1.default)(f(d), round) : f(d);
return {
x: ff(data.slice(0, 2)),
y: ff(data.slice(2, 4)),
z: ff(data.slice(4, 6)),
};
}
}
exports.ObnizPartsBle = ObnizPartsBle;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.Address = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.LocalName = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.ServiceUuids = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.BeaconDataLength = undefined;
/**
* Overall length of manufacturer-specific data.
* Used as a condition of isDevice() by default.
*
* 製造者固有データ全体の長さ
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.BeaconDataLength_ScanResponse = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.CompanyID = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.CompanyID_ScanResponse = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.ServiceDataLength = undefined;
/**
* Used as a condition of isDevice() by default.
*
* 標準でisDevice()の条件として使用
*/
ObnizPartsBle.ServiceDataUUID = undefined;
class ObnizPartsBleConnectable extends ObnizPartsBle {
constructor(peripheral, mode) {
super(peripheral, mode);
this.disconnectedListeners = [];
this.peripheral.ondisconnect = (reason) => {
this.disconnectedListeners.forEach((func) => func(reason));
if (this.ondisconnect)
this.ondisconnect(reason);
};
}
/**
* Register functions to be called on disconnection.
*
* Note: Registration is reset upon connection, so please register after connection.
*
* 切断時に呼ばれる関数を登録
*
* 注意: 接続時に登録がリセットされるため、接続後に登録してください
*
* @param func Function to be registered 登録したい関数
*/
registerDisconnected(func) {
this.disconnectedListeners.push(func);
}
/**
* Connect to peripherals with validation.
*
* バリデーションのあるペリフェラルへの接続
*
* @param keys: Key acquired when pairing previously 以前にペアリングしたときに取得されたキー
* @param setting: Additional settings when connecting 接続時の追加設定
*/
async connectWait(keys, setting) {
var _a;
if (this.peripheral.connected) {
return;
}
// 切断時に呼ぶ関数一覧を全て削除
this.disconnectedListeners.splice(0);
// TODO: Enable Validation
// if (this.mode !== 'Connectable')
// throw new Error(
// `Connection can only be used in connectable mode, the current mode is ${this.mode}`
// );
await this.peripheral.connectWait(Object.assign({ pairingOption: Object.assign({ keys }, ((_a = setting === null || setting === void 0 ? void 0 : setting.pairingOption) !== null && _a !== void 0 ? _a : {})) }, (setting !== null && setting !== void 0 ? setting : {})));
}
/**
* Disconnect from peripheral.
*
* ペリフェラルから切断
*/
async disconnectWait() {
if (!this.peripheral.connected) {
return;
}
await this.peripheral.disconnectWait();
// 切断時に呼ぶ関数一覧を全て削除
this.disconnectedListeners.splice(0);
}
/**
* Check if connected.
*
* 接続しているかどうかチェック
*
* @param connected Connection status (default: true)
*/
checkConnected(connected = true) {
if (this.peripheral.connected !== connected)
throw new Error(connected
? 'Peripheral is NOT connected!!'
: 'Peripheral IS connected!!');
}
/**
* Get any characteristic from any service.
*
* 任意のサービスから任意のキャラクタリスティックを取得
*
* @param serviceUuid Service UUID
* @param characteristicUuid Characteristic UUID
* @returns Instance of BleRemoteCharacteristic
*/
getChar(serviceUuid, characteristicUuid) {
const service = this.peripheral.getService(serviceUuid);
if (!service)
throw new ObnizError_1.ObnizBleUnknownServiceError(this.peripheral.address, serviceUuid);
const char = service.getCharacteristic(characteristicUuid);
if (!char)
throw new ObnizError_1.ObnizBleUnknownCharacteristicError(this.peripheral.address, serviceUuid, characteristicUuid);
return char;
}
/**
* Read data from any characteristic of any service.
*
* 任意のサービスの任意のキャラクタリスティックからデータを読み取り
*
* @param serviceUuid Service UUID
* @param characteristicUuid Characteristic UUID
* @returns Data read result データ読み取り結果
*/
async readCharWait(serviceUuid, characteristicUuid) {
const char = this.getChar(serviceUuid, characteristicUuid);
return await char.readWait();
}
/**
* Write data to any characteristic of any service.
*
* 任意のサービスの任意のキャラクタリスティックへデータを書き込み
*
* @param serviceUuid Service UUID
* @param characteristicUuid Characteristic UUID
* @param data Write data 書き込むデータ
* @returns Data write result データ書き込み結果
*/
async writeCharWait(serviceUuid, characteristicUuid, data, needResponse) {
const characteristic = this.getChar(serviceUuid, characteristicUuid);
return await characteristic.writeWait(data instanceof Uint8Array ? Array.from(data) : data, needResponse);
}
/**
* Register notification to any characteristic of any service.
*
* 任意のサービスの任意のキャラクタリスティックへ通知を登録
*
* @param serviceUuid Service UUID
* @param characteristicUuid Characteristic UUID
* @param callback Function called when data arrives データが来たときに呼ばれる関数
*/
async subscribeWait(serviceUuid, characteristicUuid, callback) {
const characteristic = this.getChar(serviceUuid, characteristicUuid);
await characteristic.registerNotifyWait(callback !== null && callback !== void 0 ? callback : (() => {
// do nothing.
}));
}
/**
* Unregister notification to any characteristic of any service.
*
* 任意のサービスの任意のキャラクタリスティックから通知登録を削除
*
* @param serviceUuid Service UUID
* @param characteristicUuid Characteristic UUID
*/
async unsubscribeWait(serviceUuid, characteristicUuid) {
const characteristic = this.getChar(serviceUuid, characteristicUuid);
await characteristic.unregisterNotifyWait();
}
}
exports.ObnizPartsBleConnectable = ObnizPartsBleConnectable;
class ObnizPartsBlePairable extends ObnizPartsBleConnectable {
constructor() {
super(...arguments);
/**
* Disconnect request after pairing
*
* ペアリング後に切断要求を行う
*/
this.requestDisconnectAfterPairing = true;
/**
* Wait for disconnect event at the end of pairing
*
* ペアリングの終了時には切断イベントを待つ
*/
this.waitDisconnectAfterPairing = true;
}
/**
* After pairing and before disconnect
*
* ペアリング後、切断前に行う操作
*/
async afterPairingWait() {
// do nothing
}
/**
* Perform pairing
*
* ペアリングを実行
*
* @returns Pairing key ペアリングキー
*/
async pairingWait() {
// 接続と同時にペアリングを実行
await this.connectWait(undefined, {
waitUntilPairing: true,
});
// ペアリングキーを取得
const keys = await this.peripheral.getPairingKeysWait();
/**
以下の実装と同じ
await this._peripheral.connectWait({
pairingOption: {
onPairedCallback: (keys) => {
gotKeys = keys;
},
onPairingFailed: (e) => {
throw e;
},
},
});
*/
// 任意のコードを実行
await this.afterPairingWait();
const promise = new Promise((resolve) => {
this.registerDisconnected(() => {
// ペアリングキーを返す
resolve(keys);
});
});
// 切断要求を送信
if (this.requestDisconnectAfterPairing) {
await this.disconnectWait();
}
if (this.waitDisconnectAfterPairing) {
// 切断完了を待つ
return await promise;
}
else {
// 切断完了を待たずにペアリングキーを返す
return keys;
}
}
}
exports.ObnizPartsBlePairable = ObnizPartsBlePairable;
exports.iBeaconCompanyID = [0x4c, 0x00];
exports.iBeaconDataWithStrict =
// length !== 25
{
type: {
index: 0,
length: 2,
type: 'check',
data: [0x02, 0x15],
},
uuid: {
index: 2,
length: 16,
type: 'custom',
func: (data) => data
.map((d, i) => ([2, 3, 4, 5].includes(i / 2) ? '-' : '') +
('00' + d.toString(16)).slice(-2))
.join(''),
},
major: {
index: 18,
length: 2,
type: 'unsignedNumBE',
},
minor: {
index: 20,
length: 2,
type: 'unsignedNumBE',
},
power: {
index: 22,
type: 'numLE',
},
rssi: {
index: 0,
type: 'custom',
func: (d, p) => { var _a; return (_a = p.rssi) !== null && _a !== void 0 ? _a : 0; },
},
};
exports.iBeaconData = exports.iBeaconDataWithStrict;