Skip to content

Commit

Permalink
mac - add strategy for adding / removing attribute ID's
Browse files Browse the repository at this point in the history
  • Loading branch information
brycejacobs committed Sep 20, 2015
1 parent 13ce04e commit 9aadb01
Showing 1 changed file with 63 additions and 5 deletions.
68 changes: 63 additions & 5 deletions lib/mac/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,57 @@ blenoBindings.on('kCBMsgId17', function(args) {
});

blenoBindings.addService = function AddGATTService(service) {
var attributeId = this._attributes.length ? this._attributes.length - 1 : 1;
var attributeId;
var attributeCount = 1 + service.characteristics.length;
var attributes = this._attributes;

/**
* The goal is to find an attribute range that can host the full service, which in most cases will be the next available push
* position. In the edge case, where our attribute consumes more Id's than the standard permits (0xFFFF), we must find
* a place within our attributes array that has been vacated or throw an error.
*/
if(!attributes.length){
atrributeId = 1;
} else if((attributes.length - 1 + attributeCount) >= 0xFFFF){
// perform search to find somewhere within our attributes array that contains a hole that can host the attributeCount
var consecutiveCount = 0;
var groupedOpenings = {};
for(var i = 0, ii = attributes.length; i++){
var attribute = attributes[i];
if(!attribute.kCBMsgArgAttributeID){
consecutiveCount++;
} else if(attribute.kCBMsgArgAttributeID && consecutiveCount){

// If we have found this amount of openings before, don't mark in our group so we use the first available.
if(!groupedOpenings[consecutiveCount].start){
var start = i - 1 - consecutiveCount;
var end = i + consecutiveCount - 1;
groupedOpenings[consecutiveCount] = { start: start, end: end};

if(consecutiveCount === attributeCount){
break;
}
}
consecutiveCount = 0;
}
}

if(groupedOpenings[attributeCount].start){
attributeId = groupedOpenings[attributeCount].start;
} else {
for(var openingCount in groupedOpenings){
if(parseInt(openingCount, 10) > attributeCount){
attributeId = groupedOpenings[openingCount].start;
break;
}
}
}

if(!attributeId){
throw new Error('Not enough space to add service.');
}
}

var arg = {
kCBMsgArgAttributeID: attributeId,
kCBMsgArgAttributeIDs: [],
Expand Down Expand Up @@ -225,6 +275,7 @@ blenoBindings.addService = function AddGATTService(service) {
kCBMsgArgUUID: new Buffer(characteristic.uuid, 'hex')
};
this._attributes[attributeId] = characteristic;
characteristic.attributeId = attributeId;

for (var k = 0; k < characteristic.descriptors.length; k++) {
var descriptor = characteristic.descriptors[k];
Expand All @@ -241,17 +292,24 @@ blenoBindings.addService = function AddGATTService(service) {
};

blenoBindings.removeService = function RemoveGATTService(service){
var attributeId = this._attributes[service.attributeId];
var attributes = this._attributes;
var attributeId = service.attributeId;
var attribute = attributes[attributeId];
for(var i = 0, ii = attribute.characteristics.length; i < ii; i++){
var characteristic = attribute.characteristics[i];
attributes[characteristic.attributeId] = {};
}
attributes[attributeId] = {};
var messageBody = {
kCBMsgArgAttributeID: attributeId
};
this._attributes[service.attributeId] = {};
this.sendCBMsg(11, attributeId);
}
};

blenoBindings.removeAllServices = function RemoveAllGATTServices(){
this._attributes = [];
this.sendCBMsg(12, null);
}
};

blenoBindings.setServices = function SetGATTServices(services) {
this.sendCBMsg(12, null);
Expand Down

0 comments on commit 9aadb01

Please sign in to comment.