GATT: New callback API for notification state change 70/262170/3 accepted/tizen/unified/20210805.131636 submit/tizen/20210804.223925
authorAnuj Jain <anuj01.jain@samsung.com>
Tue, 3 Aug 2021 08:49:42 +0000 (14:19 +0530)
committerAnuj Jain <anuj01.jain@samsung.com>
Wed, 4 Aug 2021 03:49:28 +0000 (09:19 +0530)
Make new callback api for notification enable/disable which
provides additional functionality of reporting client address
on notification state change.

This patchset should be merged with the following bluez and
bluetooth-frwk's patchset in order to match API and avoid crash:
bluez Change-Id:I81a0994f2299e988f8ef6428537647c899700fda
bluetooth-frwk Change-Id: Ib54ba54c318692b4ee0eaef9b2310c60dadeb661

Change-Id: Ic4868234a4fc682f9bff2c66ac1aee2683f3d6c6
Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
include/bluetooth_internal.h
include/bluetooth_private.h
include/bluetooth_type_internal.h
src/bluetooth-common.c
src/bluetooth-gatt.c
src/bluetooth-hrp.c
tests/test/ble_mouse.c
tests/test/bt_unit_test.c

index c23f64e..3532889 100644 (file)
@@ -2210,6 +2210,25 @@ int bt_gatt_set_permissions(bt_gatt_h gatt_handle, int permissions);
 int bt_gatt_characteristic_set_properties(bt_gatt_h characteristic, int properties);
 
 /**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief  Registers a callback function to be invoked when the remote device enables or disables the Notification/Indication for particular characteristics.
+ * @since_tizen 6.5
+ *
+ * @param[in] gatt_handle The GATT handle of a characteristic
+ * @param[in] callback The callback to be invoked
+ * @param[in] user_data The user data to be passed to @a callback function
+ * @return      0 on success, otherwise a negative error value
+ * @retval #BT_ERROR_NONE Successful
+ * @retval #BT_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #BT_ERROR_NOT_SUPPORTED      Not supported
+ *
+ * @see bt_gatt_server_characteristic_notif_state_changed_cb()
+ */
+int bt_gatt_server_set_characteristic_notif_state_change_cb(bt_gatt_h gatt_handle,
+                               bt_gatt_server_characteristic_notif_state_changed_cb callback,
+                               void *user_data);
+
+/**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE
  * @brief Destroys the GATT handle
  * @since_tizen 2.4
index 05900b8..0850506 100644 (file)
@@ -445,7 +445,9 @@ typedef struct {
        void *notified_user_data;
 
        bt_gatt_server_characteristic_notification_state_changed_cb notification_changed_cb;
+       bt_gatt_server_characteristic_notif_state_changed_cb notif_changed_cb;
        void *notification_changed_user_data;
+       void *notif_changed_user_data;
 
        int value_length;
        char *value;
index 10b59ab..d55a748 100644 (file)
@@ -655,6 +655,27 @@ typedef void (*bt_device_att_mtu_changed_cb)(int result, bt_device_att_mtu_info_
 
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief  Called when the remote device enables or disables the Notification/Indication for particular characteristics.
+ *
+ * @details By using this callback function, server can know notification state.
+ *
+ * @since_tizen 6.5
+ * @remarks The @a server must not be freed by application.
+ * @remarks The @a gatt_handle must not be freed by application.
+ *
+ * @param[in] remote_address The client device address
+ * @param[in] notify Indicates whether the Notification/Indication is enabled or not
+ * @param[in] server The GATT server handle
+ * @param[in] gatt_handle The characteristic's GATT handle to be read
+ * @param[in] user_data The user data passed from the registration function
+ *
+ * @see bt_gatt_server_set_read_value_requested_cb()
+ */
+typedef void (*bt_gatt_server_characteristic_notif_state_changed_cb) (const char *remote_address, bool notify,
+                       bt_gatt_server_h server, bt_gatt_h gatt_handle, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
  * @brief Attribute protocol MTU change information structure.
  * @since_tizen 5.5
  *
index a8d38f3..1cadb78 100644 (file)
@@ -1096,6 +1096,42 @@ static bt_gatt_server_characteristic_notification_state_changed_cb
        return NULL;
 }
 
