Skip to content

Commit

Permalink
Support to connect multiple devices
Browse files Browse the repository at this point in the history
  • Loading branch information
evanxd committed Jun 19, 2015
1 parent 1e00174 commit 1428016
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 41 deletions.
38 changes: 38 additions & 0 deletions lib/bluetooth_device.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* global EventEmitter2 */
'use strict';

(function(exports) {
function BluetoothDevice(name, address) {
this.name = name;
this.address = address;
}

BluetoothDevice.prototype = Object.create(EventEmitter2.prototype);

['writeCharacteristic', 'notifyCharacteristic'].forEach(function(item) {
Object.defineProperty(BluetoothDevice.prototype, item, {
set: function(value) {
this['_' + item] = value;
},
get: function() {
return this['_' + item];
}
});
});

BluetoothDevice.prototype.send = function(data) {
data = this._parseHexString(data);
this.writeCharacteristic.writeValue(data);
};

BluetoothDevice.prototype._parseHexString = function(str) {
var arrayBuffer = new ArrayBuffer(Math.ceil(str.length / 2));
var uint8Array = new Uint8Array(arrayBuffer);
for (var i = 0, j = 0; i < str.length; i += 2, j++) {
uint8Array[j] = parseInt(str.substr(i, 2), 16);
}
return arrayBuffer;
};

exports.BluetoothDevice = BluetoothDevice;
}(window));
81 changes: 40 additions & 41 deletions lib/bluetooth_helper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global EventEmitter2 */
/* global BluetoothDevice */
'use strict';

(function(exports) {
Expand All @@ -7,58 +7,52 @@
var BLE_TX_UUID = '713d0002-503e-4c75-ba94-3148f18d941e';
var bluetooth = navigator.mozBluetooth;

function BluetoothHelper(name, address) {
this.name = name;
this.address = address;
function BluetoothHelper() {
this._devices = [];
this.startScan();
}

BluetoothHelper.prototype = Object.create(EventEmitter2.prototype);

BluetoothHelper.prototype.address = null,
BluetoothHelper.prototype.name = null,
BluetoothHelper.prototype.isConnected = false,
BluetoothHelper.prototype._bluetooth = null,
BluetoothHelper.prototype._devices = null,
BluetoothHelper.prototype._gatt = null,
BluetoothHelper.prototype._writeChar = null,
BluetoothHelper.prototype._notifyChar = null,
BluetoothHelper.prototype._isScanning = false,

BluetoothHelper.prototype.send = function(data) {
data = this._parseHexString(data);
this._writeChar.writeValue(data);
};
BluetoothHelper.prototype.addDevice = function(name, address) {
var device = new BluetoothDevice(name, address);
// TODO: Pop the device from array once it is disconnected.
this._devices.push(device);
return device;
},

BluetoothHelper.prototype._parseHexString = function(str) {
var arrayBuffer = new ArrayBuffer(Math.ceil(str.length / 2));
var uint8Array = new Uint8Array(arrayBuffer);
for (var i = 0, j = 0; i < str.length; i += 2, j++) {
uint8Array[j] = parseInt(str.substr(i, 2), 16);
BluetoothHelper.prototype.startScan = function() {
if (this._isScanning) {
return;
}
return arrayBuffer;
};

BluetoothHelper.prototype.connect = function() {
if (bluetooth.defaultAdapter) {
// For stability, We use startLeScan to instead of startDiscovery.
// For stability, We use startScan to instead of startDiscovery.
return bluetooth.defaultAdapter.startLeScan([]).then(scan => {
this._isScanning = true;
this._scan = scan;
scan.addEventListener('devicefound',
this._handleDevicefound.bind(this));
}).catch(() => {
this.connect();
this.startScan();
});
} else {
bluetooth.addEventListener('attributechanged',
this._handleAttributechanged.bind(this));
}
};

BluetoothHelper.prototype.disconnect = function() {
BluetoothHelper.prototype.stopScan = function() {
if (!this._isScanning) {
return;
}
if (this._gatt) {
return this._gatt.disconnect().then(() => {
return bluetooth.defaultAdapter.stopLeScan(this._scan);
}).then(() => {
this.emit('disconnected');
this.isConnected = false;
this._isScanning = false;
this.emit('scanningstoped');
});
} else {
return Promise.reject('GATT is undefined.');
Expand All @@ -71,7 +65,7 @@
case 'defaultAdapter':
bluetooth.removeEventListener('attributechanged',
this._handleAttributechanged);
this.connect();
this.startScan();
break;
}
}
Expand All @@ -81,34 +75,39 @@
var devcie = evt.device;
var gatt = devcie.gatt;
this._gatt = gatt;
if (devcie.name === this.name ||
devcie.address === this.address) {
this.name = devcie.name;
this.address = devcie.address;
devcie = this._devices.find(function(item) {
return (item.address === devcie.address ||
item.name === devcie.name) &&
!devcie.paired;
});
if (devcie) {
gatt.connect().then(() => {
return this._discoverServices();
this._discoverServices(devcie);
});
}
};

BluetoothHelper.prototype._discoverServices = function() {
BluetoothHelper.prototype._discoverServices = function(devcie) {
var gatt = this._gatt;
return gatt.discoverServices().then(() => {
var service = gatt.services.find(function(service) {
return service.uuid === BLE_SERVICE_UUID;
});
this._writeChar =
var writeCharacteristic =
service.characteristics.find(function(characteristic) {
return characteristic.uuid === BLE_RX_UUID;
});
this._notifyChar =
var notifyCharacteristic =
service.characteristics.find(function(characteristic) {
return characteristic.uuid === BLE_TX_UUID;
});
this.emit('connected');
this.isConnected = true;
devcie.writeCharacteristic = writeCharacteristic;
devcie.notifyCharacteristic = notifyCharacteristic;
devcie.emit('connected', devcie);
});
};

exports.Bluetooth = new BluetoothHelper();
// For testing.
exports.BluetoothHelper = BluetoothHelper;
}(window));

0 comments on commit 1428016

Please sign in to comment.