UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

116 lines 4.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const iotile_common_1 = require("@iotile/iotile-common"); const iotile_types_1 = require("../common/iotile-types"); const config_1 = require("../config"); ; const IOS_STRATEGY = { steps: [ { preupdateWait: 180, update: { minInterval: 15, maxInterval: 15, timeout: 1000 } } ] }; const ANDROID_STRATEGY = { steps: [ { preupdateWait: 300, update: { minInterval: 7.5, maxInterval: 10, timeout: 1000 } }, { preupdateWait: 0, update: { minInterval: 7.5, maxInterval: 15, timeout: 1000 } }, { preupdateWait: 0, update: { minInterval: 7.5, maxInterval: 30, timeout: 1000 } } ] }; const UPDATE_STRATEGIES = { [iotile_types_1.Platform.IOS]: IOS_STRATEGY, [iotile_types_1.Platform.Android]: ANDROID_STRATEGY }; class BLEConnectionOptimizer { constructor(platform) { this.platform = platform; this.attempt = 0; } async optimizeConnection(device, adapter, maxAttempts = 4) { let info; this.attempt = 0; if (!(this.platform in UPDATE_STRATEGIES)) { config_1.catBLEOptimizer.warn(`Unknown platform '${this.platform}' in optimizeConnection, not optimizing`); return null; } try { info = await device.queryBLEConnectionInfo(); } catch (err) { config_1.catBLEOptimizer.info("Not optimizing BLE connection on old device that does not support the required RPCs."); config_1.catBLEOptimizer.info(JSON.stringify(err)); return null; } let strategy = UPDATE_STRATEGIES[this.platform]; if (strategy.steps.length > 0 && info.intervalMS <= strategy.steps[0].update.maxInterval) { config_1.catBLEOptimizer.info(`No optimization required, default interval: ${info.intervalMS} ms`); return null; } config_1.catBLEOptimizer.info(`Running ${this.platform} strategy, starting interval: ${info.intervalMS} ms`); try { for (let step of strategy.steps) { if (step.preupdateWait > 0) { await iotile_common_1.delay(step.preupdateWait); } config_1.catBLEOptimizer.info(`Attempting to set interval [${step.update.minInterval}, ${step.update.maxInterval}], attempt: ${this.attempt}`); let updateErr = await device.updateBLEParams(step.update.minInterval, step.update.maxInterval, step.update.timeout); this.attempt += 1; await iotile_common_1.delay(300); if (updateErr == 17) { config_1.catBLEOptimizer.warn(`BLE stack busy, trying step again. Interval [${step.update.minInterval}, ${step.update.maxInterval}], attempt: ${this.attempt}`); await iotile_common_1.delay(300); let updateErr = await device.updateBLEParams(step.update.minInterval, step.update.maxInterval, step.update.timeout); this.attempt += 1; if (updateErr !== 0) { config_1.catBLEOptimizer.error(`Could not update ble connection after backing off 300 ms due to a busy BLE stack: error = ${updateErr}`, null); return null; } } else if (updateErr) { config_1.catBLEOptimizer.error(`Unexpected error optimizing BLE connection: error code = ${updateErr}`, null); return null; } info = await device.queryBLEConnectionInfo(); if (info.intervalMS <= step.update.maxInterval) { config_1.catBLEOptimizer.info(`Successfully optimized BLE connection interval to ${info.intervalMS} ms`); return null; } } } catch (err) { config_1.catBLEOptimizer.error(`Unexpected error optimizing BLE connection ${err}`, err); return null; } config_1.catBLEOptimizer.warn(`Unable to achieve target BLE interval range, final interval: ${info.intervalMS} ms`); return null; } } exports.BLEConnectionOptimizer = BLEConnectionOptimizer; //# sourceMappingURL=iotile-ble-optimizer.js.map