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