Don't add the recovery logic into the platform image
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-headset-connection.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <string.h>
20 #include <dlog.h>
21 #include <vconf.h>
22 #include <vconf-internal-bt-keys.h>
23
24 #include "bluetooth-api.h"
25 #include "bt-internal-types.h"
26
27 #include "bt-service-common.h"
28 #include "bt-service-event.h"
29 #include "bt-service-main.h"
30 #include "bt-service-adapter.h"
31 #include "bt-service-device.h"
32 #include "bt-service-audio.h"
33 #include "bt-service-headset-connection.h"
34
35 #include "bt-service-opp-client.h"
36
37
38
39 static GList *p_connection_list = NULL;
40 typedef enum {
41         BLUETOOTH_NONE_CONNECTED = 0x00,
42         BLUETOOTH_HFP_CONNECTED ,
43         BLUETOOTH_A2DP_CONNECTED,
44         BLUETOOTH_ALL_CONNECTED,
45 } bluetooth_state_type_t;
46
47 typedef struct {
48         bluetooth_state_type_t state;
49         bluetooth_device_info_t dev_info;
50         int connection_type;
51 } bt_connection_node_info_t;
52
53 gboolean connection_local = FALSE;
54
55
56 void _bt_headset_set_local_connection(gboolean value)
57 {
58         BT_INFO("setting connection_local to %d", value);
59         connection_local = value;
60 }
61
62 gboolean _bt_headset_get_local_connection()
63 {
64         return connection_local;
65 }
66
67 //gint compare_state(GList *data, bluetooth_state_type_t state)
68 gint compare_state(gconstpointer list_data, gconstpointer conn_state)
69 {
70         GList *data = (GList *) list_data;
71         bluetooth_state_type_t *state = (bluetooth_state_type_t *)conn_state;
72         bt_connection_node_info_t *p_data = (bt_connection_node_info_t *) data;
73         if (p_data->state == *state) {
74                 BT_INFO("State Already Added");
75                 return 0;
76         }
77         return 1;
78 }
79
80 gboolean connect_remote_media_audio(gpointer user_data)
81 {
82         bt_connection_node_info_t *conn_info =
83                         (bt_connection_node_info_t *) user_data;
84         GList *list = NULL;
85         bluetooth_state_type_t state;
86
87         char remote_address[BT_ADDRESS_STRING_SIZE] = { 0 };
88         _bt_convert_addr_type_to_string(remote_address, conn_info->dev_info.device_address.addr);
89         if (p_connection_list == NULL) {
90                 BT_INFO("None of device connected and this hasbeen triggered");
91                 g_free(conn_info);
92                 return FALSE;
93         }
94         if (conn_info->connection_type == BT_AUDIO_A2DP) {
95                 state = BLUETOOTH_A2DP_CONNECTED;
96                 list = g_list_find_custom(p_connection_list,
97                                 &state, compare_state);
98                 if (list == NULL) {
99                         BT_INFO("Head Set didn't initiated a2dp connection");
100                         BT_INFO("local device initiating A2DP connection");
101                         _bt_audio_connect(0, BT_AUDIO_A2DP,
102                                         &conn_info->dev_info.device_address, NULL);
103                 } else {
104                         BT_INFO("A2DP Connection Already exists");
105                 }
106                 g_free(conn_info);
107         } else {
108                 state = BLUETOOTH_HFP_CONNECTED;
109                 list = g_list_find_custom(p_connection_list,
110                                 &state, compare_state);
111                 if (list == NULL) {
112                         BT_INFO("Headset didn't initiated HFP connection");
113                         BT_INFO("local device intiating HFP Connection");
114                         _bt_audio_connect(0, BT_AUDIO_HSP,
115                                         &conn_info->dev_info.device_address, NULL);
116                 } else {
117                         BT_INFO("HFP Connection Already exists");
118                 }
119                 g_free(conn_info);
120         }
121         return FALSE;
122 }
123
124 void _bt_get_bluetooth_device_info(char *remote_address, bluetooth_device_info_t *device)
125 {
126         GArray *dev_list = NULL;
127         int size = 0;
128         int i = 0;
129         bluetooth_device_info_t info;
130         char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
131
132         if (device == NULL)
133                 return;
134
135         dev_list = g_array_new (FALSE, FALSE, sizeof(gchar));
136
137         _bt_get_bonded_devices(&dev_list);
138         size = (dev_list->len) / sizeof(bluetooth_device_info_t);
139         for (i = 0; i < size; i++) {
140                 info = g_array_index(dev_list, bluetooth_device_info_t, i);
141                 _bt_convert_addr_type_to_string(bond_address, info.device_address.addr);
142                 if (strcmp(bond_address, remote_address) == 0) {
143                         BT_INFO("Match found");
144                         memcpy(device, &info, sizeof(bluetooth_device_info_t));
145                         g_array_free(dev_list, TRUE);
146                         return;
147                 }
148         }
149         g_array_free(dev_list, TRUE);
150         return;
151 }
152
153 void _bt_headset_add_timer_function(int connection_type, bluetooth_device_info_t *info)
154 {
155         bt_connection_node_info_t *pass_conn_info = NULL;
156
157         if (info == NULL)
158                 return;
159
160         pass_conn_info = g_new0(bt_connection_node_info_t, 1);
161         pass_conn_info->connection_type = connection_type;
162         memcpy(&pass_conn_info->dev_info, info, sizeof(bluetooth_device_info_t));
163         /* This need to be freed in timer function */
164         g_timeout_add(CONNECT_TIMEOUT, connect_remote_media_audio,
165                 pass_conn_info);
166         return;
167 }
168
169 void _bt_start_timer_for_connection(char *remote_address, int connection_type)
170 {
171         GArray *dev_list = NULL;
172         int size;
173         int i;
174         int j;
175         bluetooth_device_info_t info;
176         char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
177         dev_list = g_array_new(FALSE, FALSE, sizeof(gchar));
178         _bt_get_bonded_devices(&dev_list);
179         size = (dev_list->len) / sizeof(bluetooth_device_info_t);
180
181         for (i = 0; i < size; i++) {
182                 info = g_array_index(dev_list, bluetooth_device_info_t, i);
183                 j = 0;
184                 _bt_convert_addr_type_to_string(bond_address,
185                                 info.device_address.addr);
186                 if (strcmp(bond_address, remote_address) != 0)
187                         continue;
188                 BT_INFO("Device address Matched");
189
190                 while (j != info.service_index) {
191                         BT_INFO("UUID %s", info.uuids[j]);
192                         if (connection_type == BT_AUDIO_A2DP) {
193                                 if (strcmp(info.uuids[j], A2DP_SINK_UUID) == 0) {
194                                         BT_INFO("Remote Device has A2DP Sink Support start timer");
195                                         _bt_headset_add_timer_function(BT_AUDIO_A2DP, &info);
196                                         goto end;
197                                 }
198                         } else {
199                                 if (strcmp(info.uuids[j], HFP_HS_UUID) == 0) {
200                                         BT_INFO("Remote Device has HFP Sink Support start timer");
201                                         _bt_headset_add_timer_function(BT_AUDIO_HSP, &info);
202                                         goto end;
203                                 }
204                         }
205                         j++;
206                 }
207         }
208 end:
209         g_array_free(dev_list, TRUE);
210 }
211
212 void __bt_connection_manager_set_state(char *remote_address, int event)
213 {
214         bt_connection_node_info_t *info;
215
216         char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
217         if (event == BLUETOOTH_EVENT_AG_CONNECTED) {
218                 info = g_new0(bt_connection_node_info_t, 1);
219                 info->state = BLUETOOTH_HFP_CONNECTED;
220                 _bt_get_bluetooth_device_info(remote_address, &info->dev_info);
221                 _bt_convert_addr_type_to_string(bond_address,
222                                 info->dev_info.device_address.addr);
223                 BT_INFO("Adding HFP Connected device to list");
224                 p_connection_list = g_list_append(p_connection_list, info);
225         } else if (event == BLUETOOTH_EVENT_AG_DISCONNECTED) {
226                 /* Delete coresponding node */
227                 BT_INFO("Deleting HFP Connected device from list");
228                 GList *list = NULL;
229                 bluetooth_state_type_t state;
230                 bt_connection_node_info_t *h_conn;
231                 state = BLUETOOTH_HFP_CONNECTED;
232                 list = g_list_find_custom(p_connection_list,
233                                 &state, compare_state);
234                 if (list == NULL) {
235                         BT_INFO("Didn't found any device with HFP State");
236                         return;
237                 }
238                 h_conn = list->data;
239                 p_connection_list = g_list_remove(p_connection_list, h_conn);
240                 g_free(h_conn);
241         } else if (event == BLUETOOTH_EVENT_AV_CONNECTED) {
242                 info = g_new0(bt_connection_node_info_t, 1);
243                 info->state = BLUETOOTH_A2DP_CONNECTED;
244                 _bt_get_bluetooth_device_info(remote_address, &info->dev_info);
245                 _bt_convert_addr_type_to_string(bond_address,
246                                 info->dev_info.device_address.addr);
247                 BT_INFO("Adding A2DP Connected device to list");
248                 p_connection_list = g_list_append(p_connection_list, info);
249         } else if (event == BLUETOOTH_EVENT_AV_DISCONNECTED) {
250                 BT_INFO("Deleting A2DP Connected device from list");
251                 bt_connection_node_info_t *a_conn;
252                 GList *list = NULL;
253                 bluetooth_state_type_t state;
254                 state = BLUETOOTH_A2DP_CONNECTED;
255                 list = g_list_find_custom(p_connection_list,
256                                 &state, compare_state);
257                 if (list == NULL) {
258                         BT_INFO("Didn't found any device with A2DP State");
259                         return;
260                 }
261                 a_conn = list->data;
262                 p_connection_list = g_list_remove(p_connection_list, a_conn);
263                 g_free(a_conn);
264         }
265 }
266