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;
static GSList * hal_gattc_client_app_list = NULL;
-static int bt_client_if = 0;
-
struct conn_mtu_s {
int conn_id;
int mtu;
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)
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;
}
}
+ 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);
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);
}
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)\
{\
" </interface>"
"</node>";
+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;
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("+");
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) {
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);
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;
/*
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;
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);
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 */
+ }
}
}
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);
}
}
}
int _bt_gatt_init(void)
{
+ const char *stack_name = NULL;
+
BT_DBG("+");
if (OAL_STATUS_SUCCESS != gatt_enable()) {
/* 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;
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;
}
}
}
}
+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;