Skip to content

Commit e9170e6

Browse files
committed
BLE: Cordio fix default connection handle for GattServer write and areUpdatesEnabled
1 parent c30eee0 commit e9170e6

File tree

1 file changed

+94
-32
lines changed

1 file changed

+94
-32
lines changed

features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioGattServer.cpp

Lines changed: 94 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include <algorithm>
1818
#include "CordioGattServer.h"
19-
#include "CordioGap.h"
2019
#include "mbed.h"
2120
#include "wsf_types.h"
2221
#include "att_api.h"
@@ -286,33 +285,63 @@ ble_error_t GattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Hand
286285

287286
ble_error_t GattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
288287
{
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+
}
290299

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
291307
if (AttsSetAttr(attributeHandle, len, (uint8_t*)buffer) != ATT_SUCCESS) {
292308
return BLE_ERROR_PARAM_OUT_OF_RANGE;
293309
}
294310

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+
}
297315

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);
304338
}
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);
314341
}
315342
}
343+
344+
AttsCccSet(conn_id, idx, *((uint16_t*)buffer));
316345
}
317346

318347
return BLE_ERROR_NONE;
@@ -332,26 +361,59 @@ ble_error_t GattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Han
332361
}
333362
}
334363

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;
337396
}
338397

339398
ble_error_t GattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP)
340399
{
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+
}
342408

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)) {
349411
*enabledP = true;
350-
} else {
351-
*enabledP = false;
412+
return BLE_ERROR_NONE;
352413
}
353-
return BLE_ERROR_NONE;
354414
}
415+
*enabledP = false;
416+
return BLE_ERROR_NONE;
355417
}
356418
}
357419

@@ -365,7 +427,7 @@ ble_error_t GattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const
365427
for (idx = 0; idx < cccCnt; idx++) {
366428
if (characteristic.getValueHandle() == cccHandles[idx]) {
367429
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)) {
369431
*enabledP = true;
370432
} else {
371433
*enabledP = false;

0 commit comments

Comments
 (0)