Jan Jongboom / Mbed 2 deprecated HPE_LightSensor

Dependencies:   BLE_API mbed nRF51822

Revision:
0:0c885d287f5a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleBLE.h	Mon May 09 13:19:09 2016 +0000
@@ -0,0 +1,210 @@
+/**
+ * Because BLE_API is too hard
+ */
+#include <string>
+#include <vector>
+#include <map>
+#include "ble/BLE.h"
+
+using namespace std;
+
+template <class T>
+class ReadOnlyCharacteristic {
+public:
+    ReadOnlyCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) :
+        ble(aBle)
+    {
+        state = new ReadOnlyGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 
+            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY :
+            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+    }
+    
+    ~ReadOnlyCharacteristic() {
+        // @todo clear defaultValue
+        if (state) {
+            free(state);
+        }
+    }
+    
+    void update(T newValue) {
+        ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T));
+    }
+    
+    ReadOnlyGattCharacteristic<T>* getChar(void) {
+        return state;
+    }
+
+private:
+    BLE* ble;
+    ReadOnlyGattCharacteristic<T>* state;
+};
+
+template <class T>
+class ReadWriteCharacteristic {
+public:
+    ReadWriteCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) :
+        ble(aBle)
+    {
+        state = new ReadWriteGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 
+            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY :
+            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+    }
+    
+    ~ReadWriteCharacteristic() {
+        // @todo clear defaultValue
+        if (state) {
+            free(state);
+        }
+    }
+    
+    void update(T newValue) {
+        ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T));
+    }
+    
+    ReadWriteGattCharacteristic<T>* getChar(void) {
+        return state;
+    }
+
+private:
+    BLE* ble;
+    ReadWriteGattCharacteristic<T>* state;
+};
+
+class SimpleBLE {
+public:
+    SimpleBLE(const char* aName, uint16_t aInterval = 1000) : name(aName), interval(aInterval) {
+        ble = &BLE::Instance();
+    }
+    ~SimpleBLE() {}
+    
+    // Start up the BLE service and just run with it!
+    void spin() {
+        ble->init(this, &SimpleBLE::bleInitComplete);
+    
+        /* SpinWait for initialization to complete. This is necessary because the
+         * BLE object is used in the main loop below. */
+        while (ble->hasInitialized()  == false) { /* spin loop */ }
+    
+        while (true) {
+            ble->waitForEvent();
+        }
+    }
+    
+    template <typename T>
+    ReadOnlyCharacteristic<T>* createReadOnlyChar(uint16_t serviceUuid, 
+                                                 uint16_t charUuid, 
+                                                 bool enableNotify,
+                                                 T defaultValue) {
+        ReadOnlyCharacteristic<T>* c = new ReadOnlyCharacteristic<T>(ble, charUuid, enableNotify, defaultValue);
+        
+        if (services.count(serviceUuid) == 0) {
+            services[serviceUuid] = new vector<GattCharacteristic*>();
+        }
+        
+        services[serviceUuid]->push_back(c->getChar());
+        
+        return c;
+    }
+
+    template <typename T>
+    ReadWriteCharacteristic<T>* createReadWriteChar(uint16_t serviceUuid, 
+                                                 uint16_t charUuid, 
+                                                 bool enableNotify,
+                                                 T defaultValue,
+                                                 void(*callback)(const uint8_t*, size_t)) {
+        ReadWriteCharacteristic<T>* c = new ReadWriteCharacteristic<T>(ble, charUuid, enableNotify, defaultValue);
+
+        if (services.count(serviceUuid) == 0) {
+            services[serviceUuid] = new vector<GattCharacteristic*>();
+        }
+        
+        services[serviceUuid]->push_back(c->getChar());
+        writeCallbacks[c->getChar()] = (void*)callback;
+        
+        return c;
+    }
+    
+    void onDisconnection(Gap::DisconnectionEventCallback_t callback) {
+        ble->gap().onDisconnection(callback);
+    }
+    
+    void onConnection(Gap::ConnectionEventCallback_t callback) {
+        ble->gap().onConnection(callback);
+    }
+    
+    void onDataWrittenCallback(const GattWriteCallbackParams *params) {
+        // see if we know for which char this message is...
+        typedef std::map<GattCharacteristic*, void* >::iterator it_type;
+        for(it_type it = writeCallbacks.begin(); it != writeCallbacks.end(); it++) {
+            if (it->first->getValueHandle() == params->handle) {
+                void(*func)(const uint8_t*, size_t) = (void(*)(const uint8_t*, size_t))it->second;
+                
+                func(params->data, params->len);
+            }
+        }
+        
+        // handle corresponds to the characteristic being written
+        // then we can read data to get a buffer of the actual data
+//        if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
+//            // When writing 1 -> turn LED on, 0 -> turn LED off
+//            char val = params->data[0];
+//            actuatedLED = val == 1 ? LED_ON : LED_OFF;
+//        }
+    }
+
+    
+private:
+    void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+    {
+        printf("bleInitComplete\r\n");
+        
+        BLE&        ble   = params->ble;
+        ble_error_t error = params->error;
+    
+        if (error != BLE_ERROR_NONE) {
+            printf("BLE Init error %d\r\n", error);
+            return;
+        }
+    
+        /* Ensure that it is the default instance of BLE */
+        if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+            return;
+        }
+
+        ble.gattServer().onDataWritten(this, &SimpleBLE::onDataWrittenCallback);
+
+        // let's add some services yo (why is there no 'auto' in mbed?)
+        uint16_t uuid16_list[services.size()];
+        
+        size_t counter = 0;
+        typedef std::map<std::uint16_t, vector<GattCharacteristic*>* >::iterator it_type;
+        for(it_type it = services.begin(); it != services.end(); it++) {
+            printf("Creating service 0x%x\n", it->first);
+
+            uuid16_list[counter++] = it->first;
+            
+            GattCharacteristic* charTable[it->second->size()];
+            for (size_t git = 0; git < it->second->size(); git++) {
+                charTable[git] = it->second->at(git);
+            }
+            GattService service(it->first, charTable, it->second->size());
+            ble.gattServer().addService(service);
+        }
+
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)name, strlen(name));
+        ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+        ble.gap().setAdvertisingInterval(interval);
+        ble.gap().startAdvertising();
+        
+        printf("Started advertising\n");
+    }
+
+    BLE* ble;
+    const char* name;
+    uint16_t interval;
+    map<uint16_t, vector<GattCharacteristic*>* > services;
+    map<GattCharacteristic*, void*> writeCallbacks;
+};
+