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