[Adapt] Implement simultaneous Audio profile connection logic 89/88089/1
authorAnupam Roy <anupam.r@samsung.com>
Tue, 13 Sep 2016 08:42:18 +0000 (14:12 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Tue, 13 Sep 2016 08:42:18 +0000 (14:12 +0530)
This patch handles following:-
 a/ Add "Audio Connect All" request to wait state if one connection
    is under progress.
 b/ Issue get bonded device info to find out whether remote device supports
    A2DP Sink and HFP HF roles or not.
 c/ If user wants to connect second audio device, while another is in progress
    then internally disconnect the connected profile (HFP or A2DP) of the
    first device (if already connected) and and put connection type of
    second device to wait list. Once connection is terminated for first device,
    connection of waiting device is triggered.
 d/ Implements pending audio connection request logic for A2DP profile.
    If remote device supports both HFP and A2DP, then HFP connection is
    initiated first and A2DP connection is put to pending connection state.
    Once AG is connected, A2DP connection is triggered.

Change-Id: I19b71c5639c724ecf7b693ddfba56fe1e815223b
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-service-adaptation/services/adapter/bt-service-core-adapter.c
bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c
bt-service-adaptation/services/audio/bt-service-audio.c
bt-service-adaptation/services/audio/hf/bt-service-hf.c
bt-service-adaptation/services/bt-service-common.c
bt-service-adaptation/services/bt-service-event-receiver.c
bt-service-adaptation/services/include/bt-service-audio-common.h
bt-service-adaptation/services/include/bt-service-common.h

index 8cc1a43..6975837 100644 (file)
@@ -713,7 +713,14 @@ static int __bt_init_profiles()
        /* Initialize HFP Audio Gateway */
        ret = _bt_audio_initialize(BT_AG_MODULE);
        if (ret != BLUETOOTH_ERROR_NONE) {
-               BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
+               BT_ERR("_bt_audio_initialize(BT_AG_MODULE) Failed");
+               return ret;
+       }
+
+       /* Registering callback for receiving audio services searched */
+       ret = _bt_audio_initialize(BT_AUDIO_ALL_MODULE);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("_bt_audio_initialize(BT_AUDIO_ALL_MODULE) Failed");
                return ret;
        }
 
index c4c2fc7..cf2aed3 100644 (file)
@@ -66,11 +66,12 @@ int _bt_a2dp_disconnect_remote_sink(bluetooth_device_address_t *device_address)
 
 static void __bt_handle_av_connected_state(bluetooth_device_address_t *address)
 {
-       char addr[BT_ADDRESS_STRING_SIZE + 1];
+       char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
        char connected_address[BT_ADDRESS_STRING_SIZE + 1];
        gboolean connected;
-       bt_headset_wait_t *wait_device;
+       bt_headset_wait_t *wait_device = NULL;
        bluetooth_device_address_t device_address;
+       bluetooth_device_address_t wait_device_address;
        GVariant *param;
        int result = BLUETOOTH_ERROR_NONE;
        ret_if(NULL == address);
@@ -79,6 +80,9 @@ static void __bt_handle_av_connected_state(bluetooth_device_address_t *address)
        _bt_convert_addr_type_to_string(addr, address->addr);
        BT_INFO("Address of connected device [%s]", addr);
 
+       /* Set VCONF Key for A2DP Connected status */
+       _bt_set_device_values(TRUE, VCONFKEY_BT_DEVICE_A2DP_HEADSET_CONNECTED);
+
        /* Send A2DP(SRC Role) connected event to Application */
        param = g_variant_new("(is)", result, addr);
        _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AV_CONNECTED, param);
@@ -101,23 +105,44 @@ static void __bt_handle_av_connected_state(bluetooth_device_address_t *address)
        if (wait_device != NULL &&
                        (g_strcmp0(wait_device->address, addr) == 0))
                _bt_rel_wait_data();
+       else {
+               if (wait_device != NULL) {
+                       BT_INFO("A2DP Profile connected for device [%s] but another device [%s]is waiting to be connnected type [%d]",
+                                       addr, wait_device->address, wait_device->type);
+                       BT_INFO("Trigger connect for the waiting device [%s], audio type [%d]",
+                                       wait_device->address, wait_device->type);
+                       _bt_convert_addr_string_to_type(wait_device_address.addr,
+                                       wait_device->address);
+                       _bt_audio_connect(wait_device->type, &wait_device_address);
+                       /* Now free the wait list */
+                       //_bt_rel_wait_data();
+               }
+       }
        BT_INFO("-");
 }
 
 static void __bt_handle_av_disconnected_state(bluetooth_device_address_t *address)
 {
-       char addr[BT_ADDRESS_STRING_SIZE + 1];
+       char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
        int result = BLUETOOTH_ERROR_NONE;
        GArray *out_param;
        bt_headset_wait_t *wait_device;
        bluetooth_device_address_t device_address;
+       bt_pending_audio_conn_t *data = NULL;
        GVariant *param;
-       invocation_info_t *req_info;
+       invocation_info_t *req_info = NULL;
        ret_if(NULL == address);
        BT_INFO("+");
 
        _bt_convert_addr_type_to_string(addr, address->addr);
 
+       if (!_bt_is_service_connected(addr, BT_AUDIO_A2DP)) {
+               BT_ERR("A2DP Disconnected for addr[%s], but it is already disconnected..", addr);
+               return;
+       }
+       /* Set VCONF status for A2DP Disconnection */
+       _bt_set_device_values(FALSE, VCONFKEY_BT_DEVICE_A2DP_HEADSET_CONNECTED);
+
        /* Send A2DP(SRC Role) disconnected event to Application */
        param = g_variant_new("(is)", result, addr);
        _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AV_DISCONNECTED, param);
