SimpleBLE example for mbed OS 5
Dependents: SimpleBLE-Example-mbedos5
Fork of SimpleBLE by
Diff: SimpleBLE.h
- Revision:
- 4:0c99ff9d2373
- Parent:
- 2:15329a3de04c
- Child:
- 5:9b33cae085cc
--- a/SimpleBLE.h Fri Aug 19 10:58:38 2016 +0200 +++ b/SimpleBLE.h Fri Aug 19 11:47:47 2016 +0200 @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include <string> #include <sstream> #include <vector> #include <map> +#include "mbed_events.h" #include "ble/BLE.h" #define def_fn(T, postfix) \ @@ -75,7 +76,7 @@ class SimpleCharBase { public: virtual void update(T newValue) = 0; - virtual T* getValue(void) = 0; + virtual T* getValue(void) = 0; }; /** @@ -85,16 +86,16 @@ template <class T, template <typename T2> class U> class SimpleCharInternal : public Updatable, public SimpleCharBase<T> { public: - SimpleCharInternal(BLE* aBle, - const UUID &uuid, - GattCharacteristic::Properties_t aGattChar, + SimpleCharInternal(BLE* aBle, + const UUID &uuid, + GattCharacteristic::Properties_t aGattChar, T aDefaultValue, void(*aCallback)(T) = NULL) : ble(aBle), value(new T(aDefaultValue)), callback(aCallback) { state = new U<T>(uuid, value, aGattChar); } - + ~SimpleCharInternal() { if (state) { free(state); @@ -103,12 +104,12 @@ free(value); } } - + virtual void update(T newValue) { *value = newValue; ble->gattServer().write(state->getValueHandle(), (uint8_t *)value, sizeof(T)); } - + U<T>* getChar(void) { return state; } @@ -116,7 +117,7 @@ virtual T* getValue(void) { return value; } - + virtual void onDataWritten(const uint8_t* data, size_t len) { *value = ((T*)data)[0]; if (callback) { @@ -153,7 +154,7 @@ operator T() const { return *(base->getValue()); }; - + private: SimpleCharBase<T>* base; }; @@ -161,38 +162,36 @@ class SimpleBLE { public: - SimpleBLE(const char* aName, uint16_t aInterval = 1000, bool aLogging = true) - : name(aName), interval(aInterval), logging(aLogging) + SimpleBLE(const char* aName, uint16_t aInterval = 1000, bool aLogging = true) + : name(aName), interval(aInterval), logging(aLogging) { ble = &BLE::Instance(); } ~SimpleBLE() {} - - void start() { + + void start(EventQueue* aEventQueue) { + eventQueue = aEventQueue; + ble->init(this, &SimpleBLE::bleInitComplete); - + ble->onEventsToProcess(BLE::OnEventsToProcessCallback_t(this, &SimpleBLE::scheduleBleEventsProcessing)); + /* 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 */ } } - - // Start up the BLE service and just run with it! - void waitForEvent() { - ble->waitForEvent(); - } - + void onDisconnection(Gap::DisconnectionEventCallback_t callback) { ble->gap().onDisconnection(callback); } - + void onConnection(Gap::ConnectionEventCallback_t callback) { ble->gap().onConnection(callback); } - + BLE* getBle(void) { return ble; } - + def_fn(uint8_t, u8) def_fn(uint16_t, u16) def_fn(uint32_t, u32) @@ -201,41 +200,41 @@ def_fn(int32_t, i32) def_fn(bool, bool) def_fn(float, float) - + private: void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { if (logging) printf("bleInitComplete\r\n"); - + BLE& ble = params->ble; ble_error_t error = params->error; - + if (error != BLE_ERROR_NONE) { if (logging) 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[uint16_services.size()]; size_t uuid16_counter = 0; - { + { typedef std::map<uint16_t, vector<GattCharacteristic*>* >::iterator it_type; for(it_type it = uint16_services.begin(); it != uint16_services.end(); it++) { if (logging) printf("Creating service 0x%x\n", it->first); - uuid16_list[uuid16_counter++] = it->first; - + uuid16_list[uuid16_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); } @@ -248,13 +247,13 @@ typedef std::map<string, vector<GattCharacteristic*>* >::iterator it_type; for(it_type it = uint128_services.begin(); it != uint128_services.end(); it++) { if (logging) printf("Creating service %s\n", it->first.c_str()); - uuid128_list[uuid128_counter++] = it->first.c_str(); - + uuid128_list[uuid128_counter++] = it->first.c_str(); + GattCharacteristic* charTable[it->second->size()]; for (size_t git = 0; git < it->second->size(); git++) { charTable[git] = it->second->at(git); } - + GattService service(UUID(it->first.c_str()), charTable, it->second->size()); ble.gattServer().addService(service); } @@ -267,10 +266,10 @@ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(interval); ble.gap().startAdvertising(); - + if (logging) printf("Started advertising\r\n"); } - + void onDataWrittenCallback(const GattWriteCallbackParams *params) { // see if we know for which char this message is... typedef std::map<GattCharacteristic*, Updatable* >::iterator it_type; @@ -280,7 +279,7 @@ } } } - + void addToServices(uint16_t uuid, GattCharacteristic* c) { if (uint16_services.count(uuid) == 0) { uint16_services[uuid] = new vector<GattCharacteristic*>(); @@ -288,7 +287,7 @@ uint16_services[uuid]->push_back(c); } - + void addToServices(const char* aUuid, GattCharacteristic* c) { string uuid(aUuid); if (uint128_services.count(uuid) == 0) { @@ -297,58 +296,62 @@ uint128_services[uuid]->push_back(c); } - + + void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + eventQueue->call(Callback<void()>(ble, &BLE::processEvents)); + } + // === START READONLY === - + template <typename T> - SimpleChar<T> readOnly(uint16_t serviceUuid, - const UUID& charUuid, + SimpleChar<T> readOnly(uint16_t serviceUuid, + const UUID& charUuid, bool enableNotify = true, T defaultValue = T()) { - GattCharacteristic::Properties_t gattChar = enableNotify ? + GattCharacteristic::Properties_t gattChar = enableNotify ? GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; - SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = + SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = new SimpleCharInternal<T, ReadOnlyGattCharacteristic>(ble, charUuid, gattChar, defaultValue); - + addToServices(serviceUuid, c->getChar()); - + return *(new SimpleChar<T>(c)); } template <typename T> - SimpleChar<T> readOnly(const char* serviceUuid, - const UUID& charUuid, + SimpleChar<T> readOnly(const char* serviceUuid, + const UUID& charUuid, bool enableNotify = true, T defaultValue = T()) { - GattCharacteristic::Properties_t gattChar = enableNotify ? + GattCharacteristic::Properties_t gattChar = enableNotify ? GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; - SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = + SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = new SimpleCharInternal<T, ReadOnlyGattCharacteristic>(ble, charUuid, gattChar, defaultValue); - + addToServices(serviceUuid, c->getChar()); return *(new SimpleChar<T>(c)); } // === END READONLY === - + // === START READWRITE === template <typename T> - SimpleChar<T> readWrite(uint16_t serviceUuid, - const UUID& charUuid, + SimpleChar<T> readWrite(uint16_t serviceUuid, + const UUID& charUuid, bool enableNotify = true, T defaultValue = T(), void(*callback)(T) = NULL) { - GattCharacteristic::Properties_t gattChar = enableNotify ? + GattCharacteristic::Properties_t gattChar = enableNotify ? GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; - SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = + SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = new SimpleCharInternal<T, ReadWriteGattCharacteristic>(ble, charUuid, gattChar, defaultValue, callback); addToServices(serviceUuid, c->getChar()); @@ -357,52 +360,52 @@ return *(new SimpleChar<T>(c)); } - - + + template <typename T> - SimpleChar<T> readWrite(const char* serviceUuid, - const UUID& charUuid, + SimpleChar<T> readWrite(const char* serviceUuid, + const UUID& charUuid, bool enableNotify = true, T defaultValue = T(), void(*callback)(T) = NULL) { - GattCharacteristic::Properties_t gattChar = enableNotify ? + GattCharacteristic::Properties_t gattChar = enableNotify ? GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; - SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = + SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = new SimpleCharInternal<T, ReadWriteGattCharacteristic>(ble, charUuid, gattChar, defaultValue, callback); addToServices(serviceUuid, c->getChar()); writeCallbacks[c->getChar()] = c; - + return *(new SimpleChar<T>(c)); } - + template <typename T> - SimpleChar<T> readWrite(uint16_t serviceUuid, - const UUID& charUuid, + SimpleChar<T> readWrite(uint16_t serviceUuid, + const UUID& charUuid, void(*callback)(T) = NULL) { return readWrite(serviceUuid, charUuid, true, T(), callback); } template <typename T> - SimpleChar<T> readWrite(const char* serviceUuid, - const UUID& charUuid, + SimpleChar<T> readWrite(const char* serviceUuid, + const UUID& charUuid, void(*callback)(T) = NULL) { return readWrite(serviceUuid, charUuid, true, T(), callback); } - + // === END READWRITE === - + // === START WRITEONLY === template <typename T> - SimpleChar<T> writeOnly(uint16_t serviceUuid, + SimpleChar<T> writeOnly(uint16_t serviceUuid, const UUID& charUuid, void(*callback)(T) = NULL) { - SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = + SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = new SimpleCharInternal<T, WriteOnlyGattCharacteristic>(ble, charUuid, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE, T(), callback); addToServices(serviceUuid, c->getChar()); @@ -413,20 +416,20 @@ } template <typename T> - SimpleChar<T> writeOnly(const char* serviceUuid, + SimpleChar<T> writeOnly(const char* serviceUuid, const UUID& charUuid, void(*callback)(T) = NULL) { - SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = + SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = new SimpleCharInternal<T, WriteOnlyGattCharacteristic>(ble, charUuid, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE, T(), callback); addToServices(serviceUuid, c->getChar()); writeCallbacks[c->getChar()] = c; - + return *(new SimpleChar<T>(c)); } - + // === END WRITEONLY === BLE* ble; @@ -436,5 +439,6 @@ map<uint16_t, vector<GattCharacteristic*>* > uint16_services; map<string, vector<GattCharacteristic*>* > uint128_services; map<GattCharacteristic*, Updatable*> writeCallbacks; + EventQueue* eventQueue; };