Skip to content

Commit

Permalink
Refactored discovery functions, resolves #4
Browse files Browse the repository at this point in the history
  • Loading branch information
thegecko committed Aug 23, 2015
1 parent 0224cda commit 16a5c2c
Show file tree
Hide file tree
Showing 12 changed files with 491 additions and 356 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
.DS_Store
node_modules
*.sublime-*
44 changes: 43 additions & 1 deletion README.md
Expand Up @@ -137,13 +137,15 @@ string serviceUUID: service to search for
Connect to the device.

```
void device.connect(connectFn, disconnectFn);
void device.connect(connectFn, [disconnectFn], [suppressDiscovery]);
```

function connectFn(): callback once connected

function disconnectFn(): callback when disconnected

bool suppressDiscovery: don't undertake automatic discovery of services, characteristics and descriptors

#### device.disconnect

Disconnect from device.
Expand All @@ -152,6 +154,26 @@ Disconnect from device.
void device.disconnect();
```

#### device.discoverServices

Discover all services for this device

```
void device.discoverServices(callbackFn)
```

function callbackFn(): callback once discovery complete

#### device.discoverAll

Discover all services, characteristics and descriptors for this device

```
void device.discoverAll(callbackFn)
```

function callbackFn(): callback once discovery complete

### Service

string uuid: uuid of service
Expand All @@ -160,6 +182,16 @@ bool primary: whether service is primary or not

object characteristics: map of service characteristics keyed on characteristic uuid

#### service.discoverCharacteristics

Discover all characteristics for this service

```
void service.discoverCharacteristics(callbackFn)
```

function callbackFn(): callback once discovery complete

### Characteristic

string uuid: uuid of characteristic
Expand Down Expand Up @@ -212,6 +244,16 @@ void characteristic.disableNotify(completeFn);

function completeFn(): callback function once completed

#### characteristic.discoverDescriptors

Discover all descriptors for this characteristic

```
void characteristic.discoverDescriptors(callbackFn)
```

function callbackFn(): callback once discovery complete

### Descriptor

string uuid: uuid of descriptor
Expand Down
69 changes: 35 additions & 34 deletions dist/bleat.chromeos.js
@@ -1,7 +1,7 @@
/* @license
*
* BLE Abstraction Tool: chromeos adapter
* Version: 0.0.6
* Version: 0.0.7
*
* The MIT License (MIT)
*
Expand Down Expand Up @@ -30,15 +30,15 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['bleat.core'], factory.bind(this, root));
define(['bleat.core'], factory.bind(this, root.chrome));
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS
module.exports = factory(root, require('./bleat.core'));
module.exports = factory(root.chrome, require('./bleat.core'));
} else {
// Browser globals with support for web workers (root is window)
factory(root, root.bleat);
factory(root.chrome, root.bleat);
}
}(this, function(root, bleat) {
}(this, function(chrome, bleat) {
"use strict";

function checkForError(errorFn, continueFn) {
Expand All @@ -55,7 +55,7 @@
}

// https://developer.chrome.com/apps/bluetoothLowEnergy
if (root.chrome && root.chrome.bluetooth && root.chrome.bluetoothLowEnergy) {
if (chrome && chrome.bluetooth && chrome.bluetoothLowEnergy) {

bleat.addAdapter("chromeos", {
charNotifies: {},
Expand Down Expand Up @@ -108,39 +108,40 @@
},
connect: function(device, connectFn, disconnectFn, errorFn) {
chrome.bluetoothLowEnergy.connect(device.address, checkForError(errorFn, function() {

this.deviceDisconnects[device.address] = function() {
device.connected = false;
device.services = {};
disconnectFn();
};
device.connected = true;

chrome.bluetoothLowEnergy.getServices(device.address, checkForError(errorFn, function(services) {
services.forEach(function(serviceInfo) {
var service = new bleat.Service(serviceInfo.uuid, serviceInfo.instanceId, serviceInfo.isPrimary);
device.services[service.uuid] = service;
chrome.bluetoothLowEnergy.getCharacteristics(serviceInfo.instanceId, checkForError(errorFn, function(characteristics) {
characteristics.forEach(function(characteristicInfo) {
var characteristic = new bleat.Characteristic(characteristicInfo.uuid, characteristicInfo.instanceId, characteristicInfo.properties);
service.characteristics[characteristic.uuid] = characteristic;

chrome.bluetoothLowEnergy.getDescriptors(characteristicInfo.instanceId, checkForError(errorFn, function(descriptors) {
descriptors.forEach(function(descriptorInfo) {
var descriptor = new bleat.Descriptor(descriptorInfo.uuid, descriptorInfo.instanceId);
characteristic.descriptors[descriptor.uuid] = descriptor;
});
}));
});
}));
});
setTimeout(connectFn, 0);
}));
this.deviceDisconnects[device.address] = disconnectFn;
connectFn();
}.bind(this)));
},
disconnect: function(device, errorFn) {
chrome.bluetoothLowEnergy.disconnect(device.address, checkForError(errorFn));
},
discoverServices: function(device, completeFn, errorFn) {
chrome.bluetoothLowEnergy.getServices(device.address, checkForError(errorFn, function(services) {
services.forEach(function(serviceInfo) {
var service = new bleat.Service(serviceInfo.instanceId, serviceInfo.uuid, serviceInfo.isPrimary);
device.services[service.uuid] = service;
});
completeFn();
}));
},
discoverCharacteristics: function(service, completeFn, errorFn) {
chrome.bluetoothLowEnergy.getCharacteristics(service._handle, checkForError(errorFn, function(characteristics) {
characteristics.forEach(function(characteristicInfo) {
var characteristic = new bleat.Characteristic(characteristicInfo.instanceId, characteristicInfo.uuid, characteristicInfo.properties);
service.characteristics[characteristic.uuid] = characteristic;
});
completeFn();
}));
},
discoverDescriptors: function(characteristic, completeFn, errorFn) {
chrome.bluetoothLowEnergy.getDescriptors(characteristic._handle, checkForError(errorFn, function(descriptors) {
descriptors.forEach(function(descriptorInfo) {
var descriptor = new bleat.Descriptor(descriptorInfo.instanceId, descriptorInfo.uuid);
characteristic.descriptors[descriptor.uuid] = descriptor;
});
completeFn();
}));
},
readCharacteristic: function(characteristic, completeFn, errorFn) {
chrome.bluetoothLowEnergy.readCharacteristicValue(characteristic.handle, checkForError(errorFn, function(characteristicInfo) {
completeFn(characteristicInfo.value);
Expand Down
107 changes: 66 additions & 41 deletions dist/bleat.core.js
@@ -1,7 +1,7 @@
/* @license
*
* BLE Abstraction Tool: core functionality
* Version: 0.0.13
* Version: 0.0.14
*
* The MIT License (MIT)
*
Expand Down Expand Up @@ -61,12 +61,28 @@
};
}

function AsyncWait(finishFn) {
var count = 0;
var callbackAdded = false;
this.addCallback = function(fn) {
count++;
callbackAdded = true;
return function() {
if (fn) fn.apply(null, arguments);
if (--count === 0 && finishFn) finishFn();
};
};
this.finish = function() {
if (!callbackAdded && finishFn) finishFn();
};
}

// Device Object
var Device = function(address, name, serviceUUIDs) {
this.address = address;
this.name = name;
this.connected = false;
this.serviceUUIDs = serviceUUIDs;
this.connected = false;
this.services = {};
};
Device.prototype.hasService = function(serviceUUID) {
Expand All @@ -79,25 +95,60 @@
});
return found;
};
Device.prototype.connect = function(connectFn, disconnectFn) {
adapter.connect(this, executeFn(connectFn), executeFn(disconnectFn), raiseError("connect error"));
Device.prototype.connect = function(connectFn, disconnectFn, suppressDiscovery) {
adapter.connect(this, function() {
this.connected = true;
if (suppressDiscovery) return executeFn(connectFn)();
this.discoverAll(connectFn);
}.bind(this), function() {
this.connected = false;
this.services = {};
executeFn(disconnectFn)();
}.bind(this), raiseError("connect error"));
};
Device.prototype.disconnect = function() {
adapter.disconnect(this, raiseError("disconnect error"));
};
Device.prototype.discoverServices = function(completeFn) {
if (this.connected === false) return raiseError("discovery error")("device not connected");
adapter.discoverServices(this, executeFn(completeFn), raiseError("service discovery error"));
};
Device.prototype.discoverAll = function(completeFn) {
if (this.connected === false) return raiseError("discovery error")("device not connected");
var wait = new AsyncWait(completeFn);

this.discoverServices(wait.addCallback(function() {
Object.keys(this.services).forEach(function(serviceUUID) {
var service = this.services[serviceUUID];

service.discoverCharacteristics(wait.addCallback(function() {
Object.keys(service.characteristics).forEach(function(characteristicUUID) {
var characteristic = service.characteristics[characteristicUUID];
characteristic.discoverDescriptors(wait.addCallback());
}, this);
}.bind(this)));

}, this);
}.bind(this)));

wait.finish();
};

// Service Object
var Service = function(uuid, handle, primary) {
var Service = function(handle, uuid, primary) {
this._handle = handle;
this.uuid = uuid;
this.handle = handle;
this.primary = primary;
this.characteristics = {};
};
Service.prototype.discoverCharacteristics = function(completeFn) {
adapter.discoverCharacteristics(this, executeFn(completeFn), raiseError("characteristic discovery error"));
};

// Characteristic Object
var Characteristic = function(uuid, handle, properties) {
var Characteristic = function(handle, uuid, properties) {
this._handle = handle;
this.uuid = uuid;
this.handle = handle;
this.properties = properties;
this.descriptors = {};
};
Expand All @@ -113,11 +164,14 @@
Characteristic.prototype.disableNotify = function(completeFn) {
adapter.disableNotify(this, executeFn(completeFn), raiseError("disable notify error"));
};
Characteristic.prototype.discoverDescriptors = function(completeFn) {
adapter.discoverDescriptors(this, executeFn(completeFn), raiseError("descriptor discovery error"));
};

// Descriptor Object
var Descriptor = function(uuid, handle) {
var Descriptor = function(handle, uuid) {
this._handle = handle;
this.uuid = uuid;
this.handle = handle;
};
Descriptor.prototype.read = function(completeFn) {
adapter.readDescriptor(this, executeFn(completeFn), raiseError("read descriptor error"));
Expand All @@ -138,8 +192,8 @@
init: function(readyFn, errorFn, adapterName) {
onError = errorFn;
if (adapterName) adapter = adapters[adapterName];
if (!adapter) raiseError("init error")("adapter not found");
else adapter.init(executeFn(readyFn), raiseError("init error"));
if (!adapter) return raiseError("init error")("adapter not found");
adapter.init(executeFn(readyFn), raiseError("init error"));
},
startScan: function(foundFn) {
adapter.stop(raiseError("stop scan error"));
Expand All @@ -153,35 +207,6 @@
stopScan: function() {
adapter.stop(raiseError("stop scan error"));
},
asyncWait: function(finishFn, errorFn) {
var count = 0;
var callbackAdded = false;
this.addCallback = function(fn) {
count++;
callbackAdded = true;
return function() {
if (fn) {
fn.apply(null, arguments);
}
if (--count == 0 && finishFn) {
finishFn();
}
}
};
this.error = function() {
if (errorFn) {
errorFn.apply(null, arguments);
}
if (--count == 0 && finishFn) {
finishFn();
}
};
this.finish = function() {
if (!callbackAdded && finishFn) {
finishFn();
}
};
},
Device: Device,
Service: Service,
Characteristic: Characteristic,
Expand Down

0 comments on commit 16a5c2c

Please sign in to comment.