123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- // (c) 2014-2016 Don Coleman
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /* global cordova, module */
- "use strict";
- var stringToArrayBuffer = function(str) {
- var ret = new Uint8Array(str.length);
- for (var i = 0; i < str.length; i++) {
- ret[i] = str.charCodeAt(i);
- }
- return ret.buffer;
- };
- var base64ToArrayBuffer = function(b64) {
- return stringToArrayBuffer(atob(b64));
- };
- function massageMessageNativeToJs(message) {
- if (message.CDVType == 'ArrayBuffer') {
- message = base64ToArrayBuffer(message.data);
- }
- return message;
- }
- // Cordova 3.6 doesn't unwrap ArrayBuffers in nested data structures
- // https://github.com/apache/cordova-js/blob/94291706945c42fd47fa632ed30f5eb811080e95/src/ios/exec.js#L107-L122
- function convertToNativeJS(object) {
- Object.keys(object).forEach(function (key) {
- var value = object[key];
- object[key] = massageMessageNativeToJs(value);
- if (typeof(value) === 'object') {
- convertToNativeJS(value);
- }
- });
- }
- // set of auto-connected device ids
- var autoconnected = {};
- module.exports = {
- scan: function (services, seconds, success, failure) {
- var successWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- success(peripheral);
- };
- cordova.exec(successWrapper, failure, 'BLE', 'scan', [services, seconds]);
- },
- startScan: function (services, success, failure) {
- var successWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- success(peripheral);
- };
- cordova.exec(successWrapper, failure, 'BLE', 'startScan', [services]);
- },
- stopScan: function (success, failure) {
- cordova.exec(success, failure, 'BLE', 'stopScan', []);
- },
- startScanWithOptions: function(services, options, success, failure) {
- var successWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- success(peripheral);
- };
- options = options || {};
- cordova.exec(successWrapper, failure, 'BLE', 'startScanWithOptions', [services, options]);
- },
- // iOS only
- connectedPeripheralsWithServices: function(services, success, failure) {
- cordova.exec(success, failure, 'BLE', 'connectedPeripheralsWithServices', [services]);
- },
- // iOS only
- peripheralsWithIdentifiers: function(identifiers, success, failure) {
- cordova.exec(success, failure, 'BLE', 'peripheralsWithIdentifiers', [identifiers]);
- },
- // Android only
- bondedDevices: function(success, failure) {
- cordova.exec(success, failure, 'BLE', 'bondedDevices', []);
- },
- // this will probably be removed
- list: function (success, failure) {
- cordova.exec(success, failure, 'BLE', 'list', []);
- },
- connect: function (device_id, success, failure) {
- // wrap success so nested array buffers in advertising info are handled correctly
- var successWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- success(peripheral);
- };
- cordova.exec(successWrapper, failure, 'BLE', 'connect', [device_id]);
- },
- autoConnect: function (deviceId, connectCallback, disconnectCallback) {
- var disconnectCallbackWrapper;
- autoconnected[deviceId] = true;
- // wrap connectCallback so nested array buffers in advertising info are handled correctly
- var connectCallbackWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- connectCallback(peripheral);
- };
- // iOS needs to reconnect on disconnect, unless ble.disconnect was called.
- if (cordova.platformId === 'ios') {
- disconnectCallbackWrapper = function(peripheral) {
- // let the app know the peripheral disconnected
- disconnectCallback(peripheral);
-
- // reconnect if we have a peripheral.id and the user didn't call disconnect
- if (peripheral.id && autoconnected[peripheral.id]) {
- cordova.exec(connectCallbackWrapper, disconnectCallbackWrapper, 'BLE', 'autoConnect', [deviceId]);
- }
- };
- } else { // no wrapper for Android
- disconnectCallbackWrapper = disconnectCallback;
- }
- cordova.exec(connectCallbackWrapper, disconnectCallbackWrapper, 'BLE', 'autoConnect', [deviceId]);
- },
- disconnect: function (device_id, success, failure) {
- try {
- delete autoconnected[device_id];
- } catch(e) {
- // ignore error
- }
- cordova.exec(success, failure, 'BLE', 'disconnect', [device_id]);
- },
- requestMtu: function (device_id, mtu, success, failure) {
- cordova.exec(success, failure, 'BLE', 'requestMtu', [device_id, mtu]);
- },
- refreshDeviceCache: function(deviceId, timeoutMillis, success, failure) {
- var successWrapper = function(peripheral) {
- convertToNativeJS(peripheral);
- success(peripheral);
- };
- cordova.exec(successWrapper, failure, 'BLE', 'refreshDeviceCache', [deviceId, timeoutMillis]);
- },
- // characteristic value comes back as ArrayBuffer in the success callback
- read: function (device_id, service_uuid, characteristic_uuid, success, failure) {
- cordova.exec(success, failure, 'BLE', 'read', [device_id, service_uuid, characteristic_uuid]);
- },
- // RSSI value comes back as an integer
- readRSSI: function(device_id, success, failure) {
- cordova.exec(success, failure, 'BLE', 'readRSSI', [device_id]);
- },
- // value must be an ArrayBuffer
- write: function (device_id, service_uuid, characteristic_uuid, value, success, failure) {
- cordova.exec(success, failure, 'BLE', 'write', [device_id, service_uuid, characteristic_uuid, value]);
- },
- // value must be an ArrayBuffer
- writeWithoutResponse: function (device_id, service_uuid, characteristic_uuid, value, success, failure) {
- cordova.exec(success, failure, 'BLE', 'writeWithoutResponse', [device_id, service_uuid, characteristic_uuid, value]);
- },
- // value must be an ArrayBuffer
- writeCommand: function (device_id, service_uuid, characteristic_uuid, value, success, failure) {
- console.log("WARNING: writeCommand is deprecated, use writeWithoutResponse");
- cordova.exec(success, failure, 'BLE', 'writeWithoutResponse', [device_id, service_uuid, characteristic_uuid, value]);
- },
- // success callback is called on notification
- notify: function (device_id, service_uuid, characteristic_uuid, success, failure) {
- console.log("WARNING: notify is deprecated, use startNotification");
- cordova.exec(success, failure, 'BLE', 'startNotification', [device_id, service_uuid, characteristic_uuid]);
- },
- // success callback is called on notification
- startNotification: function (device_id, service_uuid, characteristic_uuid, success, failure) {
- cordova.exec(success, failure, 'BLE', 'startNotification', [device_id, service_uuid, characteristic_uuid]);
- },
- // success callback is called when the descriptor 0x2902 is written
- stopNotification: function (device_id, service_uuid, characteristic_uuid, success, failure) {
- cordova.exec(success, failure, 'BLE', 'stopNotification', [device_id, service_uuid, characteristic_uuid]);
- },
- isConnected: function (device_id, success, failure) {
- cordova.exec(success, failure, 'BLE', 'isConnected', [device_id]);
- },
- isEnabled: function (success, failure) {
- cordova.exec(success, failure, 'BLE', 'isEnabled', []);
- },
- enable: function (success, failure) {
- cordova.exec(success, failure, "BLE", "enable", []);
- },
- showBluetoothSettings: function (success, failure) {
- cordova.exec(success, failure, "BLE", "showBluetoothSettings", []);
- },
- startStateNotifications: function (success, failure) {
- cordova.exec(success, failure, "BLE", "startStateNotifications", []);
- },
- stopStateNotifications: function (success, failure) {
- cordova.exec(success, failure, "BLE", "stopStateNotifications", []);
- }
- };
- module.exports.withPromises = {
- scan: module.exports.scan,
- startScan: module.exports.startScan,
- startScanWithOptions: module.exports.startScanWithOptions,
- connect: module.exports.connect,
- startNotification: module.exports.startNotification,
- startStateNotifications: module.exports.startStateNotifications,
- stopScan: function() {
- return new Promise(function(resolve, reject) {
- module.exports.stopScan(resolve, reject);
- });
- },
- disconnect: function(device_id) {
- return new Promise(function(resolve, reject) {
- module.exports.disconnect(device_id, resolve, reject);
- });
- },
- read: function(device_id, service_uuid, characteristic_uuid) {
- return new Promise(function(resolve, reject) {
- module.exports.read(device_id, service_uuid, characteristic_uuid, resolve, reject);
- });
- },
- write: function(device_id, service_uuid, characteristic_uuid, value) {
- return new Promise(function(resolve, reject) {
- module.exports.write(device_id, service_uuid, characteristic_uuid, value, resolve, reject);
- });
- },
- writeWithoutResponse: function (device_id, service_uuid, characteristic_uuid, value) {
- return new Promise(function(resolve, reject) {
- module.exports.writeWithoutResponse(device_id, service_uuid, characteristic_uuid, value, resolve, reject);
- });
- },
- stopNotification: function (device_id, service_uuid, characteristic_uuid) {
- return new Promise(function(resolve, reject) {
- module.exports.stopNotification(device_id, service_uuid, characteristic_uuid, resolve, reject);
- });
- },
- isConnected: function (device_id) {
- return new Promise(function(resolve, reject) {
- module.exports.isConnected(device_id, resolve, reject);
- });
- },
- isEnabled: function () {
- return new Promise(function(resolve, reject) {
- module.exports.isEnabled(resolve, reject);
- });
- },
- enable: function () {
- return new Promise(function(resolve, reject) {
- module.exports.enable(resolve, reject);
- });
- },
- showBluetoothSettings: function () {
- return new Promise(function(resolve, reject) {
- module.exports.showBluetoothSettings(resolve, reject);
- });
- },
- stopStateNotifications: function () {
- return new Promise(function(resolve, reject) {
- module.exports.stopStateNotifications(resolve, reject);
- });
- },
- readRSSI: function(device_id) {
- return new Promise(function(resolve, reject) {
- module.exports.readRSSI(device_id, resolve, reject);
- });
- }
- };
|