+static bt_gatt_server_characteristic_notif_state_changed_cb
+               __bt_gatt_attribute_get_notif_change_cb(
+                       bt_gatt_server_h *server, int handle, bt_gatt_h *char_handle, void **user_data)
+{
+       const GSList *gatt_server_list = NULL;
+       const GSList *l1, *l2, *l3;
+
+       gatt_server_list = _bt_gatt_get_server_list();
+
+       for (l1 = gatt_server_list; l1 != NULL; l1 = l1->next) {
+               bt_gatt_server_s *serv = l1->data;
+
+               if (!serv)
+                       return NULL;
+
+               for (l2 = serv->services; l2 != NULL; l2 = l2->next) {
+                       bt_gatt_service_s *svc = l2->data;
+
+                       for (l3 = svc->characteristics; l3 != NULL; l3 = l3->next) {
+                               bt_gatt_characteristic_s *chr = l3->data;
+
+                               if (chr && chr->handle == handle) {
+                                       if (chr->notif_changed_cb) {
+                                               *user_data = chr->notif_changed_user_data;
+                                               *char_handle =  (bt_gatt_h*) chr;
+                                               *server = serv;
+                                               return chr->notif_changed_cb;
+                                       } else
+                                               return NULL;
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+
 static bt_gatt_server_notification_sent_cb __bt_gatt_attribute_get_notification_completed_cb(
                        bt_gatt_server_h *server, int handle, bt_gatt_h *char_handle, void **user_data)
 {
@@ -2863,21 +2899,34 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                bluetooth_gatt_server_notification_changed_t *notif_info =
                                        (bluetooth_gatt_server_notification_changed_t*)(param->param_data);
 
-               bt_gatt_server_characteristic_notification_state_changed_cb cb;
+               bt_gatt_server_characteristic_notification_state_changed_cb cb1;
+               bt_gatt_server_characteristic_notif_state_changed_cb cb2;
                bt_gatt_server_h server_handle = NULL;
                bt_gatt_h char_handle = NULL;
                void *user_data_cfm = NULL;
 
-               cb = __bt_gatt_attribute_get_notification_change_cb(&server_handle,
+               cb1 = __bt_gatt_attribute_get_notification_change_cb(&server_handle,
+                                               notif_info->handle, &char_handle, &user_data_cfm);
+               cb2 = __bt_gatt_attribute_get_notif_change_cb(&server_handle,
                                                notif_info->handle, &char_handle, &user_data_cfm);
 
-               if (cb == NULL) {
+               if (cb1 == NULL && cb2 == NULL) {
                        BT_INFO("cb is NULL");
                        return;
                }
 
-               BT_INFO("CCCD Noticfication ENABLED [%d]", notif_info->notification);
-               cb(notif_info->notification, server_handle, char_handle, user_data_cfm);
+               if (cb1 != NULL) {
+                       BT_INFO("CCCD Notification ENABLED [%d]", notif_info->notification);
+                       cb1(notif_info->notification, server_handle, char_handle, user_data_cfm);
+               }
+
+               if (cb2 != NULL) {
+                       _bt_convert_address_to_string(&device_addr, &notif_info->device_address);
+                       BT_INFO("CCCD Notification ENABLED [%d]", notif_info->notification);
+                       cb2(device_addr, notif_info->notification, server_handle, char_handle, user_data_cfm);
+                       if (device_addr != NULL)
+                               free(device_addr);
+               }
 #else
                bt_gatt_char_notify_change_t *value_change = param->param_data;
                bt_gatt_server_characteristic_notification_state_changed_cb cb;
index bfba256..5ac2bef 100644 (file)
@@ -2851,6 +2851,26 @@ int bt_gatt_server_set_characteristic_notification_state_change_cb(bt_gatt_h gat
        return BT_ERROR_NONE;
 } /* LCOV_EXCL_STOP */
 
+int bt_gatt_server_set_characteristic_notif_state_change_cb(bt_gatt_h gatt_handle,
+                       bt_gatt_server_characteristic_notif_state_changed_cb callback,
+                       void *user_data)
+{
+       bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+
+       BT_CHECK_GATT_SERVER_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_GATT_SERVER_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(gatt_handle);
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
+       chr->notif_changed_cb = callback; /* LCOV_EXCL_START */
+       chr->notif_changed_user_data = user_data;
+
+       return BT_ERROR_NONE;
+} /* LCOV_EXCL_STOP */
+
 #ifdef TIZEN_FEATURE_GATT_RELAY
 /* LCOV_EXCL_START */
 static int __gatt_service_add_num_handle(bt_gatt_service_s *service)
index cf95587..98d1d82 100644 (file)
@@ -171,15 +171,15 @@ static gboolean __hrp_timeout(gpointer user_data)
        return FALSE;
 }
 
-static void __bt_hrp_gatt_server_set_char_notification_state_change_cb(bool notify,
+static void __bt_hrp_gatt_server_set_char_notif_state_change_cb(const char *remote_address, bool notify,
                bt_gatt_server_h server, bt_gatt_h gatt_handle,
                void *user_data)
 {
-       BT_INFO("[HR]__bt_gatt_server_notification_state_change_cb");
+       BT_INFO("[HR]__bt_gatt_server_notif_state_change_cb");
        BT_INFO("[HR]notify %d", notify);
        BT_INFO("[HR]server %s", (char *)server);
        BT_INFO("[HR]gatt_handle %s", (char *)gatt_handle);
-
+       BT_INFO("[HR]remote address %s", remote_address);
 }
 
 static void __bt_hrp_fast_interval_adv_state_changed_cb(int result,
@@ -355,12 +355,12 @@ static int __bt_hrp_create_secondary_service(void)
                return error_code;
        }
 
-       error_code = bt_gatt_server_set_characteristic_notification_state_change_cb
+       error_code = bt_gatt_server_set_characteristic_notif_state_change_cb
                                                        (hrp_server_info_s.hrs_characteristic,
-                                                       __bt_hrp_gatt_server_set_char_notification_state_change_cb, NULL);
+                                                       __bt_hrp_gatt_server_set_char_notif_state_change_cb, NULL);
 
        if (error_code != BT_ERROR_NONE)
-               BT_ERR("[HR]bt_gatt_server_set_characteristic_notification_state_change_cb : %s\n", _bt_convert_error_to_string(error_code));
+               BT_ERR("[HR]bt_gatt_server_set_characteristic_notif_state_change_cb : %s\n", _bt_convert_error_to_string(error_code));
 
        error_code = bt_gatt_server_register_service(hrp_server_info_s.hrp_sensor, hrp_server_info_s.dis_service);
        if (error_code != BT_ERROR_NONE) {
index 31305db..1bcd848 100644 (file)
@@ -238,12 +238,13 @@ static void __bt_gatt_write_value_desc_req_cb(const char *remote_address,
 }
 
 
-static void __bt_gatt_notification_state_change_cb(bool notify,
+static void __bt_gatt_notif_state_change_cb(const char *remote_address, bool notify,
                bt_gatt_server_h server, bt_gatt_h gatt_handle,
                void *user_data)
 {
        BLE_PRT("Notification %s [%d]", notify ? "enabled" : "disabled", notify);
        BLE_PRT("server %s\n", (char *)server);
+       BLE_PRT("Remote Address %s", remote_address);
 }
 
 
@@ -335,8 +336,8 @@ static int __bt_register_hogp_service(void)
        ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_3,
                __bt_gatt_read_value1_req_cb, NULL);
 
-       ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic1_3,
-               __bt_gatt_notification_state_change_cb, NULL);
+       ret = bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic1_3,
+               __bt_gatt_notif_state_change_cb, NULL);
 
        ret = bt_gatt_service_add_characteristic(service1, characteristic1_3);
        BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
@@ -359,8 +360,8 @@ static int __bt_register_hogp_service(void)
        ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_4,
                __bt_gatt_read_value1_req_cb, NULL);
 
-       ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic1_4,
-               __bt_gatt_notification_state_change_cb, NULL);
+       ret = bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic1_4,
+               __bt_gatt_notif_state_change_cb, NULL);
 
        ret = bt_gatt_service_add_characteristic(service1, characteristic1_4);
        BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
@@ -450,8 +451,8 @@ static int __bt_register_hogp_service(void)
        ret = bt_gatt_server_set_read_value_requested_cb(characteristic2_1,
                __bt_gatt_read_value_req_cb, NULL);
 
-       ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic2_1,
-               __bt_gatt_notification_state_change_cb, NULL);
+       ret = bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic2_1,
+               __bt_gatt_notif_state_change_cb, NULL);
 
        ret = bt_gatt_service_add_characteristic(service2, characteristic2_1);
        BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
index 0966920..2516fb4 100644 (file)
@@ -1915,13 +1915,14 @@ void __bt_gatt_server_read_value_requested_cb(
        g_free(new_value);
 }
 
-void __bt_gatt_server_notification_state_change_cb(bool notify,
+void __bt_gatt_server_notif_state_change_cb(const char *remote_address, bool notify,
                bt_gatt_server_h server, bt_gatt_h gatt_handle,
                void *user_data)
 {
        __print_gatt_handler(gatt_handle);
        TC_PRT("Notification %s [%d]", notify ? "enabled" : "disabled", notify);
        TC_PRT("server %s", (char *)server);
+       TC_PRT("Remote address [%s]", remote_address);
        printf("\n\n");
 }
 
@@ -6947,8 +6948,8 @@ int test_input_callback(void *data)
 
                        bt_gatt_server_set_read_value_requested_cb(characteristic,
                                __bt_gatt_server_read_value_requested_cb, NULL);
-                       bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
-                               __bt_gatt_server_notification_state_change_cb, NULL);
+                       bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic,
+                               __bt_gatt_server_notif_state_change_cb, NULL);
                        ret = bt_gatt_service_add_characteristic(service, characteristic);
                        TC_PRT("bt_gatt_service_add_characteristic : %s\n", __bt_get_error_message(ret));
 