@@ -134,15 +159,39 @@ static void __bt_handle_av_disconnected_state(bluetooth_device_address_t *addres
                if (NULL == req_info) {
                        /* This means, AV Disconnect request has successfully passed, and real disconnect is completed */
                        BT_INFO("Neither AV Connect or AV Disconnect request is found..means, AV Profile is disconnected");
+
+                       req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, addr);
+                       if (req_info == NULL) {
+                               BT_INFO("Audio Connect All request is also Not found..");
+
+                               req_info = _bt_get_request_info_data(BT_AUDIO_DISCONNECT, addr);
+                               if (req_info == NULL) {
+                                       BT_INFO("Audio DisConnect All request is also Not found..");
+                               } else {
+                                       BT_INFO("Audio DisConnect All request is found..");
+                                       /* Check if HFP profile is also connected, if yes, disconnect it too */
+                                       _bt_audio_check_pending_disconnection(addr, BT_AUDIO_HSP);
+                               }
+                       } else {
+                               BT_INFO("Audio Connect All request is found..");
+                               result = BLUETOOTH_ERROR_INTERNAL;
+                               data = _bt_get_service_search_info(addr);
+                               if (data) {
+                                       BT_INFO("Pending connect is found, delete it..");
+                                       _bt_cleanup_search_info_and_reply_pending_req(data, BLUETOOTH_ERROR_NONE);
+                                       req_info = NULL;
+                               } else {
+                                       BT_INFO("Pending connect is Not found..");
+                               }
+                       }
                        goto check_wait_device;
                } else {
                        BT_ERR("AV Connect request has failed.."); /* DBUS return needed */
+                       result = BLUETOOTH_ERROR_INTERNAL;
                        goto check_wait_device;
                }
        } else {
-               /* If AV_DISCONNECT failed, as if it would have passed, then Disconnecting event would have come and
-               we must have replied DBUS context */
-               BT_ERR("AV Disconnect request found for [%s], means disconnect request has failed", addr); /* DBUS return needed */
+               BT_ERR("AV Disconnect request found for [%s], means disconnect request is successful", addr); /* DBUS return needed */
                goto check_wait_device;
        }
 check_wait_device:
@@ -152,21 +201,25 @@ check_wait_device:
                goto dbus_return;
        }
 
