@@ -65,8 +65,32 @@ static const ble_gatts_rw_authorize_reply_params_t write_auth_invalid_reply = {
65
65
}
66
66
};
67
67
68
+ static ble_error_t set_attribute_value (
69
+ Gap::Handle_t connectionHandle,
70
+ GattAttribute::Handle_t attributeHandle,
71
+ ble_gatts_value_t *value
72
+ ) {
73
+ uint32_t err = sd_ble_gatts_value_set (connectionHandle, attributeHandle, value);
74
+ switch (err) {
75
+ case NRF_SUCCESS:
76
+ return BLE_ERROR_NONE;
77
+ case NRF_ERROR_INVALID_ADDR:
78
+ case NRF_ERROR_INVALID_PARAM:
79
+ return BLE_ERROR_INVALID_PARAM;
80
+ case NRF_ERROR_NOT_FOUND:
81
+ case NRF_ERROR_DATA_SIZE:
82
+ case BLE_ERROR_INVALID_CONN_HANDLE:
83
+ case BLE_ERROR_GATTS_INVALID_ATTR_TYPE:
84
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
85
+ case NRF_ERROR_FORBIDDEN:
86
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
87
+ default :
88
+ return BLE_ERROR_UNSPECIFIED;
89
+ }
68
90
}
69
91
92
+ } // end of anonymous namespace
93
+
70
94
/* *************************************************************************/
71
95
/* !
72
96
@brief Adds a new service to the GATT table on the peripheral
@@ -285,53 +309,49 @@ ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute
285
309
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance (BLE::DEFAULT_INSTANCE).getGap ();
286
310
connectionHandle = gap.getConnectionHandle ();
287
311
}
288
- error_t error = (error_t ) sd_ble_gatts_hvx (connectionHandle, &hvx_params);
289
- if (error != ERROR_NONE) {
290
- switch (error) {
291
- case ERROR_BLE_NO_TX_BUFFERS: /* Notifications consume application buffers. The return value can be used for resending notifications. */
292
- case ERROR_BUSY:
293
- returnValue = BLE_STACK_BUSY;
294
- break ;
295
312
296
- case ERROR_INVALID_STATE:
297
- case ERROR_BLEGATTS_SYS_ATTR_MISSING:
298
- returnValue = BLE_ERROR_INVALID_STATE;
299
- break ;
313
+ bool updatesEnabled = false ;
314
+ if (connectionHandle != BLE_CONN_HANDLE_INVALID) {
315
+ ble_error_t err = areUpdatesEnabled (connectionHandle, attributeHandle, &updatesEnabled);
300
316
301
- default :
302
- ASSERT_INT ( ERROR_NONE,
303
- sd_ble_gatts_value_set (connectionHandle, attributeHandle, &value),
304
- BLE_ERROR_PARAM_OUT_OF_RANGE );
317
+ // FIXME: The softdevice allocates and populates CCCD when the client
318
+ // interract with them. Checking for updates may return an out of
319
+ // range error in such case.
320
+ if (err && err != BLE_ERROR_PARAM_OUT_OF_RANGE) {
321
+ return err;
322
+ }
323
+ }
305
324
306
- /* Notifications consume application buffers. The return value can
307
- * be used for resending notifications. */
308
- returnValue = BLE_STACK_BUSY;
309
- break ;
325
+ if (updatesEnabled) {
326
+ error_t error = (error_t ) sd_ble_gatts_hvx (connectionHandle, &hvx_params);
327
+ if (error != ERROR_NONE) {
328
+ switch (error) {
329
+ case ERROR_BLE_NO_TX_BUFFERS: /* Notifications consume application buffers. The return value can be used for resending notifications. */
330
+ case ERROR_BUSY:
331
+ returnValue = BLE_STACK_BUSY;
332
+ break ;
333
+
334
+ case ERROR_INVALID_STATE:
335
+ case ERROR_BLEGATTS_SYS_ATTR_MISSING:
336
+ returnValue = BLE_ERROR_INVALID_STATE;
337
+ break ;
338
+
339
+ default :
340
+ ASSERT_INT ( ERROR_NONE,
341
+ sd_ble_gatts_value_set (connectionHandle, attributeHandle, &value),
342
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
343
+
344
+ /* Notifications consume application buffers. The return value can
345
+ * be used for resending notifications. */
346
+ returnValue = BLE_STACK_BUSY;
347
+ break ;
348
+ }
310
349
}
350
+ } else {
351
+ returnValue = set_attribute_value (connectionHandle, attributeHandle, &value);
311
352
}
312
353
} else {
313
- uint32_t err = sd_ble_gatts_value_set (connectionHandle, attributeHandle, &value);
314
- switch (err) {
315
- case NRF_SUCCESS:
316
- returnValue = BLE_ERROR_NONE;
317
- break ;
318
- case NRF_ERROR_INVALID_ADDR:
319
- case NRF_ERROR_INVALID_PARAM:
320
- returnValue = BLE_ERROR_INVALID_PARAM;
321
- break ;
322
- case NRF_ERROR_NOT_FOUND:
323
- case NRF_ERROR_DATA_SIZE:
324
- case BLE_ERROR_INVALID_CONN_HANDLE:
325
- case BLE_ERROR_GATTS_INVALID_ATTR_TYPE:
326
- returnValue = BLE_ERROR_PARAM_OUT_OF_RANGE;
327
- break ;
328
- case NRF_ERROR_FORBIDDEN:
329
- returnValue = BLE_ERROR_OPERATION_NOT_PERMITTED;
330
- break ;
331
- default :
332
- returnValue = BLE_ERROR_UNSPECIFIED;
333
- break ;
334
- }
354
+ returnValue = set_attribute_value (connectionHandle, attributeHandle, &value);
335
355
}
336
356
337
357
return returnValue;
@@ -346,7 +366,12 @@ ble_error_t nRF5xGattServer::areUpdatesEnabled(const GattCharacteristic &charact
346
366
347
367
ble_error_t nRF5xGattServer::areUpdatesEnabled (Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
348
368
{
349
- int characteristicIndex = resolveValueHandleToCharIndex (characteristic.getValueHandle ());
369
+ return areUpdatesEnabled (connectionHandle, characteristic.getValueHandle (), enabledP);
370
+ }
371
+
372
+ ble_error_t nRF5xGattServer::areUpdatesEnabled (Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, bool *enabledP)
373
+ {
374
+ int characteristicIndex = resolveValueHandleToCharIndex (attributeHandle);
350
375
if (characteristicIndex == -1 ) {
351
376
return BLE_ERROR_INVALID_PARAM;
352
377
}
0 commit comments