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