Tizen 2.1 base
[apps/native/ug-bluetooth-efl.git] / src / libraries / bt-net-connection.c
1 /*
2  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.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://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software 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 #include "bt-debug.h"
18 #include "bt-main-ug.h"
19 #include "bt-main-view.h"
20 #include "bt-util.h"
21 #include "bt-ipc-handler.h"
22
23 #include <net_connection.h>
24
25 /**********************************************************************
26 *                                                 Static Functions
27 ***********************************************************************/
28
29 void __bt_cb_profile_state_changed(connection_profile_state_e state, void *user_data)
30 {
31         FN_START;
32
33         bt_address_t address = { { 0 } };
34         bt_dev_t *dev;
35
36         if (user_data == NULL)
37                 return;
38
39         dev = (bt_dev_t *)user_data;
40
41         BT_DBG("state: %d", state);
42
43         memcpy(address.bd_addr, dev->bd_addr, BT_ADDRESS_LENGTH_MAX);
44
45         if (state == CONNECTION_PROFILE_STATE_CONNECTED) {
46                 _bt_ipc_update_connected_status(dev->ugd, BT_NETWORK_CONNECTED,
47                                         TRUE, BT_UG_ERROR_NONE, &address);
48         } else if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
49                 _bt_ipc_update_connected_status(dev->ugd, BT_NETWORK_CONNECTED,
50                                         FALSE, BT_UG_ERROR_NONE, &address);
51         }
52 }
53
54 static void __bt_cb_net_opened(connection_error_e result, void* user_data)
55 {
56         FN_START;
57
58         bt_ug_data *ugd;
59         bt_dev_t *clone_dev;
60         bt_dev_t *dev;
61
62         BT_DBG("result: %d", result);
63
64         ret_if(user_data == NULL);
65
66         clone_dev = (bt_dev_t *)user_data;
67
68         ugd = (bt_ug_data *)clone_dev->ugd;
69         if (clone_dev->ugd == NULL) {
70                 g_free(clone_dev);
71                 return;
72         }
73
74         dev = _bt_main_get_dev_info_by_address(ugd->paired_device,
75                                                 clone_dev->addr_str);
76
77         if (dev == NULL) {
78                 /* 'dev' was freed */
79                 g_free(clone_dev);
80                 return;
81         }
82
83         ugd->connect_req = FALSE;
84
85         if (dev->status == BT_CONNECTING)
86                 dev->status = BT_IDLE;
87
88         elm_genlist_item_update((Elm_Object_Item *)dev->genlist_item);
89         g_free(clone_dev);
90
91         FN_END;
92 }
93
94 static void __bt_cb_net_closed(connection_error_e result, void* user_data)
95 {
96         FN_START;
97
98         bt_ug_data *ugd;
99         bt_dev_t *dev;
100
101         BT_DBG("result: %d", result);
102
103         ret_if(user_data == NULL);
104
105         dev = (bt_dev_t *)user_data;
106
107         ugd = dev->ugd;
108         if (ugd)
109                 ugd->connect_req = FALSE;
110
111         if (dev->status == BT_DISCONNECTING)
112                 dev->status = BT_IDLE;
113
114         elm_genlist_item_update((Elm_Object_Item *)dev->genlist_item);
115
116         FN_END;
117 }
118
119 static connection_profile_h __bt_get_net_profile(void *connection,
120                         connection_iterator_type_e type,
121                         unsigned char *address)
122 {
123         int result;
124         gchar **split_string;
125         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
126         char *profile_name = NULL;
127         connection_profile_iterator_h profile_iter;
128         connection_profile_h profile_h;
129         connection_profile_type_e profile_type;
130
131         retv_if(connection == NULL, NULL);
132         retv_if(address == NULL, NULL);
133
134         _bt_util_addr_type_to_addr_net_string(net_address, address);
135
136         result = connection_get_profile_iterator(connection,
137                                 type,
138                                 &profile_iter);
139         if (result != CONNECTION_ERROR_NONE) {
140                 BT_ERR("Fail to get profile iterator [%d]", result);
141                 return NULL;
142         }
143
144         while (connection_profile_iterator_has_next(profile_iter)) {
145                 profile_name = NULL;
146                 profile_h = NULL;
147                 split_string = NULL;
148
149                 if (connection_profile_iterator_next(profile_iter,
150                                         &profile_h) != CONNECTION_ERROR_NONE) {
151                         BT_ERR("Fail to get profile handle");
152                         return NULL;
153                 }
154
155                 if (connection_profile_get_type(profile_h,
156                                         &profile_type) != CONNECTION_ERROR_NONE) {
157                         BT_ERR("Fail to get profile type\n");
158                         continue;
159                 }
160
161                 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
162                         continue;
163
164                 if (connection_profile_get_name(profile_h,
165                                         &profile_name) != CONNECTION_ERROR_NONE) {
166                         BT_ERR("Fail to get profile name");
167                         return NULL;
168                 }
169
170                 split_string = g_strsplit(profile_name, "_", 3);
171
172                 g_free(profile_name);
173
174                 if (g_strv_length(split_string) < 3)
175                         continue;
176
177                 if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
178                         BT_DBG("matched profile");
179                         g_strfreev(split_string);
180                         return profile_h;
181                 }
182
183                 g_strfreev(split_string);
184         }
185
186         FN_END;
187
188         return NULL;
189 }
190
191 /**********************************************************************
192 *                                                Common Functions
193 ***********************************************************************/
194
195 int _bt_create_net_connection(void **net_connection)
196 {
197         FN_START;
198
199         int result;
200         connection_h connection = NULL;
201
202         result = connection_create(&connection);
203
204         if (result != CONNECTION_ERROR_NONE ||
205              connection == NULL) {
206                 BT_DBG("connection_create() failed: %d", result);
207                 return BT_UG_FAIL;
208         }
209
210         *net_connection = connection;
211
212         FN_END;
213         return BT_UG_ERROR_NONE;
214 }
215
216 int _bt_destroy_net_connection(void *net_connection)
217 {
218         FN_START;
219
220         int result;
221
222         retv_if(net_connection == NULL, BT_UG_FAIL);
223
224         result = connection_destroy(net_connection);
225         connection_unset_type_changed_cb(net_connection);
226
227         FN_END;
228
229         return (result == CONNECTION_ERROR_NONE) ?
230                 BT_UG_ERROR_NONE : BT_UG_FAIL;
231 }
232
233 void _bt_set_profile_state_changed_cb(void *profile, void *user_data)
234 {
235         FN_START;
236
237         connection_profile_h profile_clone = NULL;
238         bt_dev_t *dev;
239
240         ret_if(profile == NULL);
241         ret_if(user_data == NULL);
242
243         dev = (bt_dev_t *)user_data;
244
245         if (connection_profile_clone(&profile_clone,
246                                 profile) != CONNECTION_ERROR_NONE) {
247                 BT_ERR("Fail to clone the profile");
248                 return;
249         }
250
251         if (connection_profile_set_state_changed_cb(profile,
252                         __bt_cb_profile_state_changed,
253                         dev) != CONNECTION_ERROR_NONE) {
254                 connection_profile_destroy(profile_clone);
255                 return;
256         }
257
258         dev->net_profile = profile_clone;
259
260         FN_END;
261 }
262
263 void _bt_unset_profile_state_changed_cb(void *profile)
264 {
265         FN_START;
266
267         ret_if(profile == NULL);
268         connection_profile_unset_state_changed_cb(profile);
269         connection_profile_destroy(profile);
270
271         FN_END;
272 }
273
274 void *_bt_get_registered_net_profile(void *connection, unsigned char *address)
275 {
276         FN_START;
277
278         return __bt_get_net_profile(connection,
279                         CONNECTION_ITERATOR_TYPE_REGISTERED,
280                         address);
281 }
282
283 void *_bt_get_connected_net_profile(void *connection, unsigned char *address)
284 {
285         FN_START;
286
287         return __bt_get_net_profile(connection,
288                         CONNECTION_ITERATOR_TYPE_CONNECTED,
289                         address);
290 }
291
292 int _bt_connect_net_profile(void *connection, void *profile, void *user_data)
293 {
294         FN_START;
295
296         int result;
297         bt_dev_t *dev;
298         bt_dev_t *clone_dev;
299         connection_wifi_state_e wifi_state;
300
301         retv_if(connection == NULL, BT_UG_FAIL);
302         retv_if(profile == NULL, BT_UG_FAIL);
303         retv_if(user_data == NULL, BT_UG_FAIL);
304
305         dev = (bt_dev_t *)user_data;
306
307         result = connection_get_wifi_state(connection, &wifi_state);
308         if (result != CONNECTION_ERROR_NONE) {
309                 BT_ERR("Fail to get wifi state: %d", result);
310                 return BT_UG_FAIL;
311         }
312
313         if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
314                 BT_ERR("Wifi is connected");
315                 return BT_UG_FAIL;
316         }
317
318         /* Fix P121126-0868 */
319         /* 'dev' can be freed, if use try to unbond during connecting NAP */
320         clone_dev = g_malloc0(sizeof(bt_dev_t));
321         g_strlcpy(clone_dev->addr_str, dev->addr_str,
322                         BT_ADDRESS_STR_LEN + 1);
323         clone_dev->ugd = dev->ugd;
324         clone_dev->genlist_item = dev->genlist_item;
325
326         result = connection_open_profile(connection,
327                                 profile,
328                                 __bt_cb_net_opened,
329                                 clone_dev);
330
331         if (result != CONNECTION_ERROR_NONE) {
332                 BT_ERR("Connection open Failed: %d", result);
333                 g_free(clone_dev);
334                 return BT_UG_FAIL;
335         }
336
337         FN_END;
338         return BT_UG_ERROR_NONE;
339 }
340
341 int _bt_disconnect_net_profile(void *connection, void *profile, void *user_data)
342 {
343         FN_START;
344
345         int result;
346
347         retv_if(connection == NULL, BT_UG_FAIL);
348         retv_if(profile == NULL, BT_UG_FAIL);
349
350         result = connection_close_profile(connection,
351                                 profile,
352                                 __bt_cb_net_closed,
353                                 user_data);
354
355         if (result != CONNECTION_ERROR_NONE) {
356                 BT_ERR("Connection close Failed: %d", result);
357                 return BT_UG_FAIL;
358         }
359
360         FN_END;
361         return BT_UG_ERROR_NONE;
362 }