@@ -7017,8 +7018,8 @@ int test_input_callback(void *data)
 
                        bt_gatt_server_set_read_value_requested_cb(characteristic,
                                __bt_gatt_server_read_value_requested_cb, NULL);
-                       bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
-                               __bt_gatt_server_notification_state_change_cb, NULL);
+                       bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic,
+                               __bt_gatt_server_notif_state_change_cb, NULL);
                        ret = bt_gatt_service_add_characteristic(service, characteristic);
                        TC_PRT("bt_gatt_service_add_characteristic : %s\n", __bt_get_error_message(ret));
 
@@ -7100,8 +7101,8 @@ int test_input_callback(void *data)
 
                        bt_gatt_server_set_read_value_requested_cb(characteristic,
                                __bt_gatt_server_read_value_requested_cb, NULL);
-                       bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
-                               __bt_gatt_server_notification_state_change_cb, NULL);
+                       bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic,
+                               __bt_gatt_server_notif_state_change_cb, NULL);
                        ret = bt_gatt_service_add_characteristic(service, characteristic);
                        TC_PRT("bt_gatt_service_add_characteristic : %s\n", __bt_get_error_message(ret));
 
@@ -7483,8 +7484,8 @@ int test_input_callback(void *data)
                        ret = bt_gatt_server_set_write_value_requested_cb(characteristic,
                                __bt_gatt_server_write_value_requested_cb, NULL);
 
-                       ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
-                                               __bt_gatt_server_notification_state_change_cb, NULL);
+                       ret = bt_gatt_server_set_characteristic_notif_state_change_cb(characteristic,
+                                               __bt_gatt_server_notif_state_change_cb, NULL);
 
                        ret = bt_gatt_service_add_characteristic(service, characteristic);
                        TC_PRT("bt_gatt_service_add_characteristic : %s\n", __bt_get_error_message(ret));