16
16
17
17
#include < algorithm>
18
18
#include " CordioGattServer.h"
19
- #include " CordioGap.h"
20
19
#include " mbed.h"
21
20
#include " wsf_types.h"
22
21
#include " att_api.h"
@@ -286,33 +285,63 @@ ble_error_t GattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Hand
286
285
287
286
ble_error_t GattServer::write (GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
288
287
{
289
- uint16_t connectionHandle = Gap::getInstance ().getConnectionHandle ();
288
+ // Check to see if this is a CCCD, if it is the case update the value for all
289
+ // connections
290
+ uint8_t idx;
291
+ for (idx = 0 ; idx < cccCnt; idx++) {
292
+ if (attributeHandle == cccSet[idx].handle ) {
293
+ for (uint16_t conn_id = 0 , conn_found = 0 ; (conn_found < DM_CONN_MAX) && (conn_id < 0x100 ); ++conn_id) {
294
+ if (DmConnInUse (conn_id) == true ) {
295
+ ++conn_found;
296
+ } else {
297
+ continue ;
298
+ }
290
299
300
+ AttsCccSet (conn_id, idx, *((uint16_t *)buffer));
301
+ }
302
+ return BLE_ERROR_NONE;
303
+ }
304
+ }
305
+
306
+ // write the value to the attribute handle
291
307
if (AttsSetAttr (attributeHandle, len, (uint8_t *)buffer) != ATT_SUCCESS) {
292
308
return BLE_ERROR_PARAM_OUT_OF_RANGE;
293
309
}
294
310
295
- if (!localOnly) {
296
- if (connectionHandle != DM_CONN_ID_NONE) {
311
+ // return if the update does not have to be propagated to peers
312
+ if (localOnly) {
313
+ return BLE_ERROR_NONE;
314
+ }
297
315
298
- // Check to see if this characteristic has a CCCD attribute
299
- uint8_t idx;
300
- for (idx = 0 ; idx < cccCnt; idx++) {
301
- if (attributeHandle == cccHandles[idx]) {
302
- break ;
303
- }
316
+ // Check to see if this characteristic has a CCCD attribute
317
+ for (idx = 0 ; idx < cccCnt; idx++) {
318
+ if (attributeHandle == cccHandles[idx]) {
319
+ break ;
320
+ }
321
+ }
322
+
323
+ // exit if the characteristic has no CCCD attribute
324
+ if (idx >= cccCnt) {
325
+ return BLE_ERROR_NONE;
326
+ }
327
+
328
+ // This characteristic has a CCCD attribute. Handle notifications and indications.
329
+ // for all connections
330
+
331
+ for (uint16_t conn_id = 0 , conn_found = 0 ; (conn_found < DM_CONN_MAX) && (conn_id < 0x100 ); ++conn_id) {
332
+ if (DmConnInUse (conn_id) == true ) {
333
+ ++conn_found;
334
+ } else {
335
+ uint16_t cccEnabled = AttsCccEnabled (conn_id, idx);
336
+ if (cccEnabled & ATT_CLIENT_CFG_NOTIFY) {
337
+ AttsHandleValueNtf (conn_id, attributeHandle, len, (uint8_t *)buffer);
304
338
}
305
- if (idx < cccCnt) {
306
- // This characteristic has a CCCD attribute. Handle notifications and indications.
307
- uint16_t cccEnabled = AttsCccEnabled (connectionHandle, idx);
308
- if (cccEnabled & ATT_CLIENT_CFG_NOTIFY) {
309
- AttsHandleValueNtf (connectionHandle, attributeHandle, len, (uint8_t *)buffer);
310
- }
311
- if (cccEnabled & ATT_CLIENT_CFG_INDICATE) {
312
- AttsHandleValueInd (connectionHandle, attributeHandle, len, (uint8_t *)buffer);
313
- }
339
+ if (cccEnabled & ATT_CLIENT_CFG_INDICATE) {
340
+ AttsHandleValueInd (conn_id, attributeHandle, len, (uint8_t *)buffer);
314
341
}
315
342
}
343
+
344
+ AttsCccSet (conn_id, idx, *((uint16_t *)buffer));
316
345
}
317
346
318
347
return BLE_ERROR_NONE;
@@ -332,26 +361,59 @@ ble_error_t GattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Han
332
361
}
333
362
}
334
363
335
- // This is not a CCCD. Use the non-connection specific update method.
336
- return write (attributeHandle, buffer, len, localOnly);
364
+ // write the value to the attribute handle
365
+ if (AttsSetAttr (attributeHandle, len, (uint8_t *)buffer) != ATT_SUCCESS) {
366
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
367
+ }
368
+
369
+ // return if the update does not have to be propagated to peers
370
+ if (localOnly) {
371
+ return BLE_ERROR_NONE;
372
+ }
373
+
374
+ // Check to see if this characteristic has a CCCD attribute
375
+ for (idx = 0 ; idx < cccCnt; idx++) {
376
+ if (attributeHandle == cccHandles[idx]) {
377
+ break ;
378
+ }
379
+ }
380
+
381
+ // exit if the characteristic has no CCCD attribute
382
+ if (idx >= cccCnt) {
383
+ return BLE_ERROR_NONE;
384
+ }
385
+
386
+ // This characteristic has a CCCD attribute. Handle notifications and indications.
387
+ uint16_t cccEnabled = AttsCccEnabled (connectionHandle, idx);
388
+ if (cccEnabled & ATT_CLIENT_CFG_NOTIFY) {
389
+ AttsHandleValueNtf (connectionHandle, attributeHandle, len, (uint8_t *)buffer);
390
+ }
391
+ if (cccEnabled & ATT_CLIENT_CFG_INDICATE) {
392
+ AttsHandleValueInd (connectionHandle, attributeHandle, len, (uint8_t *)buffer);
393
+ }
394
+
395
+ return BLE_ERROR_NONE;
337
396
}
338
397
339
398
ble_error_t GattServer::areUpdatesEnabled (const GattCharacteristic &characteristic, bool *enabledP)
340
399
{
341
- uint16_t connectionHandle = Gap::getInstance ().getConnectionHandle ();
400
+ for (size_t idx = 0 ; idx < cccCnt; idx++) {
401
+ if (characteristic.getValueHandle () == cccHandles[idx]) {
402
+ for (uint16_t conn_id = 0 , conn_found = 0 ; (conn_found < DM_CONN_MAX) && (conn_id < 0x100 ); ++conn_id) {
403
+ if (DmConnInUse (conn_id) == true ) {
404
+ ++conn_found;
405
+ } else {
406
+ continue ;
407
+ }
342
408
343
- if (connectionHandle != DM_CONN_ID_NONE) {
344
- uint8_t idx;
345
- for (idx = 0 ; idx < cccCnt; idx++) {
346
- if (characteristic.getValueHandle () == cccHandles[idx]) {
347
- uint16_t cccValue = AttsCccGet (connectionHandle, idx);
348
- if (cccValue & ATT_CLIENT_CFG_NOTIFY) {
409
+ uint16_t cccValue = AttsCccGet (conn_id, idx);
410
+ if ((cccValue & ATT_CLIENT_CFG_NOTIFY) || (cccValue & ATT_CLIENT_CFG_INDICATE)) {
349
411
*enabledP = true ;
350
- } else {
351
- *enabledP = false ;
412
+ return BLE_ERROR_NONE;
352
413
}
353
- return BLE_ERROR_NONE;
354
414
}
415
+ *enabledP = false ;
416
+ return BLE_ERROR_NONE;
355
417
}
356
418
}
357
419
@@ -365,7 +427,7 @@ ble_error_t GattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const
365
427
for (idx = 0 ; idx < cccCnt; idx++) {
366
428
if (characteristic.getValueHandle () == cccHandles[idx]) {
367
429
uint16_t cccValue = AttsCccGet (connectionHandle, idx);
368
- if (cccValue & ATT_CLIENT_CFG_NOTIFY) {
430
+ if (cccValue & ATT_CLIENT_CFG_NOTIFY || (cccValue & ATT_CLIENT_CFG_INDICATE) ) {
369
431
*enabledP = true ;
370
432
} else {
371
433
*enabledP = false ;
0 commit comments