-       if (g_strcmp0(wait_device->address, addr) != 0) {
-               BT_INFO("Trigger connect for the waiting device [%s], audio type [%d]",
-                               wait_device->address, wait_device->type);
-               _bt_convert_addr_string_to_type(device_address.addr,
-                               wait_device->address);
-               _bt_audio_connect(wait_device->type, &device_address);
-               /* Now free the wait list */
-               _bt_rel_wait_data();
+       if (((wait_device->type == BT_AUDIO_ALL) &&
+                                (wait_device->ag_flag == TRUE)) ||
+                                (wait_device->type == BT_AUDIO_A2DP) ||
+                               (wait_device->disconnection_type == BT_AUDIO_A2DP)) {
+               if (g_strcmp0(wait_device->address, addr) != 0) {
+                       BT_INFO("Trigger connect for the waiting device [%s], audio type [%d]",
+                                       wait_device->address, wait_device->type);
+                       _bt_convert_addr_string_to_type(device_address.addr,
+                                       wait_device->address);
+                       _bt_audio_connect(wait_device->type, &device_address);
+                       /* Now free the wait list */
+                       //_bt_rel_wait_data();
+               }
        }
 
 dbus_return:
        if (req_info) {
                out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-               g_array_append_vals(out_param, &device_address,
-                               sizeof(bluetooth_device_address_t));
+               g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
                _bt_service_method_return(req_info->context,
                                out_param, result);
                g_array_free(out_param, TRUE);
@@ -199,15 +252,20 @@ static void __bt_reply_av_disconnection_pending_request(bluetooth_device_address
        req_info = _bt_get_request_info_data(BT_AV_DISCONNECT, addr);
        if (NULL == req_info) {
                BT_INFO("AV DisConnect request not found or possibly already replied");
-               return;
+               req_info = _bt_get_request_info_data(BT_AUDIO_DISCONNECT, addr);
+               if (req_info == NULL) {
+                       BT_INFO("Audio All DisConnect request  is also not found or possibly already replied");
+                       return;
+               } else {
+                       BT_INFO("Audio All DisConnect request found..");
+               }
        } else {
                BT_INFO("AV DisConnect request found for [%s]", addr);
        }
 
        /* In any of the above cases, do DBUS return */
        out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-       g_array_append_vals(out_param, &device_address,
-                       sizeof(bluetooth_device_address_t));
+       g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
        _bt_service_method_return(req_info->context,
                        out_param, result);
        g_array_free(out_param, TRUE);
@@ -222,6 +280,7 @@ static void __bt_reply_av_connection_pending_request(bluetooth_device_address_t
        bluetooth_device_address_t device_address;
        GArray *out_param;
        invocation_info_t *req_info;
+       bt_pending_audio_conn_t *data = NULL;
        int result = BLUETOOTH_ERROR_NONE;
        memcpy(device_address.addr, address->addr, BLUETOOTH_ADDRESS_LENGTH);
        _bt_convert_addr_type_to_string(addr, address->addr);
@@ -229,16 +288,28 @@ static void __bt_reply_av_connection_pending_request(bluetooth_device_address_t
        req_info = _bt_get_request_info_data(BT_AV_CONNECT, addr);
        if (NULL == req_info) {
                BT_INFO("AV Connect request not found or possibly already replied");
-               return;
+               req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, addr);
+
+               if (req_info == NULL) {
+                       BT_INFO("AV Connect request & Audio All connect not found or possibly already replied");
+                       return;
+               } else {
+                       BT_INFO("Audio All connect request found for address [%s]", addr);
+                       /* TODO Delete the search info if present */
+                       data = _bt_get_service_search_info(addr);
+                       if (data) {
+                               BT_INFO("Audio Connect All request present and pending connect is also present, delete info");
+                               _bt_cleanup_search_info_and_reply_pending_req(data, BLUETOOTH_ERROR_NONE);
+                       } else {
+                               BT_ERR("Abnormal: Audio Connect All request present but pending connect absent");
+                       }
+               }
        } else {
                BT_INFO("AV Connect request found for [%s]", addr);
        }
 
-       /* TODO: Pending data creation if multiple profile is supported */
-
        out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-       g_array_append_vals(out_param, &device_address,
-                       sizeof(bluetooth_device_address_t));
+       g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
        _bt_service_method_return(req_info->context,
                        out_param, result);
        g_array_free(out_param, TRUE);
index f6bfbaf..9f15baf 100644 (file)
@@ -31,6 +31,7 @@
 #include "bt-service-common.h"
 #include "bt-request-handler.h"
 #include "bt-service-audio-common.h"
+#include "bt-service-core-device.h"
 #include "bt-service-a2dp-src.h"
 #include "bt-service-hf.h"
 
@@ -43,11 +44,22 @@ typedef struct {
         char device_address[BT_ADDRESS_STRING_SIZE + 1];
 } bt_connected_headset_data_t;
 
+/* List for saving device service search info */
+static GSList *g_service_search_info_list = NULL;
+
 /* Headset connection data structures */
 gboolean connection_local = FALSE;
 
 static void __bt_remove_device_from_wait_list(char *prev_waiting_device);
 
+static void __bt_audio_device_property_event_handler(int oal_event, gpointer event_data);
+
+static int __bt_process_audio_connect_all(bt_pending_audio_conn_t *info);
+
+static int __bt_is_headset_connecting(int type);
+
+static int __bt_is_headset_disconnecting(int type);
+
 void _bt_headset_set_local_connection(gboolean value)
 {
        BT_INFO("setting connection_local to %d", value);
@@ -116,11 +128,13 @@ void _bt_add_headset_to_list(int type, int status, const char *address)
        }
 
        connected_device->device_state = status;
-       if (status == BT_STATE_CONNECTED)
+       if ((status == BT_STATE_CONNECTED) || (status == BT_STATE_CONNECTING))
                connected_device->type |= type;
        g_strlcpy(connected_device->device_address, address,
                        sizeof(connected_device->device_address));
        g_connected_list = g_list_append(g_connected_list, connected_device);
+       BT_INFO("Added device[%s] in connected list, device state [%d] Device Type [%d]",
+                               address, connected_device->device_state, connected_device->type);
 }
 
 gboolean _bt_is_headset_type_connected(int type, char *address)
@@ -184,9 +198,49 @@ gboolean __bt_is_companion_device(const char *addr)
 }
 #endif
 
+static int __bt_is_headset_disconnecting(int type)
+{
+       bt_connected_headset_data_t *connected_device = NULL;
+
+       /* Check if any other headset is connected */
+       GList *node = NULL;
+
+       node = g_list_first(g_connected_list);
+       while (node != NULL) {
+               connected_device = node->data;
+               if (connected_device->device_state == BT_STATE_DISCONNECTING) {
+                       return BLUETOOTH_ERROR_CONNECTION_BUSY;
+               }
+               node = g_list_next(node);
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_is_headset_connecting(int type)
+{
+       bt_connected_headset_data_t *connected_device = NULL;
+
+       /* Check if any other headset is connected */
+       GList *node = NULL;
+
+       node = g_list_first(g_connected_list);
+       while (node != NULL) {
+               connected_device = node->data;
+               if (connected_device->device_state == BT_STATE_CONNECTING) {
+                       BT_ERR("@@Device [%s] is already under connecting state", connected_device->device_address);
+                       return BLUETOOTH_ERROR_CONNECTION_BUSY;
+               }
+               node = g_list_next(node);
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 static int __bt_is_headset_connected(int type, const char *address)
 {
        gboolean connected = FALSE;
+       int conn_type;
        char connected_address[BT_ADDRESS_STRING_SIZE + 1];
        bluetooth_device_address_t device_address;
        bt_connected_headset_data_t *connected_device = NULL;
@@ -197,10 +251,13 @@ static int __bt_is_headset_connected(int type, const char *address)
        /* Check if any other headset is connected */
        GList *node = NULL;;
 
+       BT_INFO("Checking  if any Headset connected or not: current device [%s] current dev type [%d]", address, type);
        node = g_list_first(g_connected_list);
        while (node != NULL) {
                connected_device = node->data;
-               if ((connected_device->type & type) == type) {
+               BT_INFO(" A Device is already connected found in list [%s] conn type [%d",
+                               connected_device->device_address, connected_device->type);
+               if ((connected_device->type & type)) {
                        g_strlcpy(connected_address, connected_device->device_address,
                                        BT_ADDRESS_STRING_SIZE + 1);
 #ifdef TIZEN_SUPPORT_DUAL_HF
@@ -219,8 +276,10 @@ static int __bt_is_headset_connected(int type, const char *address)
                node = g_list_next(node);
        }
 
-       if (!connected)
+       if (!connected) {
+               BT_INFO("There is no connected device with connection type [%d]", type);
                return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
 
        BT_DBG("connected headset %s", connected_address);
 
@@ -230,28 +289,39 @@ static int __bt_is_headset_connected(int type, const char *address)
        else if (TRUE == __bt_is_companion_device(address))
                return BLUETOOTH_ERROR_NOT_CONNECTED;
 #endif
+
+       /* Convert BD adress from string type */
+       _bt_convert_addr_string_to_type(device_address.addr, connected_address);
+       int value = BLUETOOTH_ERROR_NONE;
+       BT_DBG("Already connected headset addr  [%s] connected headset type [0x%x] current dev conn type [0x%x]",
+                               connected_address, connected_device->type, type);
+       conn_type = connected_device->type & type;
+       BT_DBG("Attempt disconnection of Type [0x%x] of already connected device" , conn_type);
+       value = _bt_audio_disconnect(connected_device->type & type, &device_address);
+
        /* If already one device is waiting, remove current waiting device and add new */
-       if (g_wait_data != NULL) {
-               if (g_strcmp0(g_wait_data->address, address) != 0) {
-                       __bt_remove_device_from_wait_list(g_wait_data->address);
-                       __bt_free_wait_data();
+       if (value == BLUETOOTH_ERROR_NONE) {
+               if (g_wait_data != NULL) {
+                       if (g_strcmp0(g_wait_data->address, address) != 0) {
+                               BT_INFO("Already one device was waiting for connection [%s], remove it", g_wait_data->address);
+                               __bt_remove_device_from_wait_list(g_wait_data->address);
+                               __bt_free_wait_data();
+                       }
                }
-       }
 
-       if (g_wait_data == NULL) {
-               g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
-               g_wait_data->address = g_strdup(address);
-               g_wait_data->type = type;
-               g_wait_data->ag_flag = FALSE;
+               if (g_wait_data == NULL) {
+                       BT_INFO("Add current device [%s] into waiting list", address);
+                       g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
+                       g_wait_data->address = g_strdup(address);
+                       g_wait_data->type = type;
+                       g_wait_data->ag_flag = FALSE;
 
-               /* Set disconnection type */
-               __bt_set_headset_disconnection_type(connected_address);
+                       /* Set disconnection type */
+                       __bt_set_headset_disconnection_type(connected_address);
+               }
        }
 
-       /* Convert BD adress from string type */
-       _bt_convert_addr_string_to_type(device_address.addr, connected_address);
-       _bt_audio_disconnect(connected_device->type & type, &device_address);
-       return BLUETOOTH_ERROR_NONE;
+       return value;
 }
 
 static void __bt_remove_device_from_wait_list(char *prev_waiting_device)
@@ -320,6 +390,7 @@ static int __bt_process_audio_profile_disconnect(bt_audio_type_t type, bluetooth
 {
        char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
        int result = BLUETOOTH_ERROR_NONE;
+       GList *node;
        BT_INFO("+");
 
        _bt_convert_addr_type_to_string(addr,
@@ -341,6 +412,21 @@ static int __bt_process_audio_profile_disconnect(bt_audio_type_t type, bluetooth
         }
 
        if (result == BLUETOOTH_ERROR_NONE) {
+               /*
+                *      This logic is added for dual HF mode issue.
+                */
+               node = g_list_first(g_connected_list);
+               while (node != NULL) {
+                       bt_connected_headset_data_t *connected_device = node->data;
+
+                       if (g_strcmp0(connected_device->device_address, addr) == 0) {
+                               BT_DBG("Connection type update");
+                               type = connected_device->type;
+                               break;
+                       }
+                       node = g_list_next(node);
+               }
+
                /* Update device status in connected list */
                _bt_add_headset_to_list(type, BT_STATE_DISCONNECTING, addr);
        } else {
@@ -391,9 +477,8 @@ int _bt_audio_initialize(bt_service_module_t module)
                case BT_AUDIO_ALL_MODULE:
                {
                        /* Register Audio module event handler */
-                       /*TODO: Register Audio event handler for device services
-                               will be supported after HSP profile implementation */
-                       return BLUETOOTH_ERROR_NOT_SUPPORT;
+                       _bt_service_register_event_handler_callback(module, __bt_audio_device_property_event_handler);
+                       break;
                }
                default:
                        BT_ERR("Not Supported: Module [%d]", module);
@@ -404,21 +489,306 @@ int _bt_audio_initialize(bt_service_module_t module)
        return ret;
 }
 
+/* This event handler process audio device service search request */
+static void __bt_audio_device_property_event_handler(int oal_event, gpointer event_data)
+{
+       GSList *l;
+       int count;
+       char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       bt_pending_audio_conn_t *info = NULL;
+       event_dev_properties_t *event;
+       int value = BLUETOOTH_ERROR_NONE;
+       int ret = BLUETOOTH_ERROR_NONE;
+       bt_remote_dev_info_t *rem_info = NULL;
+       BT_INFO("+");
+
+       if (!g_service_search_info_list) {
+               BT_INFO("No Audio Service Search request is pending..");
+               return;
+       }
+
+       /* Device Services are searched */
+       event = (event_dev_properties_t*)event_data;
+
+       rem_info = g_malloc0(sizeof(bt_remote_dev_info_t));
+       memset(rem_info, 0x00, sizeof(bt_remote_dev_info_t));
+       _bt_copy_remote_dev(rem_info, &event->device_info);
+
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)event->device_info.address.addr);
+
+       for (l = g_service_search_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (bt_pending_audio_conn_t*)l->data;
+
+               if (info && g_strcmp0(info->address, address) == 0 && info->search_status == SERVICE_SEARCH_STARTED) {
+                       BT_INFO("Service searching is ongoing for addr [%s], Services received for the same!", info->address);
+                       info->search_status = SERVICE_SEARCH_DONE;
+                       for(count=0; count < rem_info->uuid_count; count++) {
+                               BT_INFO("Device [%s] has UUID [%s]", address, rem_info->uuids[count]);
+                               if (g_strcmp0(A2DP_SINK_UUID, rem_info->uuids[count]) == 0) {
+                                       BT_INFO("Device supports A2DP Sink Profile");
+                                       info->is_a2dp_supported = TRUE;
+                               }
+                               if (g_strcmp0(HFP_HS_UUID, rem_info->uuids[count]) == 0) {
+                                       BT_INFO("Device supports HFP Profile");
+                                       info->is_hfp_supported = TRUE;
+                               }
+                       }
+                       if (info->is_a2dp_supported == FALSE && info->is_hfp_supported == FALSE) {
+                               ret = BLUETOOTH_ERROR_NOT_SUPPORT;
+                               goto fail;
+                       }
+                       break;
+               }
+               info = NULL;
+       }
+       if (!info) {
+               BT_INFO("Could not find any Audio service searching info..");
+               if (rem_info)
+                       _bt_free_remote_dev(rem_info);
+               return;
+       }
+
+       BT_INFO("AUDIO_CONNECT_ALL request is now pending for [%s]", info->address);
+       /* Give preference to HFP over A2DP for outgoing connection sequence for AUDIO_ALL_CONNECT */
+       if (info->is_hfp_supported)
+               info->type = BT_AUDIO_HSP;
+       else
+               info->type = BT_AUDIO_A2DP;
+
+       value =  __bt_is_headset_connected(info->type, info->address);
+
+       if (value == BLUETOOTH_ERROR_ALREADY_CONNECT ||
+                       value == BLUETOOTH_ERROR_IN_PROGRESS) {
+               BT_ERR("Sorry, can not start Audio All connect for [%s] reason [%d]", info->address, value);
+               if (value == BLUETOOTH_ERROR_ALREADY_CONNECT)
+                       BT_ERR("Reason: Already connected...");
+               else if (value == BLUETOOTH_ERROR_IN_PROGRESS)
+                       BT_ERR("Reason: Already in progress..");
+               ret = value;
+               goto fail;
+       } else if (value == BLUETOOTH_ERROR_NOT_CONNECTED) {
+               BT_ERR("Great, can start Audio All connect for [%s]", info->address);
+
+               value = __bt_is_headset_connecting(info->type);
+               if (value != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Sorry, can not start Audio All connect for [%s] as some other device under progress", info->address);
+                       ret = BLUETOOTH_ERROR_IN_PROGRESS;
+                       goto fail;
+               }
+               ret = __bt_process_audio_connect_all(info);
+               if (ret != BLUETOOTH_ERROR_NONE) {
+                       goto fail;
+               } else {
+                       /* Check if pending connection is necessary or not */
+                       if (info->is_hfp_supported && info->is_a2dp_supported) {
+                               /* Remote device supports both A2DP and HFP, keep search info */
+                               BT_INFO("[%s] Supports both A2DP and HFP...", info->address);
+                       } else {
+                               /* Remote device supports either A2DP or HFP, delete search info as no
+                                  pending connection is required. pending connection is only required
+                                  when both profiles are supported */
+                               BT_INFO("[%s] Supports one profile", info->address);
+                               _bt_remove_service_search_request(info->address);
+                       }
+               }
+       } else if (value == BLUETOOTH_ERROR_NONE) {
+               BT_INFO("Waiting for disconnection...");
+               /* Above means, we dont need pending connect (as only A2DP or HFP will be connected
+                  for present device) So lets delete search info */
+               _bt_remove_service_search_request(info->address);
+       } else if (value == BLUETOOTH_ERROR_IN_PROGRESS) {
+               ret = BLUETOOTH_ERROR_IN_PROGRESS;
+               goto fail;
+       }
+       //__bt_check_pending_service_search();
+       if (rem_info)
+               _bt_free_remote_dev(rem_info);
+       return;
+fail:
+       BT_ERR("Audio COnnect all failed: Either (A2DP Sink & HFP) are not supported or device buzy or already connectede..");
+       if (rem_info)
+               _bt_free_remote_dev(rem_info);
+       _bt_cleanup_search_info_and_reply_pending_req(info, ret);
+       //__bt_check_pending_service_search();
+}
+
+static int __bt_process_audio_connect_all(bt_pending_audio_conn_t *info)
+{
+       bluetooth_device_address_t device_address;
+       int result = BLUETOOTH_ERROR_NONE;
+       int type = BT_AUDIO_ALL;
+       BT_INFO("+");
+
+       _bt_convert_addr_string_to_type(device_address.addr, info->address);
+
+       /* Attempt profile level connection */
+       if (info->is_hfp_supported) {
+               type = BT_AUDIO_HSP;
+               result = _bt_connect_remote_hfp(&device_address);
+
+               if (info->is_a2dp_supported) {
+                       BT_INFO("A2DP is supported by [%s]", info->address);
+               } else {
+                       BT_INFO("A2DP is not supported");
+               }
+       } else if (info->is_a2dp_supported) {
+               type = BT_AUDIO_A2DP;
+               result = _bt_a2dp_connect_remote_sink(&device_address);
+       }
+       if (result == BLUETOOTH_ERROR_NONE) {
+               _bt_headset_set_local_connection(TRUE);
+               /* Add data to the connected list */
+               _bt_add_headset_to_list(type, BT_STATE_CONNECTING, info->address);
+       } else {
+               BT_ERR("Profile connect failed!!");
+       }
+       BT_INFO("-");
+       return result;
+}
+
+void _bt_remove_service_search_request(char *address)
+{
+       BT_INFO("+");
+       bt_pending_audio_conn_t *info = NULL;
+       GSList *l;
+
+       BT_INFO("Search pending data for address [%s]", address);
+       for (l = g_service_search_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (bt_pending_audio_conn_t*)l->data;
+
+               if (g_strcmp0(info->address, address) == 0 && info->search_status == SERVICE_SEARCH_DONE) {
+                       BT_INFO("Pending data found for addr [%s], delete it...", info->address);
+                       g_service_search_info_list = g_slist_remove(g_service_search_info_list, info);
+                       g_free(info->address);
+                       g_free(info);
+               }
+       }
+       BT_INFO("Pending data not found!!");
+}
+
+bt_pending_audio_conn_t* _bt_get_service_search_info(char *address)
+{
+       BT_INFO("+");
+       bt_pending_audio_conn_t *info = NULL;
+       GSList *l;
+
+       for (l = g_service_search_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (bt_pending_audio_conn_t*)l->data;
+
+               if (g_strcmp0(info->address, address) == 0 && info->search_status == SERVICE_SEARCH_DONE) {
+                       BT_INFO("Pending data found for addr [%s]", info->address);
+                       return info;
+               }
+       }
+       BT_INFO("Pending data not found!!");
+       return NULL;
+}
+
+void _bt_cleanup_search_info_and_reply_pending_req(bt_pending_audio_conn_t *info, int result)
+{
+       GArray *out_param;
+       invocation_info_t *req_info;
+       bluetooth_device_address_t device_address;
+
+       if (info) {
+               g_service_search_info_list = g_slist_remove(g_service_search_info_list, info);
+
+               /* Reply to async request for Audio connect, if any */
+               req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, info->address);
+               if (NULL != req_info) {
+                       BT_INFO("Delete pending data informations..");
+                       _bt_convert_addr_string_to_type(device_address.addr, info->address);
+                       out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+                       g_array_append_vals(out_param, info->address, BT_ADDRESS_STRING_SIZE);
+                       _bt_service_method_return(req_info->context,
+                                       out_param, result);
+                       g_array_free(out_param, TRUE);
+                       g_free(req_info->user_data);
+                       _bt_free_info_from_invocation_list(req_info);
+               }
+               if (info->address)
+                       g_free(info->address);
+               g_free(info);
+       }
+}
+
+void _bt_audio_check_pending_connection(char *address)
+{
+       bt_pending_audio_conn_t *data = NULL;
+       bluetooth_device_address_t device_address;
+       BT_INFO("+");
+
+       data = _bt_get_service_search_info(address);
+
+       if (data) {
+               BT_INFO("A2DP Connection is pending..initiate it...");
+               if (data->is_a2dp_supported) {
+                       _bt_convert_addr_string_to_type(device_address.addr, address);
+                       if (_bt_audio_connect(BT_AUDIO_A2DP, &device_address) != BLUETOOTH_ERROR_NONE) {
+                               BT_INFO("A2DP connect triggered for [%s]  but it failed!!", data->address);
+                               _bt_cleanup_search_info_and_reply_pending_req(data, BLUETOOTH_ERROR_INTERNAL);
+                       } else {
+                               BT_INFO("A2DP connect triggered successfully for [%s]", data->address);
+                       }
+               }
+       } else {
+               BT_INFO("A2DP Connection is not pending..");
+       }
+       BT_INFO("-");
+}
+
+void _bt_audio_check_pending_disconnection(char *address, int type)
+{
+       int ret = BLUETOOTH_ERROR_NONE;
+       bluetooth_device_address_t device_address;
+        BT_INFO("+");
+
+       if (_bt_is_service_connected(address, type)) {
+               BT_INFO("Service [%d] is connected with device [%s], disconnect it...", type, address);
+               _bt_convert_addr_string_to_type(device_address.addr, address);
+               ret = __bt_process_audio_profile_disconnect(type, &device_address);
+
+               if (ret != BLUETOOTH_ERROR_NONE)
+                       BT_ERR("Disconnecting service [%d] with device [%s] failed!!", type, address);
+       } else {
+               BT_INFO("Service [%d] is Not connected with device [%s],..", type, address);
+       }
+        BT_INFO("-");
+}
+
 int _bt_audio_connect(int type,        bluetooth_device_address_t *device_address)
 {
        int value = BLUETOOTH_ERROR_NONE;
        int ret = BLUETOOTH_ERROR_NONE;
        char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       bt_pending_audio_conn_t *info = NULL;
 
        BT_INFO("+");
        BT_CHECK_PARAMETER(device_address, return);
        _bt_convert_addr_type_to_string(address, device_address->addr);
 
+       /* If type is BT_AUDIO_ALL, enqueue search info in order to find out
+          supported services by the remote device */
        if (type == BT_AUDIO_ALL) {
-               /*TODO: Audio connect All will be supported after HSP profile implementation */
-               return BLUETOOTH_ERROR_NOT_SUPPORT;
-       }
 
+               /* Safe operation, cleanup if already any pending request is present in list */
+               _bt_remove_service_search_request(address);
+
+               info = g_malloc(sizeof(bt_pending_audio_conn_t));
+               /* Request bonded device info */
+               BT_INFO("Fire Bonded Device info for address [%s]", address);
+
+               ret = _bt_device_get_bonded_device_info(device_address);
+
+               if (ret != BLUETOOTH_ERROR_NONE)
+                       goto fail;
+               info->search_status = SERVICE_SEARCH_STARTED;
+               info->address = g_strdup(address);
+               info->type = type;
+               g_service_search_info_list = g_slist_append(g_service_search_info_list, (gpointer)info);
+               return ret;
+       }
        /* If type is A2DP Sink or HSP/HFP, check further */
        value =  __bt_is_headset_connected(type, address);
 
@@ -432,32 +802,54 @@ int _bt_audio_connect(int type,   bluetooth_device_address_t *device_address)
                }
        } else if (value == BLUETOOTH_ERROR_NONE) {
                BT_INFO("Waiting for disconnection...");
+       } else if (value == BLUETOOTH_ERROR_IN_PROGRESS) {
+               ret =  BLUETOOTH_ERROR_IN_PROGRESS;
+               goto fail;
        }
+
        return BLUETOOTH_ERROR_NONE;
 fail:
+       if (info) {
+               if (info->address)
+                       g_free(info->address);
+               g_free(info);
+       }
        return ret;
 }
 
 int _bt_audio_disconnect(int type, bluetooth_device_address_t *device_address)
 {
        int ret = BLUETOOTH_ERROR_NONE;
+       int value = BLUETOOTH_ERROR_NONE;
        char address[BT_ADDRESS_STRING_SIZE] = { 0 };
 
        _bt_convert_addr_type_to_string(address, device_address->addr);
        BT_INFO("Audio Diconnect Request: type[%d] address [%s]", type, address);
 
        if (type == BT_AUDIO_ALL) {
-               /*TODO: Audio Disconnect All will be supported after HSP profile implementation */
-               return BLUETOOTH_ERROR_NOT_SUPPORT;
+               if (_bt_is_service_connected(address, BT_AUDIO_A2DP)) {
+                       type = BT_AUDIO_A2DP;
+               } else if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
+                       type = BT_AUDIO_HSP;
+               } else {
+                       BT_ERR("No audio service connected");
+                       return BLUETOOTH_ERROR_NOT_CONNECTED;
+               }
+       }
+
+       value = __bt_is_headset_disconnecting(type);
+       if (value != BLUETOOTH_ERROR_NONE) {
+               BT_INFO("Disconnect in progress");
+               return BLUETOOTH_ERROR_IN_PROGRESS;
        }
 
        switch (type) {
-               case BT_AUDIO_HSP:
-               case BT_AUDIO_A2DP:
+               case BT_AUDIO_HSP:  /* Remote is HFP HF unit */
+               case BT_AUDIO_A2DP: /* Remote is A2DP Sink */
                        ret = __bt_process_audio_profile_disconnect(type, device_address);
                        break;
                case BT_AVRCP:
-               case BT_AUDIO_A2DP_SOURCE:
+               case BT_AUDIO_A2DP_SOURCE: /* Remote is A2DP Source */
                        return BLUETOOTH_ERROR_NOT_SUPPORT;
                default:
                        BT_ERR("Unknown role");
@@ -522,13 +914,19 @@ void _bt_remove_headset_from_list(int type, const char *address)
                                if (connected_device->type & BT_AVRCP)
                                        connected_device->type &= ~(BT_AVRCP);
                                break;
+                       case BT_AUDIO_A2DP_SOURCE:
+                               if (connected_device->type & BT_AUDIO_A2DP_SOURCE)
+                                       connected_device->type &= ~(BT_AUDIO_A2DP_SOURCE);
                }
 
                BT_DBG("Connection type = %x\n", connected_device->type);
 
                if (connected_device->type == 0x00) {
+                       BT_INFO("Device will be completely removed from connected list as the only profile connected or connecting got disconnected");
                        g_connected_list = g_list_remove(g_connected_list, connected_device);
                        g_free(connected_device);
+               } else {
+                       connected_device->device_state = BT_STATE_CONNECTED;
                }
 
                node = g_list_next(node);
index 5a413c8..630e32f 100755 (executable)
@@ -71,7 +71,6 @@ void static __bt_hf_handle_audio_disconnection_state(bt_address_t *address)
        BT_DBG("-");
 }
 
-/* Handles both HFP profile disconnect and HF Audio disconnection request */
 static void __bt_reply_hf_disconnection_pending_request(bt_address_t *address)
 {
        BT_DBG("+");
@@ -79,51 +78,86 @@ static void __bt_reply_hf_disconnection_pending_request(bt_address_t *address)
        bluetooth_device_address_t device_address;
        GArray *out_param;
        invocation_info_t *req_info;
+       bt_headset_wait_t *wait_list = NULL;
+       bt_pending_audio_conn_t* data = NULL;
        int result = BLUETOOTH_ERROR_NONE;
        memcpy(device_address.addr, address->addr, BLUETOOTH_ADDRESS_LENGTH);
        _bt_convert_addr_type_to_string(addr, address->addr);
 
-       req_info = _bt_get_request_info_data(BT_AG_DISCONNECT, addr);
+       /* Remove HSP Connection from the device */
+       _bt_remove_headset_from_list(BT_AUDIO_HSP, addr);
 
+       /* Find Async request information*/
+       req_info = _bt_get_request_info_data(BT_AG_DISCONNECT, addr);
        if (NULL == req_info) {
                BT_INFO("AG DisConnect request not found or possibly already replied..");
-               req_info = _bt_get_request_info_data(BT_AG_CONNECT, addr);
 
+               req_info = _bt_get_request_info_data(BT_AG_CONNECT, addr);
                if (req_info == NULL) {
                        BT_INFO("AG Connect request also not found..");
-                       req_info = _bt_get_request_info_data(BT_AUDIO_DISCONNECT, addr);
 
+                       req_info = _bt_get_request_info_data(BT_AUDIO_DISCONNECT, addr);
                        if (req_info == NULL) {
                                BT_INFO("AUDIO Disconnect request also not found..");
-                               req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, addr);
 
+                               req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, addr);
                                if (req_info == NULL) {
                                        BT_INFO("AUDIO Connect request also not found..");
                                        return;
+                               } else {
+                                       BT_INFO("AG Audio All Connect request found..");
+                                       result = BLUETOOTH_ERROR_INTERNAL;
                                }
+                       } else {
+                               BT_INFO("AG Audio All DisConnect request found..");
                        }
+               } else {
+                       BT_INFO("AG Connect request found..");
+                       result = BLUETOOTH_ERROR_INTERNAL;
                }
+       } else {
+               BT_INFO("AG DisConnect request found..");
        }
 
-       if (req_info->service_function == BT_AG_CONNECT ||
-               req_info->service_function == BT_AUDIO_CONNECT)
-               result = BLUETOOTH_ERROR_INTERNAL;
+       /* Cleanup device service search info if Aysnc request was Audio Connect All */
+       if (req_info->service_function == BT_AUDIO_CONNECT) {
+               /* Check if pending connect was present */
+               data = _bt_get_service_search_info(addr);
+               if (data) {
+                       BT_INFO("HF Connection failed during Audio All connect, & pending connect present");
+                       _bt_cleanup_search_info_and_reply_pending_req(data, BLUETOOTH_ERROR_INTERNAL);
+                       goto try_waiting_device;
+               } else {
+                       BT_INFO("Abnormal:HF Connection failed during Audio All connect, but pending connect not present");
+               }
+       }
 
        /* In any of the above cases, reply DBUS context */
        out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-       g_array_append_vals(out_param, &device_address,
-                       sizeof(bluetooth_device_address_t));
+       g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
        _bt_service_method_return(req_info->context,
                        out_param, result);
        g_array_free(out_param, TRUE);
        g_free(req_info->user_data);
        _bt_free_info_from_invocation_list(req_info);
+
+try_waiting_device:
+       wait_list = _bt_get_audio_wait_data();
+       if (wait_list == NULL) {
+               return;
+       }
+       _bt_convert_addr_string_to_type(device_address.addr,
+                       wait_list->address);
+       BT_INFO("Trigger connect for the waiting device [%s], audio type [%d]",
+                       wait_list->address, wait_list->type);
+       _bt_audio_connect(wait_list->type, &device_address);
+       _bt_rel_wait_data();
 }
 
 static void __bt_hf_handle_audio_connection_state(bt_address_t *bd_addr)
 {
        char address[BT_ADDRESS_STRING_SIZE] = { 0 };
-       bt_headset_wait_t *wait_list;
+       bt_headset_wait_t *wait_list = NULL;
        unsigned int result = BLUETOOTH_ERROR_NONE;
        GVariant *param;
        BT_INFO("+");
@@ -131,9 +165,9 @@ static void __bt_hf_handle_audio_connection_state(bt_address_t *bd_addr)
        _bt_convert_addr_type_to_string(address, bd_addr->addr);
        BT_INFO("HF(AG Role) Connected for address [%s]", address);
 
-       /* Send HF(AG Role) disconnected event to Application */
-        param = g_variant_new("(is)", result, address);
-        _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_CONNECTED, param);
+       /* Send HF(AG Role) connected event to Application */
+       param = g_variant_new("(is)", result, address);
+       _bt_send_event(BT_HEADSET_EVENT, BLUETOOTH_EVENT_AG_CONNECTED, param);
 
        /* Add data to the connected list */
        _bt_add_headset_to_list(BT_AUDIO_HSP,
@@ -141,12 +175,19 @@ static void __bt_hf_handle_audio_connection_state(bt_address_t *bd_addr)
 
        wait_list = _bt_get_audio_wait_data();
        if (wait_list != NULL &&
-                       (g_strcmp0(wait_list->address, address) == 0))
+                       (g_strcmp0(wait_list->address, address) == 0)) {
+               BT_INFO("Same Device [%s] is under wait, connection type [%d], going to delete it",
+                               wait_list->address, wait_list->type);
                _bt_rel_wait_data();
+       } else {
+               if (wait_list != NULL)
+                       BT_INFO("Some Device [%s] is under wait, connection type [%d], ", wait_list->address, wait_list->type);
+       }
 
        BT_INFO("Check A2DP pending connect");
-       /*TODO Check pending A2DP connection */
-       //_bt_audio_check_pending_connection(address);
+
+       /* Check pending A2DP connection */
+       _bt_audio_check_pending_connection(address);
 }
 
 static void __bt_reply_hf_connection_pending_request(bt_address_t *address)
@@ -155,27 +196,43 @@ static void __bt_reply_hf_connection_pending_request(bt_address_t *address)
        char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
        bluetooth_device_address_t device_address;
        invocation_info_t *req_info;
+       GArray *out_param;
+       bt_pending_audio_conn_t* data = NULL;
        memcpy(device_address.addr, address->addr, BLUETOOTH_ADDRESS_LENGTH);
        _bt_convert_addr_type_to_string(addr, address->addr);
 
-       /* TODO: AG Connect request is currently not handled */
        req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, addr);
 
        if (NULL != req_info) {
                BT_INFO("Audio All Connect request found");
-/*
-               out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-               g_array_append_vals(out_param, &device_address,
-                               sizeof(bluetooth_device_address_t));
-               _bt_service_method_return(req_info->context,
-                               out_param, result);
-               g_array_free(out_param, TRUE);
-               g_free(req_info->user_data);
-               _bt_free_info_from_invocation_list(req_info);
-*/
+               /* Check for Pending connect : A2DP connect is pending */
+               data = _bt_get_service_search_info(addr);
+               if (data) {
+                       BT_INFO("Pending A2DP connect is present..dont return DBUS for AUDIO_CONNECT_ALL, wait for A2DP connect");
+               } else {
+                       BT_INFO("Pending A2DP connect is Not present..return DBUS for AUDIO_CONNECT_ALL");
+                       goto dbus_return;
+               }
        } else {
                BT_INFO("Audio All Connect Request not found..");
+               req_info = _bt_get_request_info_data(BT_AG_CONNECT, addr);
+
+               if (req_info) {
+                       BT_INFO("AG Connect Request found..");
+                       goto dbus_return;
+               } else {
+                       BT_ERR("AG Connect Request also not found..Abnormal Case!!!");
+                       return;
+               }
        }
+dbus_return:
+       out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+       g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
+       _bt_service_method_return(req_info->context,
+                       out_param, BLUETOOTH_ERROR_NONE);
+       g_array_free(out_param, TRUE);
+       g_free(req_info->user_data);
+       _bt_free_info_from_invocation_list(req_info);
 }
 
 /* This event handler process events for HF (AG role) */
@@ -187,28 +244,29 @@ void _bt_hf_event_handler(int oal_event, gpointer event_data)
        switch (oal_event) {
        case OAL_EVENT_HFP_DISCONNECTED:
                /* Reply to async request for HF connect or disconnect request, if any */
-               BT_INFO("HF Profile disconnected, reply pending request and send event");
+               BT_INFO("HF Profile disconnected, reply pending DBUS request and check waiting device");
                __bt_reply_hf_disconnection_pending_request(bt_addr);
-               __bt_hf_handle_audio_disconnection_state(bt_addr);
                break;
        case OAL_EVENT_HFP_AUDIO_DISCONNECTED:
                /* Reply to async request for HF connect or disconnect request, if any */
                BT_INFO("HF SCO disconnected, reply pending request if any and send event");
-               __bt_reply_hf_disconnection_pending_request(bt_addr);
                __bt_hf_handle_audio_disconnection_state(bt_addr);
                break;
        case OAL_EVENT_HFP_CONNECTED:
-               BT_INFO("HFP Profile conencted, Curently not handled..");
+               BT_INFO("HFP Profile connected, Curently not handled..");
                break;
        case OAL_EVENT_HFP_AUDIO_CONNECTED:
                BT_INFO("HFP SCO conencted, handle the event..");
-               /* Reply to async request for HF connect request, if any */
-               __bt_reply_hf_connection_pending_request(bt_addr);
                __bt_hf_handle_audio_connection_state(bt_addr);
                break;
        case OAL_EVENT_HFP_CONNECTING:
+               /* Reply to async request for HF connect request, if any */
+               BT_INFO("HFP Profile connection successful, wait for Audio connect..");
+               __bt_reply_hf_connection_pending_request(bt_addr);
+               break;
        case OAL_EVENT_HFP_DISCONNECTING:
                BT_INFO("HFP Connecting or Disconnecting..No need to send event to app");
+               //__bt_reply_hf_disconnection_pending_request(bt_addr);
                break;
        case OAL_EVENT_HFP_AUDIO_CONNECTING:
        case OAL_EVENT_HFP_AUDIO_DISCONNECTING:
index fd42e9b..fc27897 100644 (file)
@@ -34,6 +34,7 @@
 #include <bundle.h>
 #include <eventsystem.h>
 #include <arpa/inet.h>
+#include <vconf.h>
 
 #include "bluetooth-api.h"
 #include "bt-service-common.h"
@@ -1040,3 +1041,21 @@ invocation_info_t* _bt_get_request_info_data(int service_function, char *address
 
        return NULL;
 }
+
+void _bt_set_device_values(gboolean connected, int state)
+{
+       int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+
+       if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) != 0) {
+               BT_ERR("vconf_get_int failed");
+       }
+
+       if (connected == TRUE)
+               bt_device_state |= state;
+       else if (bt_device_state & state)
+               bt_device_state ^= state;
+
+       if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+               BT_ERR("vconf_set_int failed");
+       }
+}
index f248884..0d1638d 100644 (file)
@@ -72,6 +72,7 @@ void _bt_service_register_event_handler_callback(
        case BT_AG_MODULE:
                BT_INFO("Register BT_AG_MODULE callback");
                ag_cb = cb;
+               break;
        default:
                BT_INFO("Unknown module");
        }
