Handle GATT client app's termination
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-client.c
index bf10167..17ccddb 100644 (file)
@@ -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);
                }