Implement MTU changed callback for GATT server 64/213864/1
authorinjun.yang <injun.yang@samsung.com>
Mon, 1 Jul 2019 07:59:12 +0000 (16:59 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 16 Sep 2019 04:16:47 +0000 (13:16 +0900)
[Model] All
[BinType] AP
[Customer] OPEN

[Issue#] N/A
[Request] Internal
[Occurrence Version] N/A

[Problem] Unable to notice MTU changed event to application
[Cause & Measure] Implement MTU changed callback for GATT server
[Checking Method] n/a

[Team] Convergence BT
[Developer] Injun Yang
[Solution company] Samsung
[Change Type] Specification change

Change-Id: I266f8335948c7dd358c8c4e43a974109d297a9b6
Signed-off-by: injun.yang <injun.yang@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
include/bluetooth_internal.h
include/bluetooth_private.h
include/bluetooth_type_internal.h
src/bluetooth-common.c
src/bluetooth-gatt.c
test/bt_unit_test.c
test/bt_unit_test.h

index da9e0002028a4d8c833cd43c00de7aa2fc784e71..adc7fb24002da1a5de39b28321f9a08de462cf38 100644 (file)
@@ -1913,6 +1913,44 @@ int bt_gatt_characteristic_set_properties(bt_gatt_h characteristic, int properti
  */
 int bt_gatt_destroy(bt_gatt_h gatt_handle);
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief  Registers a callback function to be invoked when the ATT MTU is changed.
+ * @since_tizen 5.5
+ * @param[in] server The created GATT server's handle
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ *
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @post bt_device_connection_state_changed_cb() will be invoked.
+ * @see bt_initialize()
+ * @see bt_gatt_server_initialize()
+ * @see bt_gatt_server_create()
+ * @see bt_gatt_server_unset_att_mtu_changed_cb()
+ */
+int bt_gatt_server_set_att_mtu_changed_cb(bt_gatt_server_h server, bt_gatt_server_att_mtu_changed_cb callback, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief Unregisters the callback function to be invoked when the ATT MTU is changed.
+ * @since_tizen 5.5
+ * @param[in] server The created GATT server's handle
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ *
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @see bt_initialize()
+ * @see bt_gatt_server_set_att_mtu_changed_cb()
+ */
+int bt_gatt_server_unset_att_mtu_changed_cb(bt_gatt_server_h server);
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE
  * @brief  Registers a callback function that will be invoked when the A2DP Source connection state is changed.
index a856bb149f9726c11e62c4d20a2dbe1e16730e55..a95b30f45e28b5b66d73f3fdc4474810f2b60385 100644 (file)
@@ -322,6 +322,8 @@ typedef struct bt_event_sig_event_slot_s {
 
 typedef struct {
        GSList *services;
+       bt_gatt_server_att_mtu_changed_cb att_mtu_changed_cb;
+       void *att_mtu_changed_user_data;
 } bt_gatt_server_s;
 
 typedef struct {
index f2fe5dcc2ed42bc01318ad9cf6aaa3a056ff1ab4..8b8e8f6b447696f19acc27a4c294410d77664c6a 100644 (file)
@@ -750,6 +750,36 @@ typedef struct {
  */
 typedef void (*bt_device_att_mtu_changed_cb)(int result, bt_device_att_mtu_info_s *mtu_info, void *user_data);
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief Attribute protocol MTU change information structure.
+ * @since_tizen 5.5
+ *
+ * @see bt_gatt_server_att_mtu_changed_cb()
+ */
+typedef struct {
+       char *remote_address;   /**< The address of remote device */
+       unsigned int mtu;               /**< MTU value */
+       unsigned int status;            /**< Request status*/
+} bt_gatt_server_att_mtu_info_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief This callback will be invoked if remote client has requested to change the MTU.
+ * @since_tizen 5.5
+ *
+ * @remarks The @a mtu_info must not be freed by application.
+ *                @a mtu_info can be used only inside the callback.
+ *                If it's needed outside, make a copy.
+ *
+ * @param[in] server The handle of a GATT server
+ * @param[in] mtu_info The MTU information
+ * @param[in] user_data The user data passed from the callback registration function
+ */
+typedef void (*bt_gatt_server_att_mtu_changed_cb)(bt_gatt_server_h server,
+               const bt_gatt_server_att_mtu_info_s *mtu_info,
+               void *user_data);
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_PROXIMITY_MODULE
  * @brief The handle of a Proximity Monitor client handle which is associated with a remote device.
index c92cb0a0b05430358532aeabb79ed3ff03fe754e..d5966fb2ea40e13853c18d1d928f5f29c860073a 100644 (file)
@@ -724,6 +724,23 @@ static int __bt_get_bt_gatt_client_att_mtu_info_s(bt_gatt_client_att_mtu_info_s
        return BT_ERROR_NONE;
 }
 
+static int __bt_get_bt_gatt_server_att_mtu_info_s(bt_gatt_server_att_mtu_info_s **dest, bluetooth_le_att_mtu_info_t *source)
+{
+       *dest = (bt_gatt_server_att_mtu_info_s *)g_malloc0(sizeof(bt_gatt_server_att_mtu_info_s));
+
+       if (_bt_convert_address_to_string(&((*dest)->remote_address), &(source->device_address)) != BT_ERROR_NONE) {
+               g_free(*dest);
+               *dest = NULL;
+
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       (*dest)->mtu = source->mtu;
+       (*dest)->status = source->status;
+
+       return BT_ERROR_NONE;
+}
+
 static int __bt_get_bt_device_connection_info_s(bt_device_connection_info_s **dest, bt_connection_info_t *source)
 {
        *dest = (bt_device_connection_info_s *)g_malloc0(sizeof(bt_device_connection_info_s));
@@ -1252,7 +1269,7 @@ static bool __bt_need_to_handle(int event)
        case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED:
        case BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED:
        case BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED:
-       case BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED:
+       case BLUETOOTH_EVENT_GATT_SERVER_ATT_MTU_CHANGED:
        case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT:
        case BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED:
        case BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION:
@@ -2907,6 +2924,29 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
 
                break;
        }
+       case BLUETOOTH_EVENT_GATT_SERVER_ATT_MTU_CHANGED: {
+               bt_gatt_server_att_mtu_info_s *mtu_info = NULL;
+               const GSList *server_list = NULL;
+               bt_gatt_server_s *server = NULL;
+
+               BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_ATT_MTU_CHANGED");
+
+               server_list = _bt_gatt_get_server_list();
+               if (!server_list)
+                       break;
+
+               server = (bt_gatt_server_s *)server_list->data;
+
+               __bt_get_bt_gatt_server_att_mtu_info_s(&mtu_info, (bluetooth_le_att_mtu_info_t *)(param->param_data));
+
+               if (server && server->att_mtu_changed_cb)
+                       server->att_mtu_changed_cb(server,
+                                       (const bt_gatt_server_att_mtu_info_s *)mtu_info,
+                                       server->att_mtu_changed_user_data);
+
+               g_free(mtu_info);
+               break;
+       }
        case BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED:
                BT_INFO("__bt_le_set_data_length_changed_cb() will be called");
                data_length_info = (bt_le_data_length_params_t *)(param->param_data);
index c17f1ae2013835a225178c8845e6442040873e62..a2b17334dc1c9e09fde8ecb3a0e0ce2ddeacccde 100644 (file)
@@ -3347,6 +3347,44 @@ int bt_gatt_server_foreach_services(bt_gatt_server_h server,
        return BT_ERROR_NONE;
 }
 
+int bt_gatt_server_set_att_mtu_changed_cb(bt_gatt_server_h server, bt_gatt_server_att_mtu_changed_cb callback, void *user_data)
+{
+       bt_gatt_server_s *server_s = (bt_gatt_server_s *)server;
+
+       BT_CHECK_GATT_SERVER_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+       BT_CHECK_INPUT_PARAMETER(server);
+
+       if (server_s->att_mtu_changed_cb) {
+               BT_INFO("Already registered");
+               server_s->att_mtu_changed_cb = callback;
+               server_s->att_mtu_changed_user_data = user_data;
+               return BT_ERROR_NONE;
+       }
+
+       BT_INFO("MTU Changed callback registered");
+       server_s->att_mtu_changed_cb = callback;
+       server_s->att_mtu_changed_user_data = user_data;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_gatt_server_unset_att_mtu_changed_cb(bt_gatt_server_h server)
+{
+       bt_gatt_server_s *server_s = (bt_gatt_server_s *)server;
+
+       BT_CHECK_GATT_SERVER_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(server);
+
+       BT_INFO("MTU Changed callback unregistered");
+       server_s->att_mtu_changed_cb = NULL;
+       server_s->att_mtu_changed_user_data = NULL;
+
+       return BT_ERROR_NONE;
+}
+
 #ifdef TIZEN_GATT_CLIENT
 int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
 {
index 15799fb895bff2c71e02d944ffbd7f4b80fe3e97..af97a574e151980240c686d3cba92cbddec19e5d 100644 (file)
@@ -615,6 +615,8 @@ tc_table_t tc_gatt[] = {
                , BT_UNIT_TEST_FUNCTION_GATT_SERVER_FOREACH_SERVICES},
        {"bt_gatt_server_get_device_mtu"
                , BT_UNIT_TEST_FUNCTION_GATT_SERVER_GET_DEVICE_MTU},
+       {"bt_gatt_server_set_att_mtu_changed_cb"
+               , BT_UNIT_TEST_FUNCTION_GATT_SERVER_SET_MTU_CHANGED_CB},
        {"Register Battery Service"
                , BT_UNIT_TEST_FUNCTION_GATT_SERVER_REGISTER_BATTERY_SVC},
        {"Change Battery Level"
@@ -2714,6 +2716,18 @@ void __tds_activation_req_cb(char *rem_bd_addr,
        tds_act_address = g_strdup(rem_bd_addr);
 }
 
+void __bt_gatt_server_att_mtu_changed_cb(bt_gatt_server_h s, const bt_gatt_server_att_mtu_info_s *mtu_info, void *user_data)
+{
+       TC_PRT("__bt_gatt_server_att_mtu_changed_cb");
+
+       if (mtu_info) {
+               TC_PRT("status [%d]", mtu_info->status);
+               TC_PRT("address [%s]", mtu_info->remote_address);
+               TC_PRT("MTU [%d]", mtu_info->mtu);
+       }
+
+}
+
 void __bt_gatt_server_notification_sent_cb(int result,
        const char *remote_address, bt_gatt_server_h server,
        bt_gatt_h characteristic, bool completed, void *user_data)
@@ -6314,6 +6328,11 @@ int test_input_callback(void *data)
 
                        break;
                }
+               case BT_UNIT_TEST_FUNCTION_GATT_SERVER_SET_MTU_CHANGED_CB: {
+                       ret = bt_gatt_server_set_att_mtu_changed_cb(server, __bt_gatt_server_att_mtu_changed_cb, NULL);
+                       TC_PRT("returns %s\n", __bt_get_error_message(ret));
+                       break;
+               }
                case BT_UNIT_TEST_FUNCTION_GATT_SERVER_REGISTER_BATTERY_SVC: {
                        bt_gatt_h service = NULL;
                        bt_gatt_h characteristic = NULL;
index d88de2647f4860295c0d8d35996356aa230ea569..c2609d0adc84fcb2cfdf83fe1ae566a61847908f 100644 (file)
@@ -260,6 +260,7 @@ BT_UNIT_TEST_FUNCTION_ADAPTER_LE_SET_SCAN_TYPE,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_UNREGISTER_ALL_SERVICES,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_FOREACH_SERVICES,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_GET_DEVICE_MTU,
+       BT_UNIT_TEST_FUNCTION_GATT_SERVER_SET_MTU_CHANGED_CB,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_REGISTER_BATTERY_SVC,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_CHANGE_BATTERY_LEVEL,
        BT_UNIT_TEST_FUNCTION_GATT_SERVER_REGISTER_HEART_RATE_SVC,