Last active
August 12, 2017 01:57
-
-
Save flavioribeiro/11915180bbcbc86dcc6acfc7253ecbef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016 Naran Inc. All rights reserved. | |
* __ _ _______ ______ _______ __ _ | |
* | | | | _ | _ | | _ | | | | | |
* | |_| | |_| | | || | |_| | |_| | | |
* | | | |_||_| | | | |
* | _ | | __ | | _ | | |
* | | | | _ | | | | _ | | | | | |
* |_| |__|__| |__|___| |_|__| |__|_| |__| | |
* | |
*/ | |
(function() { | |
'use strict'; | |
angular.module('app') | |
.service('BleService', BleService); | |
BleService.$inject = ['$rootScope', '$timeout']; | |
function BleService($rootScope, $timeout) { | |
var CONNECTED = 'connected'; | |
var DISCONNECTED = 'disconnected'; | |
var STATUS_CHECKED = 'status_checked'; | |
this.bootstrap = bootstrap; | |
this.scan = scan; | |
this.stopScan = stopScan; | |
this.write = write; | |
this.read = read; | |
this.startNotification = startNotification; | |
this.stopNotification = stopNotification; | |
this.connect = connect; | |
this.disconnect = disconnect; | |
this.isConnected = isConnected; | |
this.isEnabled = isEnabled; | |
this.enable = enable; | |
this.checkStatus = checkStatus; | |
this.pair = pair; | |
this.showBluetoothSettings = showBluetoothSettings; | |
this.mibService = '1831'; | |
this.mibChars = '2A91'; | |
this.revealChars = '2A13'; | |
this.ledChars = '2A14'; | |
this.getBoardVersion = '2A20'; | |
this.getVersion = '2A21'; | |
this.removePeerChars = '2A99'; | |
this.statusCheckChars = '2A98'; | |
this.pairChars = '2A90'; | |
this.blackBox = '2A87'; | |
this.setName = '2A97'; | |
this.battChars = '2A19'; | |
this.pushService = '1821'; | |
this.pushChars = '2A11'; | |
this.releaseChars = '2A12'; | |
this.calibrateChars = '2A35'; | |
this.pressChars = '2A18'; | |
this.doToggleChars = '2A77'; | |
this.invert = '2A53'; | |
this.state = '2A15'; | |
var isConnectionGoThrough = null; | |
function bootstrap(readyCallback) { | |
console.log('Try initialize BLE service.'); | |
ble.startStateNotifications(function(state) { | |
console.log("current ble state is: " + state); | |
$rootScope.$broadcast('ble_state_change', state); | |
console.log('Initialized BLE service, try checke determine whether or not is enable', state); | |
if (state === 'on' || state === 'off') { | |
ble.isEnabled(function() { | |
console.log("ble is enabled"); | |
readyCallback('enabled'); | |
}, function() { | |
console.log("ble is disabled"); | |
$rootScope.$broadcast('ble_disabled'); | |
readyCallback('disabled'); | |
}); | |
} else { | |
readyCallback('error'); | |
} | |
}, function() { | |
console.log("fail to listen for ble state"); | |
}); | |
} | |
function scan(successCallback, failCallback, second) { | |
if (!!second) { | |
ble.scan([], second, function(device) { | |
_handleCallback(successCallback, device); | |
}, function(error) { | |
console.log("ble_scan fails to scan", error); | |
_handleCallback(failCallback, error); | |
}); | |
} else { | |
ble.startScan([], function(device) { | |
_handleCallback(successCallback, device); | |
}, function() { | |
console.log("ble_scan fails to scan", error); | |
_handleCallback(failCallback, error); | |
}); | |
} | |
} | |
function stopScan(successCallback, failCallback) { | |
ble.stopScan(function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function write(deviceId, deviceService, deviceUuid, dataArray, successCallback, failCallback) { | |
ble.write(deviceId, deviceService, deviceUuid, dataArray.buffer, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function read(deviceId, deviceService, deviceUuid, successCallback, failCallback) { | |
ble.read(deviceId, deviceService, deviceUuid, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function startNotification(deviceId, deviceService, deviceUuid, successCallback, failCallback) { | |
ble.startNotification(deviceId, deviceService, deviceUuid, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function stopNotification(deviceId, deviceService, deviceUuid, successCallback, failCallback) { | |
ble.stopNotification(deviceId, deviceService, deviceUuid, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function connect(deviceId, successCallback, failCallback) { | |
ble.connect(deviceId, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
if (!!error) { | |
$rootScope.$broadcast('ble_disconnected'); | |
} | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function disconnect(deviceId, successCallback, failCallback) { | |
ble.disconnect(deviceId, function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function isConnected(deviceId, successCallback, failCallback) { | |
ble.isConnected(deviceId, function(res) { | |
_handleCallback(successCallback, true); | |
}, function(error) { | |
_handleCallback(failCallback, false); | |
}); | |
} | |
function isEnabled(successCallback, failCallback) { | |
ble.isEnabled(function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function enable(successCallback, failCallback) { | |
ble.enable(function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function showBluetoothSettings(successCallback, failCallback) { | |
ble.showBluetoothSettings(function(res) { | |
_handleCallback(successCallback, res); | |
}, function(error) { | |
_handleCallback(failCallback, error); | |
}); | |
} | |
function checkStatus(device, success, checkStatusFailure) { | |
startNotification(device.id, '1831', '2A98', function(buffer) { | |
var data = new Uint8Array(buffer); | |
var result = data[0]; | |
var macAddr = data[6].toString(16); | |
var num; | |
if (macAddr < 16) { | |
macAddr = '0' + macAddr; | |
} | |
for (var i = 5; i > 0; i--) { | |
if (parseInt(data[i]) < 16) { | |
num = '0' + data[i].toString(16); | |
} else { | |
num = data[i].toString(16); | |
} | |
macAddr = macAddr + ':' + num; | |
} | |
console.log("received Push status is: " + result); | |
success(result, macAddr); | |
}, function() { | |
if (checkStatusFailure) { | |
console.log("fail to receive notification for checkStatus"); | |
checkStatusFailure(); | |
} | |
}); | |
//Write status_check data to Push | |
//first write 4bytes of time data | |
//then write 16bytes of security data if have | |
var time = Math.floor((new Date).getTime() / 1000); | |
var timerArr = new Uint8Array([ | |
(time & 0xff000000) >> 24, | |
(time & 0x00ff0000) >> 16, | |
(time & 0x0000ff00) >> 8, | |
(time & 0x000000ff) | |
]); | |
var finalArray = new Uint8Array(20); | |
finalArray.set(timerArr, 0); | |
var securityArray; | |
if (!!device.security) { | |
securityArray = new Uint8Array(device.security); | |
finalArray.set(securityArray, 4); | |
} else { | |
securityArray = new Uint8Array(16); | |
finalArray.set(securityArray, 4); | |
} | |
console.log("ready to write to checkStatus characteristic"); | |
isConnectionGoThrough = false; | |
$timeout(function() { | |
if (isConnectionGoThrough === false) { | |
console.log("connection DOES NOT go through"); | |
if (checkStatusFailure) { | |
checkStatusFailure(); | |
} else { | |
disconnect(device.id); | |
} | |
} | |
}, 20000); | |
write(device.id, '1831', '2A98', finalArray, function() { | |
isConnectionGoThrough = true; | |
console.log("did write check status, now wait for response..."); | |
}, function() { | |
isConnectionGoThrough = true; | |
console.log("fail to write check status"); | |
if (checkStatusFailure) { | |
checkStatusFailure(); | |
} | |
}); | |
} | |
function pair(pairDevice, successCallback, failResponse, failRequest) { | |
startNotification(pairDevice.id, '1831', '2A90', function(buffer) { | |
var data = new Uint8Array(buffer); | |
successCallback(data); | |
}, function() { | |
failResponse(); | |
}); | |
var deviceId = device.uuid.split(":").join('').split("-").join('').split(''); | |
var deviceIdLength = deviceId.length; | |
if (deviceIdLength > 32) { | |
deviceIdLength = 32; | |
} | |
var deviceIdArr1 = new Uint8Array([0]); | |
var deviceIdArr2 = new Uint8Array([0]); | |
if (deviceIdLength < 20) { | |
deviceIdArr1 = new Uint8Array(deviceIdLength + 1); | |
} else { | |
deviceIdArr1 = new Uint8Array(20); | |
deviceIdArr2 = new Uint8Array(deviceIdLength - 20 + 1); | |
} | |
deviceIdArr1[0] = deviceIdLength; | |
for (var i=0; i<deviceIdLength; i++) { | |
if (i < 19) { | |
deviceIdArr1[i+1] = deviceId[i].charCodeAt(0); | |
} else { | |
deviceIdArr2[i-19] = deviceId[i].charCodeAt(0); | |
} | |
} | |
write(pairDevice.id, '1831', '2A90', deviceIdArr1, function() { | |
console.log("Did write pair 1"); | |
}, function() { | |
failRequest(); | |
}); | |
write(pairDevice.id, '1831', '2A90', deviceIdArr2, function() { | |
console.log("Did write pair 2"); | |
}, function() { | |
failRequest(); | |
}); | |
} | |
function _handleCallback(action, param) { | |
var callBack = action || $.noop; | |
callBack(param); | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment