Jan Jongboom / Mbed 2 deprecated HPE_LightSensor

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SimpleBLE.h Source File

SimpleBLE.h

00001 /**
00002  * Because BLE_API is too hard
00003  */
00004 #include <string>
00005 #include <vector>
00006 #include <map>
00007 #include "ble/BLE.h"
00008 
00009 using namespace std;
00010 
00011 template <class T>
00012 class ReadOnlyCharacteristic {
00013 public:
00014     ReadOnlyCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) :
00015         ble(aBle)
00016     {
00017         state = new ReadOnlyGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 
00018             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY :
00019             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
00020     }
00021     
00022     ~ReadOnlyCharacteristic() {
00023         // @todo clear defaultValue
00024         if (state) {
00025             free(state);
00026         }
00027     }
00028     
00029     void update(T newValue) {
00030         ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T));
00031     }
00032     
00033     ReadOnlyGattCharacteristic<T>* getChar(void) {
00034         return state;
00035     }
00036 
00037 private:
00038     BLE* ble;
00039     ReadOnlyGattCharacteristic<T>* state;
00040 };
00041 
00042 template <class T>
00043 class ReadWriteCharacteristic {
00044 public:
00045     ReadWriteCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) :
00046         ble(aBle)
00047     {
00048         state = new ReadWriteGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 
00049             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY :
00050             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
00051     }
00052     
00053     ~ReadWriteCharacteristic() {
00054         // @todo clear defaultValue
00055         if (state) {
00056             free(state);
00057         }
00058     }
00059     
00060     void update(T newValue) {
00061         ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T));
00062     }
00063     
00064     ReadWriteGattCharacteristic<T>* getChar(void) {
00065         return state;
00066     }
00067 
00068 private:
00069     BLE* ble;
00070     ReadWriteGattCharacteristic<T>* state;
00071 };
00072 
00073 class SimpleBLE {
00074 public:
00075     SimpleBLE(const char* aName, uint16_t aInterval = 1000) : name(aName), interval(aInterval) {
00076         ble = &BLE::Instance();
00077     }
00078     ~SimpleBLE() {}
00079     
00080     // Start up the BLE service and just run with it!
00081     void spin() {
00082         ble->init(this, &SimpleBLE::bleInitComplete);
00083     
00084         /* SpinWait for initialization to complete. This is necessary because the
00085          * BLE object is used in the main loop below. */
00086         while (ble->hasInitialized()  == false) { /* spin loop */ }
00087     
00088         while (true) {
00089             ble->waitForEvent();
00090         }
00091     }
00092     
00093     template <typename T>
00094     ReadOnlyCharacteristic<T>* createReadOnlyChar(uint16_t serviceUuid, 
00095                                                  uint16_t charUuid, 
00096                                                  bool enableNotify,
00097                                                  T defaultValue) {
00098         ReadOnlyCharacteristic<T>* c = new ReadOnlyCharacteristic<T>(ble, charUuid, enableNotify, defaultValue);
00099         
00100         if (services.count(serviceUuid) == 0) {
00101             services[serviceUuid] = new vector<GattCharacteristic*>();
00102         }
00103         
00104         services[serviceUuid]->push_back(c->getChar());
00105         
00106         return c;
00107     }
00108 
00109     template <typename T>
00110     ReadWriteCharacteristic<T>* createReadWriteChar(uint16_t serviceUuid, 
00111                                                  uint16_t charUuid, 
00112                                                  bool enableNotify,
00113                                                  T defaultValue,
00114                                                  void(*callback)(const uint8_t*, size_t)) {
00115         ReadWriteCharacteristic<T>* c = new ReadWriteCharacteristic<T>(ble, charUuid, enableNotify, defaultValue);
00116 
00117         if (services.count(serviceUuid) == 0) {
00118             services[serviceUuid] = new vector<GattCharacteristic*>();
00119         }
00120         
00121         services[serviceUuid]->push_back(c->getChar());
00122         writeCallbacks[c->getChar()] = (void*)callback;
00123         
00124         return c;
00125     }
00126     
00127     void onDisconnection(Gap::DisconnectionEventCallback_t callback) {
00128         ble->gap().onDisconnection(callback);
00129     }
00130     
00131     void onConnection(Gap::ConnectionEventCallback_t callback) {
00132         ble->gap().onConnection(callback);
00133     }
00134     
00135     void onDataWrittenCallback(const GattWriteCallbackParams *params) {
00136         // see if we know for which char this message is...
00137         typedef std::map<GattCharacteristic*, void* >::iterator it_type;
00138         for(it_type it = writeCallbacks.begin(); it != writeCallbacks.end(); it++) {
00139             if (it->first->getValueHandle() == params->handle) {
00140                 void(*func)(const uint8_t*, size_t) = (void(*)(const uint8_t*, size_t))it->second;
00141                 
00142                 func(params->data, params->len);
00143             }
00144         }
00145         
00146         // handle corresponds to the characteristic being written
00147         // then we can read data to get a buffer of the actual data
00148 //        if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
00149 //            // When writing 1 -> turn LED on, 0 -> turn LED off
00150 //            char val = params->data[0];
00151 //            actuatedLED = val == 1 ? LED_ON : LED_OFF;
00152 //        }
00153     }
00154 
00155     
00156 private:
00157     void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00158     {
00159         printf("bleInitComplete\r\n");
00160         
00161         BLE&        ble   = params->ble;
00162         ble_error_t error = params->error;
00163     
00164         if (error != BLE_ERROR_NONE) {
00165             printf("BLE Init error %d\r\n", error);
00166             return;
00167         }
00168     
00169         /* Ensure that it is the default instance of BLE */
00170         if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00171             return;
00172         }
00173 
00174         ble.gattServer().onDataWritten(this, &SimpleBLE::onDataWrittenCallback);
00175 
00176         // let's add some services yo (why is there no 'auto' in mbed?)
00177         uint16_t uuid16_list[services.size()];
00178         
00179         size_t counter = 0;
00180         typedef std::map<std::uint16_t, vector<GattCharacteristic*>* >::iterator it_type;
00181         for(it_type it = services.begin(); it != services.end(); it++) {
00182             printf("Creating service 0x%x\n", it->first);
00183 
00184             uuid16_list[counter++] = it->first;
00185             
00186             GattCharacteristic* charTable[it->second->size()];
00187             for (size_t git = 0; git < it->second->size(); git++) {
00188                 charTable[git] = it->second->at(git);
00189             }
00190             GattService service(it->first, charTable, it->second->size());
00191             ble.gattServer().addService(service);
00192         }
00193 
00194         ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00195         ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00196         ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)name, strlen(name));
00197         ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00198         ble.gap().setAdvertisingInterval(interval);
00199         ble.gap().startAdvertising();
00200         
00201         printf("Started advertising\n");
00202     }
00203 
00204     BLE* ble;
00205     const char* name;
00206     uint16_t interval;
00207     map<uint16_t, vector<GattCharacteristic*>* > services;
00208     map<GattCharacteristic*, void*> writeCallbacks;
00209 };
00210