index 2dc6d43..0ab7ce9 100644 (file)
@@ -35,6 +35,28 @@ typedef enum {
         BT_PENDING_DISCONNECT
 } bt_pending_request_t;
 
+typedef enum {
+        BT_AUDIO_HSP = 0x01,
+        BT_AUDIO_A2DP,
+        BT_AUDIO_ALL,
+        BT_AVRCP,
+        BT_AUDIO_A2DP_SOURCE
+} bt_audio_type_t;
+
+typedef enum {
+        SERVICE_SEARCH_NOT_STARTED,
+        SERVICE_SEARCH_STARTED,
+        SERVICE_SEARCH_DONE,
+} bt_audio_service_search_e;
+
+typedef struct {
+        char *address;
+        bt_audio_type_t type;
+       bt_audio_service_search_e search_status;
+        gboolean is_a2dp_supported;
+        gboolean is_hfp_supported;
+} bt_pending_audio_conn_t;
+
 typedef struct {
         char *address;
         bt_pending_request_t  pending;
@@ -49,14 +71,6 @@ typedef struct {
 } bt_headset_wait_t;
 
 typedef enum {
-        BT_AUDIO_HSP = 0x01,
-        BT_AUDIO_A2DP,
-        BT_AUDIO_ALL,
-        BT_AVRCP,
-        BT_AUDIO_A2DP_SOURCE
-} bt_audio_type_t;
-
-typedef enum {
         BT_STATE_NONE = 0x00,
         BT_STATE_CONNECTING,
         BT_STATE_CONNECTED,
@@ -88,6 +102,16 @@ gboolean _bt_is_headset_type_connected(int type, char *address);
 
 void _bt_add_headset_to_list(int type, int status, const char *address);
 
+void _bt_remove_service_search_request(char *address);
+
+bt_pending_audio_conn_t* _bt_get_service_search_info(char *address);
+
+void _bt_cleanup_search_info_and_reply_pending_req(bt_pending_audio_conn_t *info,
+                                                       int result);
+void _bt_audio_check_pending_connection(char *address);
+
+void _bt_audio_check_pending_disconnection(char *address, int type);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 1b0206f..568b3b3 100755 (executable)
@@ -403,6 +403,8 @@ void _bt_free_remote_dev(bt_remote_dev_info_t * dev_info);
 
 invocation_info_t* _bt_get_request_info_data(int service_function, char *address);
 
+void _bt_set_device_values(gboolean connected, int state);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */