SimpleBLE example for mbed OS 5
Dependents: SimpleBLE-Example-mbedos5
Fork of SimpleBLE by
SimpleBLE.h@0:2ecd71f6ab04, 2016-05-11 (annotated)
- Committer:
- janjongboom
- Date:
- Wed May 11 12:59:14 2016 +0000
- Revision:
- 0:2ecd71f6ab04
- Child:
- 1:17c8f5afa7bc
SimpleBLE Initial Commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
janjongboom | 0:2ecd71f6ab04 | 1 | /** |
janjongboom | 0:2ecd71f6ab04 | 2 | * Because BLE_API is too hard |
janjongboom | 0:2ecd71f6ab04 | 3 | */ |
janjongboom | 0:2ecd71f6ab04 | 4 | #include <string> |
janjongboom | 0:2ecd71f6ab04 | 5 | #include <sstream> |
janjongboom | 0:2ecd71f6ab04 | 6 | #include <vector> |
janjongboom | 0:2ecd71f6ab04 | 7 | #include <map> |
janjongboom | 0:2ecd71f6ab04 | 8 | #include "ble/BLE.h" |
janjongboom | 0:2ecd71f6ab04 | 9 | |
janjongboom | 0:2ecd71f6ab04 | 10 | using namespace std; |
janjongboom | 0:2ecd71f6ab04 | 11 | |
janjongboom | 0:2ecd71f6ab04 | 12 | /** |
janjongboom | 0:2ecd71f6ab04 | 13 | * Class so we can call onDataWritten on any SimpleCharInternal regardless of <T,U> |
janjongboom | 0:2ecd71f6ab04 | 14 | */ |
janjongboom | 0:2ecd71f6ab04 | 15 | class Updatable { |
janjongboom | 0:2ecd71f6ab04 | 16 | public: |
janjongboom | 0:2ecd71f6ab04 | 17 | virtual void onDataWritten(const uint8_t* data, size_t len) = 0; |
janjongboom | 0:2ecd71f6ab04 | 18 | }; |
janjongboom | 0:2ecd71f6ab04 | 19 | |
janjongboom | 0:2ecd71f6ab04 | 20 | /** |
janjongboom | 0:2ecd71f6ab04 | 21 | * Class that we wrap in SimpleChar so we can just implement operators, |
janjongboom | 0:2ecd71f6ab04 | 22 | * without having to type the full type of U when using this code. |
janjongboom | 0:2ecd71f6ab04 | 23 | * Whenever we get 'auto' we can get rid of this. |
janjongboom | 0:2ecd71f6ab04 | 24 | */ |
janjongboom | 0:2ecd71f6ab04 | 25 | template <class T> |
janjongboom | 0:2ecd71f6ab04 | 26 | class SimpleCharBase { |
janjongboom | 0:2ecd71f6ab04 | 27 | public: |
janjongboom | 0:2ecd71f6ab04 | 28 | virtual void update(T newValue) = 0; |
janjongboom | 0:2ecd71f6ab04 | 29 | virtual T* getValue(void) = 0; |
janjongboom | 0:2ecd71f6ab04 | 30 | }; |
janjongboom | 0:2ecd71f6ab04 | 31 | |
janjongboom | 0:2ecd71f6ab04 | 32 | /** |
janjongboom | 0:2ecd71f6ab04 | 33 | * Actual implementation of the char |
janjongboom | 0:2ecd71f6ab04 | 34 | * T is the underlying type, U is the GattCharacteristic it's wrapping |
janjongboom | 0:2ecd71f6ab04 | 35 | */ |
janjongboom | 0:2ecd71f6ab04 | 36 | template <class T, template <typename T2> class U> |
janjongboom | 0:2ecd71f6ab04 | 37 | class SimpleCharInternal : public Updatable, public SimpleCharBase<T> { |
janjongboom | 0:2ecd71f6ab04 | 38 | public: |
janjongboom | 0:2ecd71f6ab04 | 39 | SimpleCharInternal(BLE* aBle, |
janjongboom | 0:2ecd71f6ab04 | 40 | const UUID &uuid, |
janjongboom | 0:2ecd71f6ab04 | 41 | GattCharacteristic::Properties_t aGattChar, |
janjongboom | 0:2ecd71f6ab04 | 42 | T aDefaultValue, |
janjongboom | 0:2ecd71f6ab04 | 43 | void(*aCallback)(T) = NULL) : |
janjongboom | 0:2ecd71f6ab04 | 44 | ble(aBle), value(new T(aDefaultValue)), callback(aCallback) |
janjongboom | 0:2ecd71f6ab04 | 45 | { |
janjongboom | 0:2ecd71f6ab04 | 46 | state = new U<T>(uuid, value, aGattChar); |
janjongboom | 0:2ecd71f6ab04 | 47 | } |
janjongboom | 0:2ecd71f6ab04 | 48 | |
janjongboom | 0:2ecd71f6ab04 | 49 | ~SimpleCharInternal() { |
janjongboom | 0:2ecd71f6ab04 | 50 | if (state) { |
janjongboom | 0:2ecd71f6ab04 | 51 | free(state); |
janjongboom | 0:2ecd71f6ab04 | 52 | } |
janjongboom | 0:2ecd71f6ab04 | 53 | if (value) { |
janjongboom | 0:2ecd71f6ab04 | 54 | free(value); |
janjongboom | 0:2ecd71f6ab04 | 55 | } |
janjongboom | 0:2ecd71f6ab04 | 56 | } |
janjongboom | 0:2ecd71f6ab04 | 57 | |
janjongboom | 0:2ecd71f6ab04 | 58 | virtual void update(T newValue) { |
janjongboom | 0:2ecd71f6ab04 | 59 | *value = newValue; |
janjongboom | 0:2ecd71f6ab04 | 60 | ble->gattServer().write(state->getValueHandle(), (uint8_t *)value, sizeof(T)); |
janjongboom | 0:2ecd71f6ab04 | 61 | } |
janjongboom | 0:2ecd71f6ab04 | 62 | |
janjongboom | 0:2ecd71f6ab04 | 63 | U<T>* getChar(void) { |
janjongboom | 0:2ecd71f6ab04 | 64 | return state; |
janjongboom | 0:2ecd71f6ab04 | 65 | } |
janjongboom | 0:2ecd71f6ab04 | 66 | |
janjongboom | 0:2ecd71f6ab04 | 67 | virtual T* getValue(void) { |
janjongboom | 0:2ecd71f6ab04 | 68 | return value; |
janjongboom | 0:2ecd71f6ab04 | 69 | } |
janjongboom | 0:2ecd71f6ab04 | 70 | |
janjongboom | 0:2ecd71f6ab04 | 71 | virtual void onDataWritten(const uint8_t* data, size_t len) { |
janjongboom | 0:2ecd71f6ab04 | 72 | *value = ((T*)data)[0]; |
janjongboom | 0:2ecd71f6ab04 | 73 | if (callback) { |
janjongboom | 0:2ecd71f6ab04 | 74 | callback(*value); |
janjongboom | 0:2ecd71f6ab04 | 75 | } |
janjongboom | 0:2ecd71f6ab04 | 76 | } |
janjongboom | 0:2ecd71f6ab04 | 77 | |
janjongboom | 0:2ecd71f6ab04 | 78 | private: |
janjongboom | 0:2ecd71f6ab04 | 79 | BLE* ble; |
janjongboom | 0:2ecd71f6ab04 | 80 | T* value; |
janjongboom | 0:2ecd71f6ab04 | 81 | U<T>* state; |
janjongboom | 0:2ecd71f6ab04 | 82 | void(*callback)(T); |
janjongboom | 0:2ecd71f6ab04 | 83 | }; |
janjongboom | 0:2ecd71f6ab04 | 84 | |
janjongboom | 0:2ecd71f6ab04 | 85 | /** |
janjongboom | 0:2ecd71f6ab04 | 86 | * This is what the user gets back. it's nice and short so don't have to type much. |
janjongboom | 0:2ecd71f6ab04 | 87 | * If we get 'auto' we can get rid of this. |
janjongboom | 0:2ecd71f6ab04 | 88 | */ |
janjongboom | 0:2ecd71f6ab04 | 89 | template <class T> |
janjongboom | 0:2ecd71f6ab04 | 90 | class SimpleChar { |
janjongboom | 0:2ecd71f6ab04 | 91 | public: |
janjongboom | 0:2ecd71f6ab04 | 92 | SimpleChar(SimpleCharBase<T>* aBase) : base(aBase) { |
janjongboom | 0:2ecd71f6ab04 | 93 | } |
janjongboom | 0:2ecd71f6ab04 | 94 | ~SimpleChar() { |
janjongboom | 0:2ecd71f6ab04 | 95 | if (base) { |
janjongboom | 0:2ecd71f6ab04 | 96 | delete base; |
janjongboom | 0:2ecd71f6ab04 | 97 | } |
janjongboom | 0:2ecd71f6ab04 | 98 | } |
janjongboom | 0:2ecd71f6ab04 | 99 | |
janjongboom | 0:2ecd71f6ab04 | 100 | T operator=(const T& newValue) { |
janjongboom | 0:2ecd71f6ab04 | 101 | base->update(newValue); |
janjongboom | 0:2ecd71f6ab04 | 102 | return newValue; |
janjongboom | 0:2ecd71f6ab04 | 103 | }; |
janjongboom | 0:2ecd71f6ab04 | 104 | operator T() const { |
janjongboom | 0:2ecd71f6ab04 | 105 | return *(base->getValue()); |
janjongboom | 0:2ecd71f6ab04 | 106 | }; |
janjongboom | 0:2ecd71f6ab04 | 107 | |
janjongboom | 0:2ecd71f6ab04 | 108 | private: |
janjongboom | 0:2ecd71f6ab04 | 109 | SimpleCharBase<T>* base; |
janjongboom | 0:2ecd71f6ab04 | 110 | }; |
janjongboom | 0:2ecd71f6ab04 | 111 | |
janjongboom | 0:2ecd71f6ab04 | 112 | |
janjongboom | 0:2ecd71f6ab04 | 113 | class SimpleBLE { |
janjongboom | 0:2ecd71f6ab04 | 114 | public: |
janjongboom | 0:2ecd71f6ab04 | 115 | SimpleBLE(const char* aName, uint16_t aInterval = 1000) : name(aName), interval(aInterval) { |
janjongboom | 0:2ecd71f6ab04 | 116 | ble = &BLE::Instance(); |
janjongboom | 0:2ecd71f6ab04 | 117 | } |
janjongboom | 0:2ecd71f6ab04 | 118 | ~SimpleBLE() {} |
janjongboom | 0:2ecd71f6ab04 | 119 | |
janjongboom | 0:2ecd71f6ab04 | 120 | void start() { |
janjongboom | 0:2ecd71f6ab04 | 121 | ble->init(this, &SimpleBLE::bleInitComplete); |
janjongboom | 0:2ecd71f6ab04 | 122 | |
janjongboom | 0:2ecd71f6ab04 | 123 | /* SpinWait for initialization to complete. This is necessary because the |
janjongboom | 0:2ecd71f6ab04 | 124 | * BLE object is used in the main loop below. */ |
janjongboom | 0:2ecd71f6ab04 | 125 | while (ble->hasInitialized() == false) { /* spin loop */ } |
janjongboom | 0:2ecd71f6ab04 | 126 | } |
janjongboom | 0:2ecd71f6ab04 | 127 | |
janjongboom | 0:2ecd71f6ab04 | 128 | // Start up the BLE service and just run with it! |
janjongboom | 0:2ecd71f6ab04 | 129 | void waitForEvent() { |
janjongboom | 0:2ecd71f6ab04 | 130 | ble->waitForEvent(); |
janjongboom | 0:2ecd71f6ab04 | 131 | } |
janjongboom | 0:2ecd71f6ab04 | 132 | |
janjongboom | 0:2ecd71f6ab04 | 133 | // === START READONLY === |
janjongboom | 0:2ecd71f6ab04 | 134 | |
janjongboom | 0:2ecd71f6ab04 | 135 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 136 | SimpleChar<T> readOnly(uint16_t serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 137 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 138 | bool enableNotify = true, |
janjongboom | 0:2ecd71f6ab04 | 139 | T defaultValue = T()) { |
janjongboom | 0:2ecd71f6ab04 | 140 | GattCharacteristic::Properties_t gattChar = enableNotify ? |
janjongboom | 0:2ecd71f6ab04 | 141 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : |
janjongboom | 0:2ecd71f6ab04 | 142 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; |
janjongboom | 0:2ecd71f6ab04 | 143 | |
janjongboom | 0:2ecd71f6ab04 | 144 | SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 145 | new SimpleCharInternal<T, ReadOnlyGattCharacteristic>(ble, charUuid, gattChar, defaultValue); |
janjongboom | 0:2ecd71f6ab04 | 146 | |
janjongboom | 0:2ecd71f6ab04 | 147 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 148 | |
janjongboom | 0:2ecd71f6ab04 | 149 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 150 | } |
janjongboom | 0:2ecd71f6ab04 | 151 | |
janjongboom | 0:2ecd71f6ab04 | 152 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 153 | SimpleChar<T> readOnly(const char* serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 154 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 155 | bool enableNotify = true, |
janjongboom | 0:2ecd71f6ab04 | 156 | T defaultValue = T()) { |
janjongboom | 0:2ecd71f6ab04 | 157 | GattCharacteristic::Properties_t gattChar = enableNotify ? |
janjongboom | 0:2ecd71f6ab04 | 158 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : |
janjongboom | 0:2ecd71f6ab04 | 159 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; |
janjongboom | 0:2ecd71f6ab04 | 160 | |
janjongboom | 0:2ecd71f6ab04 | 161 | SimpleCharInternal<T, ReadOnlyGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 162 | new SimpleCharInternal<T, ReadOnlyGattCharacteristic>(ble, charUuid, gattChar, defaultValue); |
janjongboom | 0:2ecd71f6ab04 | 163 | |
janjongboom | 0:2ecd71f6ab04 | 164 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 165 | |
janjongboom | 0:2ecd71f6ab04 | 166 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 167 | } |
janjongboom | 0:2ecd71f6ab04 | 168 | |
janjongboom | 0:2ecd71f6ab04 | 169 | // === END READONLY === |
janjongboom | 0:2ecd71f6ab04 | 170 | |
janjongboom | 0:2ecd71f6ab04 | 171 | // === START READWRITE === |
janjongboom | 0:2ecd71f6ab04 | 172 | |
janjongboom | 0:2ecd71f6ab04 | 173 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 174 | SimpleChar<T> readWrite(uint16_t serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 175 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 176 | bool enableNotify = true, |
janjongboom | 0:2ecd71f6ab04 | 177 | T defaultValue = T(), |
janjongboom | 0:2ecd71f6ab04 | 178 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 179 | GattCharacteristic::Properties_t gattChar = enableNotify ? |
janjongboom | 0:2ecd71f6ab04 | 180 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : |
janjongboom | 0:2ecd71f6ab04 | 181 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; |
janjongboom | 0:2ecd71f6ab04 | 182 | |
janjongboom | 0:2ecd71f6ab04 | 183 | SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 184 | new SimpleCharInternal<T, ReadWriteGattCharacteristic>(ble, charUuid, gattChar, defaultValue, callback); |
janjongboom | 0:2ecd71f6ab04 | 185 | |
janjongboom | 0:2ecd71f6ab04 | 186 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 187 | |
janjongboom | 0:2ecd71f6ab04 | 188 | writeCallbacks[c->getChar()] = c; |
janjongboom | 0:2ecd71f6ab04 | 189 | |
janjongboom | 0:2ecd71f6ab04 | 190 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 191 | } |
janjongboom | 0:2ecd71f6ab04 | 192 | |
janjongboom | 0:2ecd71f6ab04 | 193 | |
janjongboom | 0:2ecd71f6ab04 | 194 | |
janjongboom | 0:2ecd71f6ab04 | 195 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 196 | SimpleChar<T> readWrite(const char* serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 197 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 198 | bool enableNotify = true, |
janjongboom | 0:2ecd71f6ab04 | 199 | T defaultValue = T(), |
janjongboom | 0:2ecd71f6ab04 | 200 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 201 | GattCharacteristic::Properties_t gattChar = enableNotify ? |
janjongboom | 0:2ecd71f6ab04 | 202 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : |
janjongboom | 0:2ecd71f6ab04 | 203 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; |
janjongboom | 0:2ecd71f6ab04 | 204 | |
janjongboom | 0:2ecd71f6ab04 | 205 | SimpleCharInternal<T, ReadWriteGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 206 | new SimpleCharInternal<T, ReadWriteGattCharacteristic>(ble, charUuid, gattChar, defaultValue, callback); |
janjongboom | 0:2ecd71f6ab04 | 207 | |
janjongboom | 0:2ecd71f6ab04 | 208 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 209 | |
janjongboom | 0:2ecd71f6ab04 | 210 | writeCallbacks[c->getChar()] = c; |
janjongboom | 0:2ecd71f6ab04 | 211 | |
janjongboom | 0:2ecd71f6ab04 | 212 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 213 | } |
janjongboom | 0:2ecd71f6ab04 | 214 | |
janjongboom | 0:2ecd71f6ab04 | 215 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 216 | SimpleChar<T> readWrite(uint16_t serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 217 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 218 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 219 | return readWrite(serviceUuid, charUuid, true, T(), callback); |
janjongboom | 0:2ecd71f6ab04 | 220 | } |
janjongboom | 0:2ecd71f6ab04 | 221 | |
janjongboom | 0:2ecd71f6ab04 | 222 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 223 | SimpleChar<T> readWrite(const char* serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 224 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 225 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 226 | return readWrite(serviceUuid, charUuid, true, T(), callback); |
janjongboom | 0:2ecd71f6ab04 | 227 | } |
janjongboom | 0:2ecd71f6ab04 | 228 | |
janjongboom | 0:2ecd71f6ab04 | 229 | // === END READWRITE === |
janjongboom | 0:2ecd71f6ab04 | 230 | |
janjongboom | 0:2ecd71f6ab04 | 231 | // === START WRITEONLY === |
janjongboom | 0:2ecd71f6ab04 | 232 | |
janjongboom | 0:2ecd71f6ab04 | 233 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 234 | SimpleChar<T> writeOnly(uint16_t serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 235 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 236 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 237 | GattCharacteristic::Properties_t gattChar = enableNotify ? |
janjongboom | 0:2ecd71f6ab04 | 238 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : |
janjongboom | 0:2ecd71f6ab04 | 239 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ; |
janjongboom | 0:2ecd71f6ab04 | 240 | |
janjongboom | 0:2ecd71f6ab04 | 241 | SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 242 | new SimpleCharInternal<T, WriteOnlyGattCharacteristic>(ble, charUuid, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE, defaultValue, callback); |
janjongboom | 0:2ecd71f6ab04 | 243 | |
janjongboom | 0:2ecd71f6ab04 | 244 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 245 | |
janjongboom | 0:2ecd71f6ab04 | 246 | writeCallbacks[c->getChar()] = c; |
janjongboom | 0:2ecd71f6ab04 | 247 | |
janjongboom | 0:2ecd71f6ab04 | 248 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 249 | } |
janjongboom | 0:2ecd71f6ab04 | 250 | |
janjongboom | 0:2ecd71f6ab04 | 251 | template <typename T> |
janjongboom | 0:2ecd71f6ab04 | 252 | SimpleChar<T> writeOnly(const char* serviceUuid, |
janjongboom | 0:2ecd71f6ab04 | 253 | const UUID& charUuid, |
janjongboom | 0:2ecd71f6ab04 | 254 | void(*callback)(T) = NULL) { |
janjongboom | 0:2ecd71f6ab04 | 255 | |
janjongboom | 0:2ecd71f6ab04 | 256 | SimpleCharInternal<T, WriteOnlyGattCharacteristic>* c = |
janjongboom | 0:2ecd71f6ab04 | 257 | new SimpleCharInternal<T, WriteOnlyGattCharacteristic>(ble, charUuid, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE, defaultValue, callback); |
janjongboom | 0:2ecd71f6ab04 | 258 | |
janjongboom | 0:2ecd71f6ab04 | 259 | addToServices(serviceUuid, c->getChar()); |
janjongboom | 0:2ecd71f6ab04 | 260 | |
janjongboom | 0:2ecd71f6ab04 | 261 | writeCallbacks[c->getChar()] = c; |
janjongboom | 0:2ecd71f6ab04 | 262 | |
janjongboom | 0:2ecd71f6ab04 | 263 | return *(new SimpleChar<T>(c)); |
janjongboom | 0:2ecd71f6ab04 | 264 | } |
janjongboom | 0:2ecd71f6ab04 | 265 | |
janjongboom | 0:2ecd71f6ab04 | 266 | // === END READWRITE === |
janjongboom | 0:2ecd71f6ab04 | 267 | |
janjongboom | 0:2ecd71f6ab04 | 268 | |
janjongboom | 0:2ecd71f6ab04 | 269 | void onDisconnection(Gap::DisconnectionEventCallback_t callback) { |
janjongboom | 0:2ecd71f6ab04 | 270 | ble->gap().onDisconnection(callback); |
janjongboom | 0:2ecd71f6ab04 | 271 | } |
janjongboom | 0:2ecd71f6ab04 | 272 | |
janjongboom | 0:2ecd71f6ab04 | 273 | void onConnection(Gap::ConnectionEventCallback_t callback) { |
janjongboom | 0:2ecd71f6ab04 | 274 | ble->gap().onConnection(callback); |
janjongboom | 0:2ecd71f6ab04 | 275 | } |
janjongboom | 0:2ecd71f6ab04 | 276 | |
janjongboom | 0:2ecd71f6ab04 | 277 | BLE* getBle(void) { |
janjongboom | 0:2ecd71f6ab04 | 278 | return ble; |
janjongboom | 0:2ecd71f6ab04 | 279 | } |
janjongboom | 0:2ecd71f6ab04 | 280 | |
janjongboom | 0:2ecd71f6ab04 | 281 | |
janjongboom | 0:2ecd71f6ab04 | 282 | private: |
janjongboom | 0:2ecd71f6ab04 | 283 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) |
janjongboom | 0:2ecd71f6ab04 | 284 | { |
janjongboom | 0:2ecd71f6ab04 | 285 | printf("bleInitComplete\r\n"); |
janjongboom | 0:2ecd71f6ab04 | 286 | |
janjongboom | 0:2ecd71f6ab04 | 287 | BLE& ble = params->ble; |
janjongboom | 0:2ecd71f6ab04 | 288 | ble_error_t error = params->error; |
janjongboom | 0:2ecd71f6ab04 | 289 | |
janjongboom | 0:2ecd71f6ab04 | 290 | if (error != BLE_ERROR_NONE) { |
janjongboom | 0:2ecd71f6ab04 | 291 | printf("BLE Init error %d\r\n", error); |
janjongboom | 0:2ecd71f6ab04 | 292 | return; |
janjongboom | 0:2ecd71f6ab04 | 293 | } |
janjongboom | 0:2ecd71f6ab04 | 294 | |
janjongboom | 0:2ecd71f6ab04 | 295 | /* Ensure that it is the default instance of BLE */ |
janjongboom | 0:2ecd71f6ab04 | 296 | if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { |
janjongboom | 0:2ecd71f6ab04 | 297 | return; |
janjongboom | 0:2ecd71f6ab04 | 298 | } |
janjongboom | 0:2ecd71f6ab04 | 299 | |
janjongboom | 0:2ecd71f6ab04 | 300 | ble.gattServer().onDataWritten(this, &SimpleBLE::onDataWrittenCallback); |
janjongboom | 0:2ecd71f6ab04 | 301 | |
janjongboom | 0:2ecd71f6ab04 | 302 | // let's add some services yo (why is there no 'auto' in mbed?) |
janjongboom | 0:2ecd71f6ab04 | 303 | uint16_t uuid16_list[uint16_services.size()]; |
janjongboom | 0:2ecd71f6ab04 | 304 | size_t uuid16_counter = 0; |
janjongboom | 0:2ecd71f6ab04 | 305 | { |
janjongboom | 0:2ecd71f6ab04 | 306 | typedef std::map<uint16_t, vector<GattCharacteristic*>* >::iterator it_type; |
janjongboom | 0:2ecd71f6ab04 | 307 | for(it_type it = uint16_services.begin(); it != uint16_services.end(); it++) { |
janjongboom | 0:2ecd71f6ab04 | 308 | printf("Creating service 0x%x\n", it->first); |
janjongboom | 0:2ecd71f6ab04 | 309 | uuid16_list[uuid16_counter++] = it->first; |
janjongboom | 0:2ecd71f6ab04 | 310 | |
janjongboom | 0:2ecd71f6ab04 | 311 | GattCharacteristic* charTable[it->second->size()]; |
janjongboom | 0:2ecd71f6ab04 | 312 | for (size_t git = 0; git < it->second->size(); git++) { |
janjongboom | 0:2ecd71f6ab04 | 313 | charTable[git] = it->second->at(git); |
janjongboom | 0:2ecd71f6ab04 | 314 | } |
janjongboom | 0:2ecd71f6ab04 | 315 | |
janjongboom | 0:2ecd71f6ab04 | 316 | GattService service(it->first, charTable, it->second->size()); |
janjongboom | 0:2ecd71f6ab04 | 317 | ble.gattServer().addService(service); |
janjongboom | 0:2ecd71f6ab04 | 318 | } |
janjongboom | 0:2ecd71f6ab04 | 319 | } |
janjongboom | 0:2ecd71f6ab04 | 320 | |
janjongboom | 0:2ecd71f6ab04 | 321 | // 128 Bit services |
janjongboom | 0:2ecd71f6ab04 | 322 | const char* uuid128_list[uint128_services.size()]; |
janjongboom | 0:2ecd71f6ab04 | 323 | size_t uuid128_counter = 0; |
janjongboom | 0:2ecd71f6ab04 | 324 | { |
janjongboom | 0:2ecd71f6ab04 | 325 | typedef std::map<string, vector<GattCharacteristic*>* >::iterator it_type; |
janjongboom | 0:2ecd71f6ab04 | 326 | for(it_type it = uint128_services.begin(); it != uint128_services.end(); it++) { |
janjongboom | 0:2ecd71f6ab04 | 327 | printf("Creating service %s\n", it->first.c_str()); |
janjongboom | 0:2ecd71f6ab04 | 328 | uuid128_list[uuid128_counter++] = it->first.c_str(); |
janjongboom | 0:2ecd71f6ab04 | 329 | |
janjongboom | 0:2ecd71f6ab04 | 330 | GattCharacteristic* charTable[it->second->size()]; |
janjongboom | 0:2ecd71f6ab04 | 331 | for (size_t git = 0; git < it->second->size(); git++) { |
janjongboom | 0:2ecd71f6ab04 | 332 | charTable[git] = it->second->at(git); |
janjongboom | 0:2ecd71f6ab04 | 333 | } |
janjongboom | 0:2ecd71f6ab04 | 334 | |
janjongboom | 0:2ecd71f6ab04 | 335 | GattService service(UUID(it->first.c_str()), charTable, it->second->size()); |
janjongboom | 0:2ecd71f6ab04 | 336 | ble.gattServer().addService(service); |
janjongboom | 0:2ecd71f6ab04 | 337 | } |
janjongboom | 0:2ecd71f6ab04 | 338 | } |
janjongboom | 0:2ecd71f6ab04 | 339 | |
janjongboom | 0:2ecd71f6ab04 | 340 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
janjongboom | 0:2ecd71f6ab04 | 341 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, uuid16_counter); |
janjongboom | 0:2ecd71f6ab04 | 342 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *)uuid128_list, uuid128_counter); |
janjongboom | 0:2ecd71f6ab04 | 343 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)name, strlen(name)); |
janjongboom | 0:2ecd71f6ab04 | 344 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
janjongboom | 0:2ecd71f6ab04 | 345 | ble.gap().setAdvertisingInterval(interval); |
janjongboom | 0:2ecd71f6ab04 | 346 | ble.gap().startAdvertising(); |
janjongboom | 0:2ecd71f6ab04 | 347 | |
janjongboom | 0:2ecd71f6ab04 | 348 | printf("Started advertising\r\n"); |
janjongboom | 0:2ecd71f6ab04 | 349 | } |
janjongboom | 0:2ecd71f6ab04 | 350 | |
janjongboom | 0:2ecd71f6ab04 | 351 | void onDataWrittenCallback(const GattWriteCallbackParams *params) { |
janjongboom | 0:2ecd71f6ab04 | 352 | // see if we know for which char this message is... |
janjongboom | 0:2ecd71f6ab04 | 353 | typedef std::map<GattCharacteristic*, Updatable* >::iterator it_type; |
janjongboom | 0:2ecd71f6ab04 | 354 | for(it_type it = writeCallbacks.begin(); it != writeCallbacks.end(); it++) { |
janjongboom | 0:2ecd71f6ab04 | 355 | if (it->first->getValueHandle() == params->handle) { |
janjongboom | 0:2ecd71f6ab04 | 356 | it->second->onDataWritten(params->data, params->len); |
janjongboom | 0:2ecd71f6ab04 | 357 | } |
janjongboom | 0:2ecd71f6ab04 | 358 | } |
janjongboom | 0:2ecd71f6ab04 | 359 | } |
janjongboom | 0:2ecd71f6ab04 | 360 | |
janjongboom | 0:2ecd71f6ab04 | 361 | void addToServices(uint16_t uuid, GattCharacteristic* c) { |
janjongboom | 0:2ecd71f6ab04 | 362 | if (uint16_services.count(uuid) == 0) { |
janjongboom | 0:2ecd71f6ab04 | 363 | uint16_services[uuid] = new vector<GattCharacteristic*>(); |
janjongboom | 0:2ecd71f6ab04 | 364 | } |
janjongboom | 0:2ecd71f6ab04 | 365 | |
janjongboom | 0:2ecd71f6ab04 | 366 | uint16_services[uuid]->push_back(c); |
janjongboom | 0:2ecd71f6ab04 | 367 | } |
janjongboom | 0:2ecd71f6ab04 | 368 | |
janjongboom | 0:2ecd71f6ab04 | 369 | void addToServices(const char* aUuid, GattCharacteristic* c) { |
janjongboom | 0:2ecd71f6ab04 | 370 | string uuid(aUuid); |
janjongboom | 0:2ecd71f6ab04 | 371 | if (uint128_services.count(uuid) == 0) { |
janjongboom | 0:2ecd71f6ab04 | 372 | uint128_services[uuid] = new vector<GattCharacteristic*>(); |
janjongboom | 0:2ecd71f6ab04 | 373 | } |
janjongboom | 0:2ecd71f6ab04 | 374 | |
janjongboom | 0:2ecd71f6ab04 | 375 | uint128_services[uuid]->push_back(c); |
janjongboom | 0:2ecd71f6ab04 | 376 | } |
janjongboom | 0:2ecd71f6ab04 | 377 | |
janjongboom | 0:2ecd71f6ab04 | 378 | BLE* ble; |
janjongboom | 0:2ecd71f6ab04 | 379 | const char* name; |
janjongboom | 0:2ecd71f6ab04 | 380 | uint16_t interval; |
janjongboom | 0:2ecd71f6ab04 | 381 | map<uint16_t, vector<GattCharacteristic*>* > uint16_services; |
janjongboom | 0:2ecd71f6ab04 | 382 | map<string, vector<GattCharacteristic*>* > uint128_services; |
janjongboom | 0:2ecd71f6ab04 | 383 | map<GattCharacteristic*, Updatable*> writeCallbacks; |
janjongboom | 0:2ecd71f6ab04 | 384 | }; |
janjongboom | 0:2ecd71f6ab04 | 385 |