Demonstration of possible usage of the GattServer

Dependents:   mbed-os-example-ble-GattServer_ECG

Committer:
mbed_official
Date:
Mon Mar 25 15:01:13 2019 +0000
Revision:
19:622c672f6d5f
Parent:
14:de95c96e3305
Merge pull request #225 from paul-szczepanek-arm/master

fix using mixed APIs in Gattserver example
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-ble

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 14:de95c96e3305 1 /* mbed Microcontroller Library
mbed_official 14:de95c96e3305 2 * Copyright (c) 2017 ARM Limited
mbed_official 14:de95c96e3305 3 *
mbed_official 14:de95c96e3305 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 14:de95c96e3305 5 * you may not use this file except in compliance with the License.
mbed_official 14:de95c96e3305 6 * You may obtain a copy of the License at
mbed_official 14:de95c96e3305 7 *
mbed_official 14:de95c96e3305 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 14:de95c96e3305 9 *
mbed_official 14:de95c96e3305 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 14:de95c96e3305 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 14:de95c96e3305 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 14:de95c96e3305 13 * See the License for the specific language governing permissions and
mbed_official 14:de95c96e3305 14 * limitations under the License.
mbed_official 14:de95c96e3305 15 */
mbed_official 14:de95c96e3305 16
mbed_official 14:de95c96e3305 17 #include <stdio.h>
mbed_official 14:de95c96e3305 18
mbed_official 14:de95c96e3305 19 #include "platform/Callback.h"
mbed_official 14:de95c96e3305 20 #include "events/EventQueue.h"
mbed_official 14:de95c96e3305 21 #include "platform/NonCopyable.h"
mbed_official 14:de95c96e3305 22
mbed_official 14:de95c96e3305 23 #include "ble/BLE.h"
mbed_official 14:de95c96e3305 24 #include "ble/Gap.h"
mbed_official 14:de95c96e3305 25 #include "ble/GattClient.h"
mbed_official 14:de95c96e3305 26 #include "ble/GapAdvertisingParams.h"
mbed_official 14:de95c96e3305 27 #include "ble/GapAdvertisingData.h"
mbed_official 14:de95c96e3305 28 #include "ble/GattServer.h"
mbed_official 14:de95c96e3305 29 #include "BLEProcess.h"
mbed_official 14:de95c96e3305 30
mbed_official 14:de95c96e3305 31 using mbed::callback;
mbed_official 14:de95c96e3305 32
mbed_official 14:de95c96e3305 33 /**
mbed_official 14:de95c96e3305 34 * A Clock service that demonstrate the GattServer features.
mbed_official 14:de95c96e3305 35 *
mbed_official 14:de95c96e3305 36 * The clock service host three characteristics that model the current hour,
mbed_official 14:de95c96e3305 37 * minute and second of the clock. The value of the second characteristic is
mbed_official 14:de95c96e3305 38 * incremented automatically by the system.
mbed_official 14:de95c96e3305 39 *
mbed_official 14:de95c96e3305 40 * A client can subscribe to updates of the clock characteristics and get
mbed_official 14:de95c96e3305 41 * notified when one of the value is changed. Clients can also change value of
mbed_official 14:de95c96e3305 42 * the second, minute and hour characteristric.
mbed_official 14:de95c96e3305 43 */
mbed_official 14:de95c96e3305 44 class ClockService {
mbed_official 14:de95c96e3305 45 typedef ClockService Self;
mbed_official 14:de95c96e3305 46
mbed_official 14:de95c96e3305 47 public:
mbed_official 14:de95c96e3305 48 ClockService() :
mbed_official 14:de95c96e3305 49 _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0),
mbed_official 14:de95c96e3305 50 _minute_char("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0),
mbed_official 14:de95c96e3305 51 _second_char("8dd6a1b7-bc75-4741-8a26-264af75807de", 0),
mbed_official 14:de95c96e3305 52 _clock_service(
mbed_official 14:de95c96e3305 53 /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed",
mbed_official 14:de95c96e3305 54 /* characteristics */ _clock_characteristics,
mbed_official 14:de95c96e3305 55 /* numCharacteristics */ sizeof(_clock_characteristics) /
mbed_official 14:de95c96e3305 56 sizeof(_clock_characteristics[0])
mbed_official 14:de95c96e3305 57 ),
mbed_official 14:de95c96e3305 58 _server(NULL),
mbed_official 14:de95c96e3305 59 _event_queue(NULL)
mbed_official 14:de95c96e3305 60 {
mbed_official 14:de95c96e3305 61 // update internal pointers (value, descriptors and characteristics array)
mbed_official 14:de95c96e3305 62 _clock_characteristics[0] = &_hour_char;
mbed_official 14:de95c96e3305 63 _clock_characteristics[1] = &_minute_char;
mbed_official 14:de95c96e3305 64 _clock_characteristics[2] = &_second_char;
mbed_official 14:de95c96e3305 65
mbed_official 14:de95c96e3305 66 // setup authorization handlers
mbed_official 14:de95c96e3305 67 _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
mbed_official 14:de95c96e3305 68 _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
mbed_official 14:de95c96e3305 69 _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
mbed_official 14:de95c96e3305 70 }
mbed_official 14:de95c96e3305 71
mbed_official 14:de95c96e3305 72
mbed_official 14:de95c96e3305 73
mbed_official 14:de95c96e3305 74 void start(BLE &ble_interface, events::EventQueue &event_queue)
mbed_official 14:de95c96e3305 75 {
mbed_official 14:de95c96e3305 76 if (_event_queue) {
mbed_official 14:de95c96e3305 77 return;
mbed_official 14:de95c96e3305 78 }
mbed_official 14:de95c96e3305 79
mbed_official 14:de95c96e3305 80 _server = &ble_interface.gattServer();
mbed_official 14:de95c96e3305 81 _event_queue = &event_queue;
mbed_official 14:de95c96e3305 82
mbed_official 14:de95c96e3305 83 // register the service
mbed_official 14:de95c96e3305 84 printf("Adding demo service\r\n");
mbed_official 14:de95c96e3305 85 ble_error_t err = _server->addService(_clock_service);
mbed_official 14:de95c96e3305 86
mbed_official 14:de95c96e3305 87 if (err) {
mbed_official 14:de95c96e3305 88 printf("Error %u during demo service registration.\r\n", err);
mbed_official 14:de95c96e3305 89 return;
mbed_official 14:de95c96e3305 90 }
mbed_official 14:de95c96e3305 91
mbed_official 14:de95c96e3305 92 // read write handler
mbed_official 14:de95c96e3305 93 _server->onDataSent(as_cb(&Self::when_data_sent));
mbed_official 14:de95c96e3305 94 _server->onDataWritten(as_cb(&Self::when_data_written));
mbed_official 14:de95c96e3305 95 _server->onDataRead(as_cb(&Self::when_data_read));
mbed_official 14:de95c96e3305 96
mbed_official 14:de95c96e3305 97 // updates subscribtion handlers
mbed_official 14:de95c96e3305 98 _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled));
mbed_official 14:de95c96e3305 99 _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled));
mbed_official 14:de95c96e3305 100 _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received));
mbed_official 14:de95c96e3305 101
mbed_official 14:de95c96e3305 102 // print the handles
mbed_official 14:de95c96e3305 103 printf("clock service registered\r\n");
mbed_official 14:de95c96e3305 104 printf("service handle: %u\r\n", _clock_service.getHandle());
mbed_official 14:de95c96e3305 105 printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle());
mbed_official 14:de95c96e3305 106 printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle());
mbed_official 14:de95c96e3305 107 printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle());
mbed_official 14:de95c96e3305 108
mbed_official 14:de95c96e3305 109 _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second));
mbed_official 14:de95c96e3305 110 }
mbed_official 14:de95c96e3305 111
mbed_official 14:de95c96e3305 112 private:
mbed_official 14:de95c96e3305 113
mbed_official 14:de95c96e3305 114 /**
mbed_official 14:de95c96e3305 115 * Handler called when a notification or an indication has been sent.
mbed_official 14:de95c96e3305 116 */
mbed_official 14:de95c96e3305 117 void when_data_sent(unsigned count)
mbed_official 14:de95c96e3305 118 {
mbed_official 14:de95c96e3305 119 printf("sent %u updates\r\n", count);
mbed_official 14:de95c96e3305 120 }
mbed_official 14:de95c96e3305 121
mbed_official 14:de95c96e3305 122 /**
mbed_official 14:de95c96e3305 123 * Handler called after an attribute has been written.
mbed_official 14:de95c96e3305 124 */
mbed_official 14:de95c96e3305 125 void when_data_written(const GattWriteCallbackParams *e)
mbed_official 14:de95c96e3305 126 {
mbed_official 14:de95c96e3305 127 printf("data written:\r\n");
mbed_official 14:de95c96e3305 128 printf("\tconnection handle: %u\r\n", e->connHandle);
mbed_official 14:de95c96e3305 129 printf("\tattribute handle: %u", e->handle);
mbed_official 14:de95c96e3305 130 if (e->handle == _hour_char.getValueHandle()) {
mbed_official 14:de95c96e3305 131 printf(" (hour characteristic)\r\n");
mbed_official 14:de95c96e3305 132 } else if (e->handle == _minute_char.getValueHandle()) {
mbed_official 14:de95c96e3305 133 printf(" (minute characteristic)\r\n");
mbed_official 14:de95c96e3305 134 } else if (e->handle == _second_char.getValueHandle()) {
mbed_official 14:de95c96e3305 135 printf(" (second characteristic)\r\n");
mbed_official 14:de95c96e3305 136 } else {
mbed_official 14:de95c96e3305 137 printf("\r\n");
mbed_official 14:de95c96e3305 138 }
mbed_official 14:de95c96e3305 139 printf("\twrite operation: %u\r\n", e->writeOp);
mbed_official 14:de95c96e3305 140 printf("\toffset: %u\r\n", e->offset);
mbed_official 14:de95c96e3305 141 printf("\tlength: %u\r\n", e->len);
mbed_official 14:de95c96e3305 142 printf("\t data: ");
mbed_official 14:de95c96e3305 143
mbed_official 14:de95c96e3305 144 for (size_t i = 0; i < e->len; ++i) {
mbed_official 14:de95c96e3305 145 printf("%02X", e->data[i]);
mbed_official 14:de95c96e3305 146 }
mbed_official 14:de95c96e3305 147
mbed_official 14:de95c96e3305 148 printf("\r\n");
mbed_official 14:de95c96e3305 149 }
mbed_official 14:de95c96e3305 150
mbed_official 14:de95c96e3305 151 /**
mbed_official 14:de95c96e3305 152 * Handler called after an attribute has been read.
mbed_official 14:de95c96e3305 153 */
mbed_official 14:de95c96e3305 154 void when_data_read(const GattReadCallbackParams *e)
mbed_official 14:de95c96e3305 155 {
mbed_official 14:de95c96e3305 156 printf("data read:\r\n");
mbed_official 14:de95c96e3305 157 printf("\tconnection handle: %u\r\n", e->connHandle);
mbed_official 14:de95c96e3305 158 printf("\tattribute handle: %u", e->handle);
mbed_official 14:de95c96e3305 159 if (e->handle == _hour_char.getValueHandle()) {
mbed_official 14:de95c96e3305 160 printf(" (hour characteristic)\r\n");
mbed_official 14:de95c96e3305 161 } else if (e->handle == _minute_char.getValueHandle()) {
mbed_official 14:de95c96e3305 162 printf(" (minute characteristic)\r\n");
mbed_official 14:de95c96e3305 163 } else if (e->handle == _second_char.getValueHandle()) {
mbed_official 14:de95c96e3305 164 printf(" (second characteristic)\r\n");
mbed_official 14:de95c96e3305 165 } else {
mbed_official 14:de95c96e3305 166 printf("\r\n");
mbed_official 14:de95c96e3305 167 }
mbed_official 14:de95c96e3305 168 }
mbed_official 14:de95c96e3305 169
mbed_official 14:de95c96e3305 170 /**
mbed_official 14:de95c96e3305 171 * Handler called after a client has subscribed to notification or indication.
mbed_official 14:de95c96e3305 172 *
mbed_official 14:de95c96e3305 173 * @param handle Handle of the characteristic value affected by the change.
mbed_official 14:de95c96e3305 174 */
mbed_official 14:de95c96e3305 175 void when_update_enabled(GattAttribute::Handle_t handle)
mbed_official 14:de95c96e3305 176 {
mbed_official 14:de95c96e3305 177 printf("update enabled on handle %d\r\n", handle);
mbed_official 14:de95c96e3305 178 }
mbed_official 14:de95c96e3305 179
mbed_official 14:de95c96e3305 180 /**
mbed_official 14:de95c96e3305 181 * Handler called after a client has cancelled his subscription from
mbed_official 14:de95c96e3305 182 * notification or indication.
mbed_official 14:de95c96e3305 183 *
mbed_official 14:de95c96e3305 184 * @param handle Handle of the characteristic value affected by the change.
mbed_official 14:de95c96e3305 185 */
mbed_official 14:de95c96e3305 186 void when_update_disabled(GattAttribute::Handle_t handle)
mbed_official 14:de95c96e3305 187 {
mbed_official 14:de95c96e3305 188 printf("update disabled on handle %d\r\n", handle);
mbed_official 14:de95c96e3305 189 }
mbed_official 14:de95c96e3305 190
mbed_official 14:de95c96e3305 191 /**
mbed_official 14:de95c96e3305 192 * Handler called when an indication confirmation has been received.
mbed_official 14:de95c96e3305 193 *
mbed_official 14:de95c96e3305 194 * @param handle Handle of the characteristic value that has emitted the
mbed_official 14:de95c96e3305 195 * indication.
mbed_official 14:de95c96e3305 196 */
mbed_official 14:de95c96e3305 197 void when_confirmation_received(GattAttribute::Handle_t handle)
mbed_official 14:de95c96e3305 198 {
mbed_official 14:de95c96e3305 199 printf("confirmation received on handle %d\r\n", handle);
mbed_official 14:de95c96e3305 200 }
mbed_official 14:de95c96e3305 201
mbed_official 14:de95c96e3305 202 /**
mbed_official 14:de95c96e3305 203 * Handler called when a write request is received.
mbed_official 14:de95c96e3305 204 *
mbed_official 14:de95c96e3305 205 * This handler verify that the value submitted by the client is valid before
mbed_official 14:de95c96e3305 206 * authorizing the operation.
mbed_official 14:de95c96e3305 207 */
mbed_official 14:de95c96e3305 208 void authorize_client_write(GattWriteAuthCallbackParams *e)
mbed_official 14:de95c96e3305 209 {
mbed_official 14:de95c96e3305 210 printf("characteristic %u write authorization\r\n", e->handle);
mbed_official 14:de95c96e3305 211
mbed_official 14:de95c96e3305 212 if (e->offset != 0) {
mbed_official 14:de95c96e3305 213 printf("Error invalid offset\r\n");
mbed_official 14:de95c96e3305 214 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbed_official 14:de95c96e3305 215 return;
mbed_official 14:de95c96e3305 216 }
mbed_official 14:de95c96e3305 217
mbed_official 14:de95c96e3305 218 if (e->len != 1) {
mbed_official 14:de95c96e3305 219 printf("Error invalid len\r\n");
mbed_official 14:de95c96e3305 220 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbed_official 14:de95c96e3305 221 return;
mbed_official 14:de95c96e3305 222 }
mbed_official 14:de95c96e3305 223
mbed_official 14:de95c96e3305 224 if ((e->data[0] >= 60) ||
mbed_official 14:de95c96e3305 225 ((e->data[0] >= 24) && (e->handle == _hour_char.getValueHandle()))) {
mbed_official 14:de95c96e3305 226 printf("Error invalid data\r\n");
mbed_official 14:de95c96e3305 227 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
mbed_official 14:de95c96e3305 228 return;
mbed_official 14:de95c96e3305 229 }
mbed_official 14:de95c96e3305 230
mbed_official 14:de95c96e3305 231 e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbed_official 14:de95c96e3305 232 }
mbed_official 14:de95c96e3305 233
mbed_official 14:de95c96e3305 234 /**
mbed_official 14:de95c96e3305 235 * Increment the second counter.
mbed_official 14:de95c96e3305 236 */
mbed_official 14:de95c96e3305 237 void increment_second(void)
mbed_official 14:de95c96e3305 238 {
mbed_official 14:de95c96e3305 239 uint8_t second = 0;
mbed_official 14:de95c96e3305 240 ble_error_t err = _second_char.get(*_server, second);
mbed_official 14:de95c96e3305 241 if (err) {
mbed_official 14:de95c96e3305 242 printf("read of the second value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 243 return;
mbed_official 14:de95c96e3305 244 }
mbed_official 14:de95c96e3305 245
mbed_official 14:de95c96e3305 246 second = (second + 1) % 60;
mbed_official 14:de95c96e3305 247
mbed_official 14:de95c96e3305 248 err = _second_char.set(*_server, second);
mbed_official 14:de95c96e3305 249 if (err) {
mbed_official 14:de95c96e3305 250 printf("write of the second value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 251 return;
mbed_official 14:de95c96e3305 252 }
mbed_official 14:de95c96e3305 253
mbed_official 14:de95c96e3305 254 if (second == 0) {
mbed_official 14:de95c96e3305 255 increment_minute();
mbed_official 14:de95c96e3305 256 }
mbed_official 14:de95c96e3305 257 }
mbed_official 14:de95c96e3305 258
mbed_official 14:de95c96e3305 259 /**
mbed_official 14:de95c96e3305 260 * Increment the minute counter.
mbed_official 14:de95c96e3305 261 */
mbed_official 14:de95c96e3305 262 void increment_minute(void)
mbed_official 14:de95c96e3305 263 {
mbed_official 14:de95c96e3305 264 uint8_t minute = 0;
mbed_official 14:de95c96e3305 265 ble_error_t err = _minute_char.get(*_server, minute);
mbed_official 14:de95c96e3305 266 if (err) {
mbed_official 14:de95c96e3305 267 printf("read of the minute value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 268 return;
mbed_official 14:de95c96e3305 269 }
mbed_official 14:de95c96e3305 270
mbed_official 14:de95c96e3305 271 minute = (minute + 1) % 60;
mbed_official 14:de95c96e3305 272
mbed_official 14:de95c96e3305 273 err = _minute_char.set(*_server, minute);
mbed_official 14:de95c96e3305 274 if (err) {
mbed_official 14:de95c96e3305 275 printf("write of the minute value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 276 return;
mbed_official 14:de95c96e3305 277 }
mbed_official 14:de95c96e3305 278
mbed_official 14:de95c96e3305 279 if (minute == 0) {
mbed_official 14:de95c96e3305 280 increment_hour();
mbed_official 14:de95c96e3305 281 }
mbed_official 14:de95c96e3305 282 }
mbed_official 14:de95c96e3305 283
mbed_official 14:de95c96e3305 284 /**
mbed_official 14:de95c96e3305 285 * Increment the hour counter.
mbed_official 14:de95c96e3305 286 */
mbed_official 14:de95c96e3305 287 void increment_hour(void)
mbed_official 14:de95c96e3305 288 {
mbed_official 14:de95c96e3305 289 uint8_t hour = 0;
mbed_official 14:de95c96e3305 290 ble_error_t err = _hour_char.get(*_server, hour);
mbed_official 14:de95c96e3305 291 if (err) {
mbed_official 14:de95c96e3305 292 printf("read of the hour value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 293 return;
mbed_official 14:de95c96e3305 294 }
mbed_official 14:de95c96e3305 295
mbed_official 14:de95c96e3305 296 hour = (hour + 1) % 24;
mbed_official 14:de95c96e3305 297
mbed_official 14:de95c96e3305 298 err = _hour_char.set(*_server, hour);
mbed_official 14:de95c96e3305 299 if (err) {
mbed_official 14:de95c96e3305 300 printf("write of the hour value returned error %u\r\n", err);
mbed_official 14:de95c96e3305 301 return;
mbed_official 14:de95c96e3305 302 }
mbed_official 14:de95c96e3305 303 }
mbed_official 14:de95c96e3305 304
mbed_official 14:de95c96e3305 305 private:
mbed_official 14:de95c96e3305 306 /**
mbed_official 14:de95c96e3305 307 * Helper that construct an event handler from a member function of this
mbed_official 14:de95c96e3305 308 * instance.
mbed_official 14:de95c96e3305 309 */
mbed_official 14:de95c96e3305 310 template<typename Arg>
mbed_official 14:de95c96e3305 311 FunctionPointerWithContext<Arg> as_cb(void (Self::*member)(Arg))
mbed_official 14:de95c96e3305 312 {
mbed_official 14:de95c96e3305 313 return makeFunctionPointer(this, member);
mbed_official 14:de95c96e3305 314 }
mbed_official 14:de95c96e3305 315
mbed_official 14:de95c96e3305 316 /**
mbed_official 14:de95c96e3305 317 * Read, Write, Notify, Indicate Characteristic declaration helper.
mbed_official 14:de95c96e3305 318 *
mbed_official 14:de95c96e3305 319 * @tparam T type of data held by the characteristic.
mbed_official 14:de95c96e3305 320 */
mbed_official 14:de95c96e3305 321 template<typename T>
mbed_official 14:de95c96e3305 322 class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic {
mbed_official 14:de95c96e3305 323 public:
mbed_official 14:de95c96e3305 324 /**
mbed_official 14:de95c96e3305 325 * Construct a characteristic that can be read or written and emit
mbed_official 14:de95c96e3305 326 * notification or indication.
mbed_official 14:de95c96e3305 327 *
mbed_official 14:de95c96e3305 328 * @param[in] uuid The UUID of the characteristic.
mbed_official 14:de95c96e3305 329 * @param[in] initial_value Initial value contained by the characteristic.
mbed_official 14:de95c96e3305 330 */
mbed_official 14:de95c96e3305 331 ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) :
mbed_official 14:de95c96e3305 332 GattCharacteristic(
mbed_official 14:de95c96e3305 333 /* UUID */ uuid,
mbed_official 14:de95c96e3305 334 /* Initial value */ &_value,
mbed_official 14:de95c96e3305 335 /* Value size */ sizeof(_value),
mbed_official 14:de95c96e3305 336 /* Value capacity */ sizeof(_value),
mbed_official 14:de95c96e3305 337 /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |
mbed_official 14:de95c96e3305 338 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
mbed_official 14:de95c96e3305 339 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
mbed_official 14:de95c96e3305 340 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE,
mbed_official 14:de95c96e3305 341 /* Descriptors */ NULL,
mbed_official 14:de95c96e3305 342 /* Num descriptors */ 0,
mbed_official 14:de95c96e3305 343 /* variable len */ false
mbed_official 14:de95c96e3305 344 ),
mbed_official 14:de95c96e3305 345 _value(initial_value) {
mbed_official 14:de95c96e3305 346 }
mbed_official 14:de95c96e3305 347
mbed_official 14:de95c96e3305 348 /**
mbed_official 14:de95c96e3305 349 * Get the value of this characteristic.
mbed_official 14:de95c96e3305 350 *
mbed_official 14:de95c96e3305 351 * @param[in] server GattServer instance that contain the characteristic
mbed_official 14:de95c96e3305 352 * value.
mbed_official 14:de95c96e3305 353 * @param[in] dst Variable that will receive the characteristic value.
mbed_official 14:de95c96e3305 354 *
mbed_official 14:de95c96e3305 355 * @return BLE_ERROR_NONE in case of success or an appropriate error code.
mbed_official 14:de95c96e3305 356 */
mbed_official 14:de95c96e3305 357 ble_error_t get(GattServer &server, T& dst) const
mbed_official 14:de95c96e3305 358 {
mbed_official 14:de95c96e3305 359 uint16_t value_length = sizeof(dst);
mbed_official 14:de95c96e3305 360 return server.read(getValueHandle(), &dst, &value_length);
mbed_official 14:de95c96e3305 361 }
mbed_official 14:de95c96e3305 362
mbed_official 14:de95c96e3305 363 /**
mbed_official 14:de95c96e3305 364 * Assign a new value to this characteristic.
mbed_official 14:de95c96e3305 365 *
mbed_official 14:de95c96e3305 366 * @param[in] server GattServer instance that will receive the new value.
mbed_official 14:de95c96e3305 367 * @param[in] value The new value to set.
mbed_official 14:de95c96e3305 368 * @param[in] local_only Flag that determine if the change should be kept
mbed_official 14:de95c96e3305 369 * locally or forwarded to subscribed clients.
mbed_official 14:de95c96e3305 370 */
mbed_official 14:de95c96e3305 371 ble_error_t set(
mbed_official 14:de95c96e3305 372 GattServer &server, const uint8_t &value, bool local_only = false
mbed_official 14:de95c96e3305 373 ) const {
mbed_official 14:de95c96e3305 374 return server.write(getValueHandle(), &value, sizeof(value), local_only);
mbed_official 14:de95c96e3305 375 }
mbed_official 14:de95c96e3305 376
mbed_official 14:de95c96e3305 377 private:
mbed_official 14:de95c96e3305 378 uint8_t _value;
mbed_official 14:de95c96e3305 379 };
mbed_official 14:de95c96e3305 380
mbed_official 14:de95c96e3305 381 ReadWriteNotifyIndicateCharacteristic<uint8_t> _hour_char;
mbed_official 14:de95c96e3305 382 ReadWriteNotifyIndicateCharacteristic<uint8_t> _minute_char;
mbed_official 14:de95c96e3305 383 ReadWriteNotifyIndicateCharacteristic<uint8_t> _second_char;
mbed_official 14:de95c96e3305 384
mbed_official 14:de95c96e3305 385 // list of the characteristics of the clock service
mbed_official 14:de95c96e3305 386 GattCharacteristic* _clock_characteristics[3];
mbed_official 14:de95c96e3305 387
mbed_official 14:de95c96e3305 388 // demo service
mbed_official 14:de95c96e3305 389 GattService _clock_service;
mbed_official 14:de95c96e3305 390
mbed_official 14:de95c96e3305 391 GattServer* _server;
mbed_official 14:de95c96e3305 392 events::EventQueue *_event_queue;
mbed_official 14:de95c96e3305 393 };
mbed_official 14:de95c96e3305 394
mbed_official 14:de95c96e3305 395 int main() {
mbed_official 14:de95c96e3305 396 BLE &ble_interface = BLE::Instance();
mbed_official 14:de95c96e3305 397 events::EventQueue event_queue;
mbed_official 14:de95c96e3305 398 ClockService demo_service;
mbed_official 14:de95c96e3305 399 BLEProcess ble_process(event_queue, ble_interface);
mbed_official 14:de95c96e3305 400
mbed_official 14:de95c96e3305 401 ble_process.on_init(callback(&demo_service, &ClockService::start));
mbed_official 14:de95c96e3305 402
mbed_official 14:de95c96e3305 403 // bind the event queue to the ble interface, initialize the interface
mbed_official 14:de95c96e3305 404 // and start advertising
mbed_official 14:de95c96e3305 405 ble_process.start();
mbed_official 14:de95c96e3305 406
mbed_official 14:de95c96e3305 407 // Process the event queue.
mbed_official 14:de95c96e3305 408 event_queue.dispatch_forever();
mbed_official 14:de95c96e3305 409
mbed_official 14:de95c96e3305 410 return 0;
mbed_official 14:de95c96e3305 411 }