From: DoHyun Pyun Date: Thu, 6 Feb 2020 05:01:13 +0000 (+0900) Subject: Handle GATT client app's termination X-Git-Tag: submit/tizen/20200214.001348~13 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git;a=commitdiff_plain;h=9ab3a27b600cf4d760e7a510b16f1a662caa3fce Handle GATT client app's termination Change-Id: Ic209290e0b935df315d178409d12838507a0ca2f Signed-off-by: DoHyun Pyun --- diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c index bf10167..17ccddb 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c @@ -146,7 +146,12 @@ static guint pending_le_conn_timer_id = 0; static int bt_conn_id = 0; static int bt_inst_id = 0; -#define BT_GATTC_CL_MAX 32 +/* Should match the range with bt-service-gatt.c's MAX_APPS_SUPPORTED */ +/* TODO: Adjust MAX Client after modifying MAX app handle logic */ +#define BT_GATTC_CL_MAX 11 + +static int assigned_if = 0; +static gboolean client_if_used[BT_GATTC_CL_MAX]; typedef struct { int conn_id; @@ -163,8 +168,6 @@ typedef struct { static GSList * hal_gattc_client_app_list = NULL; -static int bt_client_if = 0; - struct conn_mtu_s { int conn_id; int mtu; @@ -185,6 +188,48 @@ static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr); static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id); +void _bt_hal_gatt_client_init(void) +{ + assigned_if = 0; + memset(client_if_used, 0x00, sizeof(client_if_used)); +} + +static int __bt_hal_gatt_assign_if(void) +{ + int index; + + index = assigned_if + 1; + + if (index >= BT_GATTC_CL_MAX) + index = 1; + + while (client_if_used[index] == TRUE) { + if (index == assigned_if) { + /* No available ID */ + ERR("All interface ID is used"); + return -1; + } + + index++; + + if (index >= BT_GATTC_CL_MAX) + index = 1; + } + + assigned_if = index; + client_if_used[index] = TRUE; + + return assigned_if; +} + +static void __bt_hal_gatt_delete_if(int client_if) +{ + if (client_if >= BT_GATTC_CL_MAX || client_if < 0) + return; + + client_if_used[client_if] = FALSE; +} + /* To send stack event to hal-av handler */ void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb) @@ -226,14 +271,10 @@ static gboolean __bt_hal_register_client_cb(gpointer user_data) return FALSE; } -static int __hal_generate_client_id() -{ - return ++bt_client_if; -} - static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid) { GSList *l; + int client_if = 0; hal_gatt_client_app *info = NULL; hal_gatt_client_app *gattc_app = NULL; @@ -249,11 +290,17 @@ static hal_gatt_client_app *__hal_gattc_add_client_app(bt_uuid_t *app_uuid) } } + client_if = __bt_hal_gatt_assign_if(); + if (client_if == -1) { + ERR("Fail to allocate the client if"); + return NULL; + } + DBG("adding the gatt client app"); //add client app gattc_app = g_malloc0(sizeof(hal_gatt_client_app)); - gattc_app->client_if = __hal_generate_client_id(); + gattc_app->client_if = client_if; memcpy(&gattc_app->app_uuid, app_uuid, sizeof(bt_uuid_t)); hal_gattc_client_app_list = g_slist_append(hal_gattc_client_app_list, gattc_app); @@ -337,6 +384,9 @@ bt_status_t __hal_gattc_unregister_client(int client_if) if (info->client_if == client_if) { DBG("gatt client app found"); + + __bt_hal_gatt_delete_if(client_if); + hal_gattc_client_app_list = g_slist_remove(hal_gattc_client_app_list, info); g_free(info); } diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-client.h b/bt-oal/bluez_hal/src/bt-hal-gatt-client.h index 09b78ec..1d90fe8 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.h +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.h @@ -35,6 +35,8 @@ extern "C" { #endif +void _bt_hal_gatt_client_init(void); + void _bt_hal_register_gatt_client_handler_cb(handle_stack_msg cb); void _bt_hal_unregister_gatt_client_handler_cb(void); diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c index 54de27a..0d7dba2 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c @@ -195,7 +195,14 @@ struct hal_gatts_server_register_info_t { static GSList * hal_gatts_server_register_list; -static int g_server_inst_id = 0; + +/* Should match the range with bt-service-gatt.c's MAX_APPS_SUPPORTED */ +/* TODO: Adjust MAX Server after modifying MAX app handle logic */ +#define BT_GATTS_MAX 11 + +static int assigned_id = 0; + +static gboolean instance_id_used[BT_GATTS_MAX]; #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\ {\ @@ -335,6 +342,48 @@ static const gchar manager_introspection_xml[] = " " ""; +void _bt_hal_gatt_server_init(void) +{ + assigned_id = 0; + memset(instance_id_used, 0x00, sizeof(instance_id_used)); +} + +static int __bt_hal_gatt_assign_id(void) +{ + int index; + + index = assigned_id + 1; + + if (index >= BT_GATTS_MAX) + index = 1; + + while (instance_id_used[index] == TRUE) { + if (index == assigned_id) { + /* No available ID */ + ERR("All interface ID is used"); + return -1; + } + + index++; + + if (index >= BT_GATTS_MAX) + index = 1; + } + + assigned_id = index; + instance_id_used[index] = TRUE; + + return assigned_id; +} + +static void __bt_hal_gatt_delete_id(int instance_id) +{ + if (instance_id >= BT_GATTS_MAX || instance_id < 0) + return; + + instance_id_used[instance_id] = FALSE; +} + static GSList *_bt_get_service_list_from_server(int instance) { GSList *l; @@ -1770,11 +1819,6 @@ static int bt_hal_gatts_get_gatt_server_instance() return -1; } -int bt_hal_gatts_generate_server_id() -{ - return ++g_server_inst_id; -} - static struct hal_gatts_server_register_info_t * bt_hal_gatts_find_server_register_info_from_uuid(bt_uuid_t *app_uuid) { DBG("+"); @@ -1841,6 +1885,7 @@ static struct hal_gatts_server_register_info_t * bt_hal_gatts_find_server_regist static struct hal_gatts_server_register_info_t * bt_hal_gatts_add_server_app(bt_uuid_t *app_uuid) { struct hal_gatts_server_register_info_t * server_register_info = NULL; + int instance_id = 0; server_register_info = bt_hal_gatts_find_server_register_info_from_uuid(app_uuid); if (server_register_info != NULL) { @@ -1848,8 +1893,14 @@ static struct hal_gatts_server_register_info_t * bt_hal_gatts_add_server_app(bt_ return server_register_info; } + instance_id = __bt_hal_gatt_assign_id(); + if (instance_id == -1) { + ERR("Fail to allocate the server if"); + return NULL; + } + server_register_info = g_malloc0(sizeof(struct hal_gatts_server_register_info_t)); - server_register_info->server_if = bt_hal_gatts_generate_server_id(); + server_register_info->server_if = instance_id; DBG("Adding the gatt server app. server_if:[%d]", server_register_info->server_if); @@ -1866,9 +1917,13 @@ static bt_status_t gatt_server_register_app(bt_uuid_t *uuid) struct hal_gatts_server_register_info_t *server_register_info = NULL; DBG("Register server instance request"); - hal_register_server_data *user_data = g_malloc0(sizeof(hal_register_server_data)); - server_register_info = bt_hal_gatts_add_server_app(uuid); + if (server_register_info == NULL) { + ERR("Fail to register the server app"); + return BT_STATUS_FAIL; + } + + hal_register_server_data *user_data = g_malloc0(sizeof(hal_register_server_data)); user_data->instance_data = server_register_info->server_if; /* @@ -1936,6 +1991,8 @@ static bt_status_t gatt_server_unregister_app(int server_if) hal_gatts_server_register_list = g_slist_remove(hal_gatts_server_register_list, server_register_info); g_free(server_register_info); + __bt_hal_gatt_delete_id(server_if); + /* If server_if belongs to a GATT Server, then delete the GATT server from List */ _bt_hal_remove_gatt_server_from_list(server_if); return BT_STATUS_SUCCESS; diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-server.h b/bt-oal/bluez_hal/src/bt-hal-gatt-server.h index ffae6d5..8e0093c 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-server.h +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-server.h @@ -35,6 +35,8 @@ extern "C" { #endif +void _bt_hal_gatt_server_init(void); + void _bt_hal_register_gatt_server_handler_cb(handle_stack_msg cb); void _bt_hal_unregister_gatt_server_handler_cb(void); diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt.c b/bt-oal/bluez_hal/src/bt-hal-gatt.c index a476088..17457a4 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt.c @@ -840,12 +840,16 @@ static void __bt_hal_handle_gatt_client_mtu_exchange_completed(void *buf, uint16 static bt_status_t gatt_init(const btgatt_callbacks_t* callbacks) { bt_gatt_callbacks = callbacks; + DBG("Register A2DP Src events callback function"); _bt_hal_register_gatt_le_dbus_handler_cb(__bt_hal_gatt_events); _bt_hal_register_gatt_server_handler_cb(__bt_hal_gatt_events); _bt_hal_register_gatt_client_handler_cb(__bt_hal_gatt_events); _bt_hal_register_event_handler_cb(HAL_GATT, __bt_hal_gatt_events); + _bt_hal_gatt_server_init(); + _bt_hal_gatt_client_init(); + return BT_STATUS_SUCCESS; } diff --git a/bt-service-adaptation/services/gatt/bt-service-gatt.c b/bt-service-adaptation/services/gatt/bt-service-gatt.c index d59d769..d9e080b 100644 --- a/bt-service-adaptation/services/gatt/bt-service-gatt.c +++ b/bt-service-adaptation/services/gatt/bt-service-gatt.c @@ -240,6 +240,9 @@ static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att static void __bt_remove_all_service_handles(int instance_id); static void __bt_free_service_info(bt_gatt_service_info_t *service_info); +static int __bt_do_unregister_gatt_instance(int instance_id); +static void __bt_service_reset_gatt_data(void); + #ifdef TIZEN_GATT_CLIENT static void __bt_handle_client_instance_registered(event_gattc_register_t *data); static void __bt_handle_client_connected(event_gattc_conn_t *event_data); @@ -312,20 +315,31 @@ void _bt_check_adv_app_termination(const char *name) if (!strncasecmp(app->sender, name, strlen(name)) && app->is_initialized == TRUE) { BT_DBG("Match found, name: %s", name); - /* Unregister all service handles with stack */ - __bt_remove_all_service_handles(app->instance_id); - - /* If Advertising is enabled, stop it */ - if (app->adv_handle > 0) { - BT_INFO("Stop advertising on instance ID [%d]", app->instance_id); - /* Disable adv if running */ - BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]", - app->adv_handle, name); - _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE); - } + /* TODO 1: If App has both GATT client / server role? */ + /* TODO 2: Need to manage app info as list, not array. + This loop always run for MAX count if any apps are terminated. + */ /* Save instances of all apps that need to be unregistered */ - apps[app->instance_id] = 1; + if (app->instance_id != -1) { + /* GATT server */ + /* Unregister all service handles with stack */ + __bt_remove_all_service_handles(app->instance_id); + + /* If Advertising is enabled, stop it */ + if (app->adv_handle > 0) { + BT_INFO("Stop advertising on instance ID [%d]", app->instance_id); + /* Disable adv if running */ + BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]", + app->adv_handle, name); + _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE); + } + + apps[app->instance_id] = 1; /* App holds a GATT client Instance */ + } else if (app->client_id != -1) { + /* GATT client */ + apps[app->client_id] = 1; /* App holds a GATT server Instance */ + } } } @@ -333,8 +347,8 @@ void _bt_check_adv_app_termination(const char *name) for (k = 1; k < MAX_APPS_SUPPORTED; k++) { if (apps[k] == 1) { BT_INFO("Unregister app[%d]", k); - /* Unregister server instance */ - __bt_unregister_gatt_server_instance(k); + /* Unregister client or server instance */ + __bt_do_unregister_gatt_instance(k); } } } @@ -425,6 +439,8 @@ static void __bt_register_default_gatt_client() int _bt_gatt_init(void) { + const char *stack_name = NULL; + BT_DBG("+"); if (OAL_STATUS_SUCCESS != gatt_enable()) { @@ -434,15 +450,21 @@ int _bt_gatt_init(void) /* Register gatt event handler */ _bt_service_register_event_handler_callback(BT_GATT_MODULE, __bt_gatt_event_handler); -#ifdef TIZEN_GATT_CLIENT - /*In bluedroid product, defacult gatt client is handled differently*/ - __bt_register_default_gatt_client(); -#endif + + __bt_service_reset_gatt_data(); + + stack_name = oal_get_stack_name(); + + if (stack_name && g_strcmp0(stack_name, "bluez") == 0) { + /*In the platform, defacult gatt client should be registered */ + __bt_register_default_gatt_client(); + } + BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } -static void __bt_service_reset_gatt_data() +static void __bt_service_reset_gatt_data(void) { int k; @@ -460,6 +482,11 @@ static void __bt_service_reset_gatt_data() memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX); numapps[k].adv_data_len = 0; numapps[k].scan_rsp_len = 0; + + /* GATT client */ + numapps[k].client_id = -1; + memset(numapps[k].address.addr, 0x00, BLUETOOTH_ADDRESS_LENGTH); + numapps[k].is_watcher_enabled = FALSE; } } @@ -608,6 +635,55 @@ void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, } } +static int __bt_do_unregister_gatt_instance(int instance_id) +{ + int ret = OAL_STATUS_SUCCESS; + int k; + + BT_INFO("DeAllocate server or client instance ID [%d]", instance_id); + + /* Reset data: instance_id parameter could be either for GATT Server or for GATT client */ + for (k = 1; k < MAX_APPS_SUPPORTED; k++) { + if (numapps[k].instance_id == instance_id) { + BT_INFO("This is a GATT server app, unregister: Slot [%d] vacant", k); + numapps[k].is_initialized = FALSE; + numapps[k].instance_id = -1; + numapps[k].adv_handle = 0; + numapps[k].adv_instance = -1; + memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender)); + memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid)); + memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX); + memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX); + numapps[k].adv_data_len = 0; + numapps[k].scan_rsp_len = 0; + + /* Its a GATT Server Instance */ + ret = gatts_unregister(instance_id); + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret); + return BLUETOOTH_ERROR_INTERNAL; + } + break; + } else if (numapps[k].client_id == instance_id) { + BT_INFO("This is a GATT client app, unregister: Slot [%d] vacant", k); + numapps[k].client_id = -1; + numapps[k].is_initialized = FALSE; + memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender)); + memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid)); + memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t)); + + /* Its a GATT Client Instance */ + ret = gattc_deregister(instance_id); + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret); + return BLUETOOTH_ERROR_INTERNAL; + } + break; + } + } + return BLUETOOTH_ERROR_NONE; +} + static int __bt_unregister_gatt_server_instance(int server_instance) { int ret = OAL_STATUS_SUCCESS;