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