// File easyble.dist.js 2016-08-15T11:27:33Z // This file was generated by buildDistFiles.rb // -------------------------------------------------- // File: evothings-dist-base.js // // Set up definitions needed by Evothings JavaScript libraries // distribution files. // // Global holding everything. window.evothings = window.evothings || {}; // Define an empty No Operation function. This function is called // in place of async script loading, since we build a single merged file. evothings.__NOOP_FUN__ = function() {}; // -------------------------------------------------- // File: evothings.js // // Here we define common function such as async script loading and OS detection. ;(function() { window.evothings = window.evothings || {}; /** * @namespace * @description
Functions for loading scripts asynchronously, * detecting platform, and other common application functionality.
* @alias evothings * @public */ var evothings = window.evothings; /* ------------------ Script loading ------------------ */ var mScriptLoadingCounter = 0; var mLoadedScripts = {}; var mScriptsLoadedCallbacks = []; /** * Make sure to catch any DOMContentLoaded events occurring before * asynchronous loading of scripts. Those scripts, like ui.js, should check * this variable before listening for the event. */ evothings.gotDOMContentLoaded = false; window.addEventListener('DOMContentLoaded', function(e) { evothings.gotDOMContentLoaded = true; }) /** * Load a script. * @param {string} url - URL or path to the script. Relative paths are * relative to the HTML file that initiated script loading. * @param {function} successCallback - Optional parameterless function that * will be called when the script has loaded. * @param {function} errorCallback - Optional function that will be called * if loading the script fails, takes an error object as parameter. * @public */ evothings.loadScript = function(url, successCallback, errorCallback) { // If script is already loaded call callback directly and return. if (mLoadedScripts[url] == 'loadingcomplete') { successCallback && successCallback(); return; } // Add script to dictionary of loaded scripts. mLoadedScripts[url] = 'loadingstarted'; ++mScriptLoadingCounter; // Create script tag. var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; // Bind the onload event. script.onload = function() { // Mark as loaded. mLoadedScripts[url] = 'loadingcomplete'; --mScriptLoadingCounter; // Call success callback if given. successCallback && successCallback(); // Call scripts loaded callbacks if this was the last script loaded. if (0 == mScriptLoadingCounter) { for (var i = 0; i < mScriptsLoadedCallbacks.length; ++i) { var loadedCallback = mScriptsLoadedCallbacks[i]; loadedCallback && loadedCallback(); } // Clear callbacks - should we do this??? mScriptsLoadedCallbacks = []; } }; // onerror fires for things like malformed URLs and 404's. // If this function is called, the matching onload will not be called and // scriptsLoaded will not fire. script.onerror = function(error) { errorCallback && errorCallback(error); }; // Attaching the script tag to the document starts loading the script. document.head.appendChild(script); }; /** * Load array of scripts. * @param {array} array - Array of URL or path name stringa. * Relative paths are relative to the HTML file that initiated * script loading. * @param {function} loadedCallback - Optional parameterless * function called when all scripts in the array has loaded. * @public */ evothings.loadScripts = function(array, loadedCallback) { var lib = array.shift(); if (!lib) { // Array is empty and all scripts are loaded. loadedCallback && loadedCallback(); } else { // Load next script. evothings.loadScript(lib, function() { evothings.loadScripts(array, loadedCallback); }); } }; /** * Experimental. * Mark a script as loaded. This is useful if a script is designed * to be included both in HTML and in JavaScript. * @param {string} pathOrURL - URL or path to the script. Relative paths are * relative to the HTML file that initiated script loading. * @public */ evothings.markScriptAsLoaded = function(pathOrURL) { mLoadedScripts[url] = 'loadingcomplete'; }; /** *Add a callback that will be called when all scripts are loaded.
*It is good practise to always use this function when * loading script asynchronously or using a library that does so.
* @param {function} callback - Parameterless function that will * be called when all scripts have finished loading. * @public */ evothings.scriptsLoaded = function(callback) { // If scripts are already loaded call the callback directly, // else add the callback to the callbacks array. if (0 != Object.keys(mLoadedScripts).length && 0 == mScriptLoadingCounter) { callback && callback(); } else { mScriptsLoadedCallbacks.push(callback); } }; /* ------------------ Debugging ------------------ */ /** * Print a JavaScript object (dictionary). For debugging. * * @param {Object} obj - Object to print. * @param {function} printFun - print function (optional - defaults to * console.log if not given). * * @example * var obj = { company: 'Evothings', field: 'IoT' }; * evothings.printObject(obj); * evothings.printObject(obj, console.log); * * @public */ evothings.printObject = function(obj, printFun) { printFun = printFun || console.log; function print(obj, level) { var indent = new Array(level + 1).join(' '); for (var prop in obj) { if (obj.hasOwnProperty(prop)) { var value = obj[prop]; if (typeof value == 'object') { printFun(indent + prop + ':'); print(value, level + 1); } else { printFun(indent + prop + ': ' + value); } } } } print(obj, 0); }; /* ------------------ Platform check ------------------ */ /** * @namespace * @description Namespace for platform check functions. */ evothings.os = {}; /** * Returns true if current platform is iOS, false if not. * @return {boolean} true if platform is iOS, false if not. * @public */ evothings.os.isIOS = function() { return /iP(hone|ad|od)/.test(navigator.userAgent); }; /** * Returns true if current platform is iOS 7, false if not. * @return {boolean} true if platform is iOS 7, false if not. * @public */ evothings.os.isIOS7 = function() { return /iP(hone|ad|od).*OS 7/.test(navigator.userAgent); }; /** * Returns true if current platform is Android, false if not. * @return {boolean} true if platform is Android, false if not. * @public */ evothings.os.isAndroid = function() { return /Android|android/.test(navigator.userAgent); }; /** * Returns true if current platform is Windows Phone, false if not. * @return {boolean} true if platform is Windows Phone, false if not. * @public */ evothings.os.isWP = function() { return /Windows Phone/.test(navigator.userAgent); }; })(); // -------------------------------------------------- // File: util.js evothings = window.evothings || {}; /** * @namespace * @author Aaron Ardiri * @author Fredrik Eldh * @description Utilities for byte arrays. */ evothings.util = {}; ;(function() { /** * Interpret byte buffer as little endian 8 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.littleEndianToInt8 = function(data, offset) { var x = evothings.util.littleEndianToUint8(data, offset) if (x & 0x80) x = x - 256 return x } /** * Interpret byte buffer as unsigned little endian 8 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.littleEndianToUint8 = function(data, offset) { return data[offset] } /** * Interpret byte buffer as little endian 16 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.littleEndianToInt16 = function(data, offset) { return (evothings.util.littleEndianToInt8(data, offset + 1) << 8) + evothings.util.littleEndianToUint8(data, offset) } /** * Interpret byte buffer as unsigned little endian 16 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.littleEndianToUint16 = function(data, offset) { return (evothings.util.littleEndianToUint8(data, offset + 1) << 8) + evothings.util.littleEndianToUint8(data, offset) } /** * Interpret byte buffer as unsigned little endian 32 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.littleEndianToUint32 = function(data, offset) { return (evothings.util.littleEndianToUint8(data, offset + 3) << 24) + (evothings.util.littleEndianToUint8(data, offset + 2) << 16) + (evothings.util.littleEndianToUint8(data, offset + 1) << 8) + evothings.util.littleEndianToUint8(data, offset) } /** * Interpret byte buffer as signed big endian 16 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.bigEndianToInt16 = function(data, offset) { return (evothings.util.littleEndianToInt8(data, offset) << 8) + evothings.util.littleEndianToUint8(data, offset + 1) } /** * Interpret byte buffer as unsigned big endian 16 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.bigEndianToUint16 = function(data, offset) { return (evothings.util.littleEndianToUint8(data, offset) << 8) + evothings.util.littleEndianToUint8(data, offset + 1) } /** * Interpret byte buffer as unsigned big endian 32 bit integer. * Returns converted number. * @param {ArrayBuffer} data - Input buffer. * @param {number} offset - Start of data. * @return Converted number. * @public */ evothings.util.bigEndianToUint32 = function(data, offset) { return (evothings.util.littleEndianToUint8(data, offset) << 24) + (evothings.util.littleEndianToUint8(data, offset + 1) << 16) + (evothings.util.littleEndianToUint8(data, offset + 2) << 8) + evothings.util.littleEndianToUint8(data, offset + 3) } /** * Converts a single Base64 character to a 6-bit integer. * @private */ function b64ToUint6(nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0; } /** * Decodes a Base64 string. Returns a Uint8Array. * nBlocksSize is optional. * @param {String} sBase64 * @param {int} nBlocksSize * @return {Uint8Array} * @public */ evothings.util.base64DecToArr = function(sBase64, nBlocksSize) { var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""); var nInLen = sB64Enc.length; var nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2; var taBytes = new Uint8Array(nOutLen); for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { nMod4 = nInIdx & 3; nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; if (nMod4 === 3 || nInLen - nInIdx === 1) { for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; } nUint24 = 0; } } return taBytes; } /** * Returns the integer i in hexadecimal string form, * with leading zeroes, such that * the resulting string is at least byteCount*2 characters long. * @param {int} i * @param {int} byteCount * @public */ evothings.util.toHexString = function(i, byteCount) { var string = (new Number(i)).toString(16); while(string.length < byteCount*2) { string = '0'+string; } return string; } /** * Takes a ArrayBuffer or TypedArray and returns its hexadecimal representation. * No spaces or linebreaks. * @param data * @public */ evothings.util.typedArrayToHexString = function(data) { // view data as a Uint8Array, unless it already is one. if(data.buffer) { if(!(data instanceof Uint8Array)) data = new Uint8Array(data.buffer); } else if(data instanceof ArrayBuffer) { data = new Uint8Array(data); } else { throw "not an ArrayBuffer or TypedArray."; } var str = ''; for(var i=0; iAn all-in-one file with this library and helper libraries included is * available in file easyble.dist.js. Include this file in index.html (recommended).
*If you include easyble.js
rather than easyble.dist.js
it is safe practise to call function {@link evothings.scriptsLoaded}
* to ensure dependent libraries are loaded before calling functions
* in this library (in this case you also need to have the dependent library folders).
On Android you can disable automatic write of notify/indicate and write * the configuration descriptor yourself, supply an options object as * last parameter, see example below.
* @param {string} serviceUUID - UUID of service that has the given * characteristic (previous versions of this library allowed leaving out * the service UUID, this is unsafe practice and has been deprecated, always * specify the service UUID). * @param {string} characteristicUUID - UUID of characteristic to subscribe to. * @param {evothings.easyble.dataCallback} success - Success callback: * success(data). * @param {evothings.easyble.failCallback} fail - Error callback: fail(error). * @param {evothings.easyble.NotificationOptions} [options] - Optional settings. * @public * @instance * @example * // Example call: * device.enableNotification( * serviceUUID, * characteristicUUID, * function(data) * { * console.log('characteristic data: ' + evothings.ble.fromUtf8(data)); * }, * function(errorCode) * { * console.log('enableNotification error: ' + errorCode); * }); * * // Turn off automatic writing of the config descriptor (for special cases): * device.enableNotification( * serviceUUID, * characteristicUUID, * function(data) * { * console.log('characteristic data: ' + evothings.ble.fromUtf8(data)); * }, * function(errorCode) * { * console.log('enableNotification error: ' + errorCode); * }, * { writeConfigDescriptor: false }); */ device.enableNotification = function(arg1, arg2, arg3, arg4, arg5) { if ('function' == typeof arg2) { // Service UUID is missing. internal.enableNotification(device, arg1, arg2, arg3, arg4); } else { // Service UUID is present. internal.enableServiceNotification(device, arg1, arg2, arg3, arg4, arg5); } }; /** * Deprecated. * Use function {@link evothings.easyble.EasyBLEDevice#enableNotification} * @deprecated * @instance */ device.enableServiceNotification = function( serviceUUID, characteristicUUID, success, fail, options) { internal.enableServiceNotification( device, serviceUUID, characteristicUUID, success, fail, options); }; /** * Unsubscribe from characteristic updates to stop notifications. *On Android you can disable automatic write of notify/indicate and write * the configuration descriptor yourself, supply an options object as * last parameter, see example below.
* @param {string} serviceUUID - UUID of service that has the given * characteristic (previous versions of this library allowed leaving out * the service UUID, this is unsafe practice and has been deprecated, always * specify the service UUID). * @param serviceUUID - UUID of service that has the given characteristic. * @param characteristicUUID - UUID of characteristic to unsubscribe from. * @param {evothings.easyble.emptyCallback} success - Success callback: success() * @param {evothings.easyble.failCallback} fail - Error callback: fail(error) * @param {evothings.easyble.NotificationOptions} [options] - Optional settings. * @public * @instance * @example * // Example call: * device.disableNotification( * serviceUUID, * characteristicUUID, * function() * { * console.log('characteristic notification disabled'); * }, * function(errorCode) * { * console.log('disableNotification error: ' + errorCode); * }); */ device.disableNotification = function(arg1, arg2, arg3, arg4, arg5) { if ('function' == typeof arg2) { // Service UUID is missing. internal.disableNotification(device, arg1, arg2, arg3, arg4); } else { // Service UUID is present. internal.disableServiceNotification(device, arg1, arg2, arg3, arg4, arg5); } }; /** * Deprecated. * Use function {@link evothings.easyble.EasyBLEDevice#disableNotification} * @deprecated * @instance */ device.disableServiceNotification = function( serviceUUID, characteristicUUID, success, fail, options) { internal.disableServiceNotification( device, serviceUUID, characteristicUUID, success, fail, options); }; }; /** * Connect to a device. * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.connectToDevice = function(device, success, fail) { // Check that device is not already connected. if (device.__isConnected) { fail(evothings.easyble.error.DEVICE_ALREADY_CONNECTED); return; } evothings.ble.connect( device.address, // Success callback. function(connectInfo) { // DEBUG LOG console.log('BLE connect state: ' + connectInfo.state); if (connectInfo.state == 2) // connected { device.deviceHandle = connectInfo.deviceHandle; device.__uuidMap = {}; device.__serviceMap = {}; device.__isConnected = true; internal.connectedDevices[device.address] = device; success(device); } else if (connectInfo.state == 0) // disconnected { device.__isConnected = false; internal.connectedDevices[device.address] = null; // TODO: Perhaps this should be redesigned, as disconnect is // more of a status change than an error? What do you think? fail && fail(evothings.easyble.error.DISCONNECTED); } }, // Error callback. function(errorCode) { // DEBUG LOG console.log('BLE connect error: ' + errorCode); // Set isConnected to false on error. device.__isConnected = false; internal.connectedDevices[device.address] = null; fail(errorCode); }); }; /** * Obtain device services, them read characteristics and descriptors * for the services with the given uuid(s). * If serviceUUIDs is null, info is read for all services. * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.readServices = function(device, serviceUUIDs, success, fail) { // Read services. evothings.ble.services( device.deviceHandle, function(services) { // Array that stores services. device.__services = []; for (var i = 0; i < services.length; ++i) { var service = services[i]; service.uuid = service.uuid.toLowerCase(); device.__services.push(service); device.__uuidMap[service.uuid] = service; } internal.readCharacteristicsForServices( device, serviceUUIDs, success, fail); }, function(errorCode) { fail(errorCode); }); }; /** * Read characteristics and descriptors for the services with the given uuid(s). * If serviceUUIDs is null, info for all services are read. * Internal function. * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.readCharacteristicsForServices = function(device, serviceUUIDs, success, fail) { var characteristicsCallbackFun = function(service) { // Array with characteristics for service. service.__characteristics = []; return function(characteristics) { --readCounter; // Decrements the count added by services. readCounter += characteristics.length; for (var i = 0; i < characteristics.length; ++i) { var characteristic = characteristics[i]; characteristic.uuid = characteristic.uuid.toLowerCase(); service.__characteristics.push(characteristic); device.__uuidMap[characteristic.uuid] = characteristic; device.__serviceMap[service.uuid + ':' + characteristic.uuid] = characteristic; // DEBUG LOG //console.log('storing service:characteristic key: ' + service.uuid + ':' + characteristic.uuid); //if (!characteristic) //{ // console.log(' --> characteristic is null!') //} // Read descriptors for characteristic. evothings.ble.descriptors( device.deviceHandle, characteristic.handle, descriptorsCallbackFun(service, characteristic), function(errorCode) { fail(errorCode); }); } }; }; /** * @private */ var descriptorsCallbackFun = function(service, characteristic) { // Array with descriptors for characteristic. characteristic.__descriptors = []; return function(descriptors) { --readCounter; // Decrements the count added by characteristics. for (var i = 0; i < descriptors.length; ++i) { var descriptor = descriptors[i]; descriptor.uuid = descriptor.uuid.toLowerCase(); characteristic.__descriptors.push(descriptor); device.__uuidMap[characteristic.uuid + ':' + descriptor.uuid] = descriptor; device.__serviceMap[service.uuid + ':' + characteristic.uuid + ':' + descriptor.uuid] = descriptor; } if (0 == readCounter) { // Everything is read. success(device); } }; }; // Initialize read counter. readCounter = 0; if (null != serviceUUIDs) { // Read info for service UUIDs. readCounter = serviceUUIDs.length; for (var i = 0; i < serviceUUIDs.length; ++i) { var uuid = serviceUUIDs[i].toLowerCase(); var service = device.__uuidMap[uuid]; if (!service) { fail(evothings.easyble.error.SERVICE_NOT_FOUND + ' ' + uuid); return; } // Read characteristics for service. Will also read descriptors. evothings.ble.characteristics( device.deviceHandle, service.handle, characteristicsCallbackFun(service), function(errorCode) { fail(errorCode); }); } } else { // Read info for all services. readCounter = device.__services.length; for (var i = 0; i < device.__services.length; ++i) { // Read characteristics for service. Will also read descriptors. var service = device.__services[i]; evothings.ble.characteristics( device.deviceHandle, service.handle, characteristicsCallbackFun(service), function(errorCode) { fail(errorCode); }); } } }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.readCharacteristic = function(device, characteristicUUID, success, fail) { characteristicUUID = characteristicUUID.toLowerCase(); var characteristic = device.__uuidMap[characteristicUUID]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + characteristicUUID); return; } evothings.ble.readCharacteristic( device.deviceHandle, characteristic.handle, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.readServiceCharacteristic = function( device, serviceUUID, characteristicUUID, success, fail) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase(); var characteristic = device.__serviceMap[key]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + key); return; } evothings.ble.readCharacteristic( device.deviceHandle, characteristic.handle, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.readDescriptor = function( device, characteristicUUID, descriptorUUID, success, fail) { characteristicUUID = characteristicUUID.toLowerCase(); descriptorUUID = descriptorUUID.toLowerCase(); var descriptor = device.__uuidMap[characteristicUUID + ':' + descriptorUUID]; if (!descriptor) { fail(evothings.easyble.error.DESCRIPTOR_NOT_FOUND + ' ' + descriptorUUID); return; } evothings.ble.readDescriptor( device.deviceHandle, descriptor.handle, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.readServiceDescriptor = function( device, serviceUUID, characteristicUUID, descriptorUUID, success, fail) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase() + ':' + descriptorUUID.toLowerCase(); var descriptor = device.__serviceMap[key]; if (!descriptor) { fail(evothings.easyble.error.DESCRIPTOR_NOT_FOUND + ' ' + key); return; } evothings.ble.readDescriptor( device.deviceHandle, descriptor.handle, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.writeCharacteristic = function( device, characteristicUUID, value, success, fail) { characteristicUUID = characteristicUUID.toLowerCase(); var characteristic = device.__uuidMap[characteristicUUID]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + characteristicUUID); return; } evothings.ble.writeCharacteristic( device.deviceHandle, characteristic.handle, value, function() { success(); }, function(errorCode) { fail(errorCode); }); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.writeServiceCharacteristic = function( device, serviceUUID, characteristicUUID, value, success, fail) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase(); var characteristic = device.__serviceMap[key]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + key); return; } evothings.ble.writeCharacteristic( device.deviceHandle, characteristic.handle, value, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.writeServiceCharacteristicWithoutResponse = function( device, serviceUUID, characteristicUUID, value, success, fail) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase(); // DEBUG LOG //console.log('internal.writeServiceCharacteristicWithoutResponse key: ' + key) //console.log('internal.writeServiceCharacteristicWithoutResponse serviceMap:') for (var theKey in device.__serviceMap) { console.log(' ' + theKey); } var characteristic = device.__serviceMap[key]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + key); return; } evothings.ble.writeCharacteristicWithoutResponse( device.deviceHandle, characteristic.handle, value, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.writeDescriptor = function( device, characteristicUUID, descriptorUUID, value, success, fail) { characteristicUUID = characteristicUUID.toLowerCase(); descriptorUUID = descriptorUUID.toLowerCase(); var descriptor = device.__uuidMap[characteristicUUID + ':' + descriptorUUID]; if (!descriptor) { fail(evothings.easyble.error.DESCRIPTOR_NOT_FOUND + ' ' + descriptorUUID); return; } evothings.ble.writeDescriptor( device.deviceHandle, descriptor.handle, value, function() { success(); }, function(errorCode) { fail(errorCode); }); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.writeServiceDescriptor = function( device, serviceUUID, characteristicUUID, descriptorUUID, value, success, fail) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase() + ':' + descriptorUUID.toLowerCase(); var descriptor = device.__serviceMap[key]; if (!descriptor) { fail(evothings.easyble.error.DESCRIPTOR_NOT_FOUND + ' ' + key); return; } evothings.ble.writeDescriptor( device.deviceHandle, descriptor.handle, value, success, fail); }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.enableNotification = function( device, characteristicUUID, success, fail, options) { characteristicUUID = characteristicUUID.toLowerCase(); var characteristic = device.__uuidMap[characteristicUUID]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + characteristicUUID); return; } evothings.ble.enableNotification( device.deviceHandle, characteristic.handle, success, fail, options); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.enableServiceNotification = function( device, serviceUUID, characteristicUUID, success, fail, options) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase(); var characteristic = device.__serviceMap[key]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + key); return; } evothings.ble.enableNotification( device.deviceHandle, characteristic.handle, success, fail, options); }; /** * Called from evothings.easyble.EasyBLEDevice. * @deprecated Naming is a bit confusing, internally functions * named "xxxServiceYYY" are the "future-safe" onces, but in * the public API functions "xxxYYY" are new "future-safe" * (and backwards compatible). * @private */ internal.disableNotification = function( device, characteristicUUID, success, fail, options) { characteristicUUID = characteristicUUID.toLowerCase(); var characteristic = device.__uuidMap[characteristicUUID]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + characteristicUUID); return; } evothings.ble.disableNotification( device.deviceHandle, characteristic.handle, success, fail, options); }; /** * Called from evothings.easyble.EasyBLEDevice. * @private */ internal.disableServiceNotification = function( device, serviceUUID, characteristicUUID, success, fail, options) { var key = serviceUUID.toLowerCase() + ':' + characteristicUUID.toLowerCase(); var characteristic = device.__serviceMap[key]; if (!characteristic) { fail(evothings.easyble.error.CHARACTERISTIC_NOT_FOUND + ' ' + key); return; } evothings.ble.disableNotification( device.deviceHandle, characteristic.handle, success, fail, options); }; /** * Prints and object for debugging purposes. * @deprecated. Defined here for backwards compatibility. * Use evothings.printObject(). * @public */ evothings.easyble.printObject = evothings.printObject; /** * Reset the BLE hardware. Can be time consuming. * @public */ evothings.easyble.reset = function() { evothings.ble.reset(); }; })(); // --------------------------------------------------