Press buttons to activate the LED.

Dependencies:   BLE_API nRF51822

Fork of Puck by Nordic Pucks

Revision:
10:67e4694f2d74
Parent:
8:49ffd38fb401
Parent:
9:ba0527c6b6d0
Child:
12:8a8cc109f048
Child:
16:fb8678ee25b0
--- a/Puck.h	Thu Jul 24 14:27:55 2014 +0000
+++ b/Puck.h	Fri Aug 01 07:45:38 2014 +0000
@@ -5,7 +5,7 @@
 #include <vector>
 #include "Log.h"
 
- enum PuckState {
+enum PuckState {
     CONNECTING,
     CONNECTED,
     ADVERTISING,
@@ -48,11 +48,15 @@
         void init(uint16_t minor);
         void startAdvertising();
         void stopAdvertising();
+        void disconnect();
         bool drive();
+        int countFreeMemory();
         void onDataWritten(uint16_t handle);
         void addCharacteristic(const UUID serviceUuid, const UUID characteristicUuid, int bytes, int properties = 0xA);
-        void onCharacteristicWrite(const UUID uuid, CharacteristicWriteCallback callback);
+
+        void onCharacteristicWrite(const UUID* uuid, CharacteristicWriteCallback callback);
         void updateCharacteristicValue(const UUID uuid, uint8_t* value, int length);
+
         uint8_t* getCharacteristicValue(const UUID uuid);
 };
 
@@ -79,14 +83,15 @@
 bool isEqualUUID(const UUID* uuidA, const UUID uuidB) {
     const uint8_t* uuidABase = uuidA->getBaseUUID();
     const uint8_t* uuidBBase = uuidB.getBaseUUID();
-    if(uuidA->getShortUUID() != uuidB.getShortUUID()) {
-        return false;
-    }
+    
     for(int i = 0; i < 16; i++) {
         if(uuidABase[i] != uuidBBase[i]) {
             return false;
         }
     }
+    if(uuidA->getShortUUID() != uuidB.getShortUUID()) {
+        return false;
+    }
     return true;
 }
 
@@ -98,6 +103,30 @@
     return UUID(array);
 }
 
+void Puck::disconnect() {
+    ble.disconnect();    
+}
+
+int Puck::countFreeMemory() {
+    int blocksize = 256;
+    int amount = 0;
+    while (blocksize > 0) {
+        amount += blocksize;
+        LOG_VERBOSE("Trying to malloc %i bytes... ", amount);
+        char *p = (char *) malloc(amount);
+        if (p == NULL) {
+            LOG_VERBOSE("FAIL!\n", amount);
+            amount -= blocksize;
+            blocksize /= 2;
+        } else {
+            free(p);
+            LOG_VERBOSE("OK!\n", amount);
+        }
+    }
+    LOG_DEBUG("Free memory: %i bytes.\n", amount);
+    return amount;
+}
+
 void Puck::setState(PuckState state) {
     LOG_DEBUG("Changed state to %i\n", state);
     this->state = state;    
@@ -129,29 +158,30 @@
     }
     
     ble.init();
-    LOG_VERBOSE("Inited BLEDevice.\n");
+    LOG_DEBUG("Inited BLEDevice.\n");
     setState(DISCONNECTED);
 
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
-    LOG_VERBOSE("Accumulate advertising payload: BREDR_NOT_SUPPORTED.\n");
+    LOG_DEBUG("Accumulate advertising payload: BREDR_NOT_SUPPORTED.\n");
     
     ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload));
-    LOG_VERBOSE("Accumulate advertising payload: beacon data.\n");
+    LOG_DEBUG("Accumulate advertising payload: beacon data.\n");
     
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    LOG_VERBOSE("Setting advertising type: ADV_CONNECTABLE_UNDIRECTED.\n");
+    LOG_DEBUG("Setting advertising type: ADV_CONNECTABLE_UNDIRECTED.\n");
     
     int hundredMillisecondsInAdvertisingIntervalFormat = 160;
     ble.setAdvertisingInterval(hundredMillisecondsInAdvertisingIntervalFormat); 
-    LOG_VERBOSE("Set advertising interval: 160 (100 ms).\n");
+    LOG_DEBUG("Set advertising interval: 160 (100 ms).\n");
     
     ble.onDisconnection(onDisconnection);
     ble.onConnection(onConnection);
     ble.onDataWritten(onDataWrittenCallback);
