2727#include " BLEDeviceManager.h"
2828#include " BLEProfileManager.h"
2929
30+ #include " BLECallbacks.h"
31+
32+ #include < atomic.h>
33+ #include " ../src/services/ble/conn_internal.h"
34+
3035// GATT Server Only
3136ssize_t profile_read_process (bt_conn_t *conn,
3237 const bt_gatt_attr_t *attr,
@@ -233,6 +238,60 @@ void bleConnectEventHandler(bt_conn_t *conn,
233238 p->handleConnectEvent (conn, err);
234239}
235240
241+ static uint8_t ble_gatt_disconnected_cb (const struct bt_gatt_attr *attr, void *user_data)
242+ {
243+ struct bt_conn *conn = (struct bt_conn *)user_data;
244+ struct _bt_gatt_ccc *ccc;
245+ size_t i;
246+
247+ /* Check attribute user_data must be of type struct _bt_gatt_ccc */
248+ if (attr->write != profile_gatt_attr_write_ccc) {
249+ return BT_GATT_ITER_CONTINUE;
250+ }
251+
252+ ccc = (struct _bt_gatt_ccc *)attr->user_data ;
253+ /* If already disabled skip */
254+ if (!ccc->value ) {
255+ return BT_GATT_ITER_CONTINUE;
256+ }
257+
258+ for (i = 0 ; i < ccc->cfg_len ; i++)
259+ {
260+ /* Ignore configurations with disabled value */
261+ if (!ccc->cfg [i].value )
262+ {
263+ continue ;
264+ }
265+
266+ if (bt_addr_le_cmp (&conn->le .dst , &ccc->cfg [i].peer ))
267+ {
268+ struct bt_conn *tmp;
269+
270+ /* Skip if there is another peer connected */
271+ tmp = bt_conn_lookup_addr_le (&ccc->cfg [i].peer );
272+ if (tmp) {
273+ if (tmp->state == BT_CONN_CONNECTED) {
274+ bt_conn_unref (tmp);
275+ return BT_GATT_ITER_CONTINUE;
276+ }
277+
278+ bt_conn_unref (tmp);
279+ }
280+ }
281+ }
282+
283+ /* Reset value while disconnected */
284+ memset (&ccc->value , 0 , sizeof (ccc->value ));
285+
286+ if (ccc->cfg_changed ) {
287+ ccc->cfg_changed (ccc->value );
288+ }
289+
290+ pr_debug (LOG_MODULE_BLE, " ccc %p reseted" , ccc);
291+
292+ return BT_GATT_ITER_CONTINUE;
293+ }
294+
236295
237296void bleDisconnectEventHandler (bt_conn_t *conn,
238297 uint8_t reason,
@@ -241,6 +300,7 @@ void bleDisconnectEventHandler(bt_conn_t *conn,
241300 BLEDeviceManager* p = (BLEDeviceManager*)param;
242301
243302 pr_info (LOG_MODULE_BLE, " Connect lost. Reason: %d" , reason);
303+ bt_gatt_foreach_attr (0x0001 , 0xffff , ble_gatt_disconnected_cb, conn);
244304
245305 p->handleDisconnectEvent (conn, reason);
246306}
@@ -279,3 +339,29 @@ void ble_on_write_no_rsp_complete(struct bt_conn *conn, uint8_t err,
279339 BLECharacteristicImp::writeResponseReceived (conn, err, data);
280340}
281341
342+ ssize_t profile_gatt_attr_write_ccc (struct bt_conn *conn,
343+ const struct bt_gatt_attr *attr,
344+ const void *buf,
345+ uint16_t len,
346+ uint16_t offset)
347+ {
348+ struct _bt_gatt_ccc *ccc = (struct _bt_gatt_ccc *)attr->user_data ;
349+ const uint16_t *data = (const uint16_t *)buf;
350+ bool cccdChanged = (ccc->value != *data);
351+ ssize_t retValue = bt_gatt_attr_write_ccc (conn, attr, buf, len, offset);
352+ if (cccdChanged)
353+ {
354+ // Find characteristic and do notification
355+ const struct bt_gatt_attr *attrChrc = attr - 1 ;
356+ BLEAttribute *bleattr = (BLEAttribute *)attrChrc->user_data ;
357+ BLEAttributeType type = bleattr->type ();
358+ pr_debug (LOG_MODULE_BLE, " The Attribute type:%d" , type);
359+ if (BLETypeCharacteristic == type)
360+ {
361+ BLECharacteristicImp *blecharacteritic = (BLECharacteristicImp*)bleattr;
362+ blecharacteritic->cccdValueChanged ();
363+ }
364+ }
365+ return retValue;
366+ }
367+
0 commit comments