+    LOG_DEBUG("Hooked up internal event handlers.\n");
     
     for(int i = 0; i < services.size(); i++) {
         ble.addService(*services[i]);
-        LOG_VERBOSE("Added service %x to BLEDevice\n", services[i]);
+        LOG_DEBUG("Added service %x to BLEDevice\n", services[i]);
     }
     
     LOG_INFO("Inited puck as 0x%X.\n", minor);
@@ -176,12 +206,18 @@
 
 void Puck::addCharacteristic(const UUID serviceUuid, const UUID characteristicUuid, int bytes, int properties) {
     MBED_ASSERT(bytes <= 20);
-    
     uint16_t size = sizeof(uint8_t) * bytes;
     uint8_t* value = (uint8_t*) malloc(size);
+    if(value == NULL) {
+        LOG_ERROR("Unable to malloc value for characteristic. Possibly out of memory!\n");    
+    }
+    
     GattCharacteristic* characteristic = new GattCharacteristic(characteristicUuid, value, size, size, properties);
     characteristics.push_back(characteristic);
+    
+    
     GattService* service = NULL;
+    
     int removeIndex = -1;
     for(int i = 0; i < services.size(); i++) {
         if(isEqualUUID(&services[i]->getUUID(), serviceUuid)) {
@@ -195,6 +231,9 @@
     if(service != NULL) {
         characteristicsLength = service->getCharacteristicCount() + 1;
         characteristics = (GattCharacteristic**) malloc(sizeof(GattCharacteristic*) * characteristicsLength);
+        if(characteristics == NULL) {
+            LOG_ERROR("Unable to malloc array of characteristics for service creation. Possibly out of memory!\n");    
+        }
         for(int i = 0; i < characteristicsLength; i++) {
             characteristics[i] = service->getCharacteristic(i);    
         }
@@ -204,11 +243,16 @@
     } else {
         characteristicsLength = 1;
         characteristics = (GattCharacteristic**) malloc(sizeof(GattCharacteristic*) * characteristicsLength);
+        if(characteristics == NULL) {
+            LOG_ERROR("Unable to malloc array of characteristics for service creation. Possibly out of memory!\n");    
+        }
     }
+    
     characteristics[characteristicsLength - 1] = characteristic;
     previousCharacteristics = characteristics;
     service = new GattService(serviceUuid, characteristics, characteristicsLength);
     services.push_back(service);
+    LOG_DEBUG("Added characteristic.\n");
 }
 
 
@@ -234,27 +278,28 @@
         startAdvertising();    
     }
     while(pendingCallbackStack.size() > 0) {
-        LOG_VERBOSE("PendingCallbackStack size: %i\n", pendingCallbackStack.size());
         pendingCallbackStack.back()(pendingCallbackParameterStack.back());
         pendingCallbackStack.pop_back();
         pendingCallbackParameterStack.pop_back();
-        LOG_VERBOSE("Callback fired\n");
     }
     return true;
 }
 
 
-void Puck::onCharacteristicWrite(const UUID uuid, CharacteristicWriteCallback callback) {
+void Puck::onCharacteristicWrite(const UUID* uuid, CharacteristicWriteCallback callback) {
     CharacteristicWriteCallbacks* cb = NULL;
     for(int i = 0; i< writeCallbacks.size(); i++) {
-        if(isEqualUUID(writeCallbacks[i]->uuid, uuid)) {
+        if(isEqualUUID(writeCallbacks[i]->uuid, *uuid)) {
             cb = writeCallbacks[i];    
             break;
         }
     }
     if(cb == NULL) {
         cb = (CharacteristicWriteCallbacks*) malloc(sizeof(CharacteristicWriteCallbacks));
-        cb->uuid = &uuid;
+        if(cb == NULL) {
+            LOG_ERROR("Could not malloc CharacteristicWriteCallbacks container. Possibly out of memory!\n");    
+        }
+        cb->uuid = uuid;
         cb->callbacks = new std::vector<CharacteristicWriteCallback>();
         writeCallbacks.push_back(cb);
     }
@@ -289,8 +334,8 @@
                         pendingCallbackStack.push_back(characteristicWriteCallbacks->callbacks->at(k));
                         pendingCallbackParameterStack.push_back(characteristic->getValuePtr());
                     }
+                    return;
                 }
-                return;
             }
         }
     }