Remove the devider of genlist for IOT profile
[apps/native/ug-bluetooth-efl.git] / standard / bt-net-connection.c
1 /*
2 * ug-bluetooth-efl
3 *
4 * Copyright 2012 Samsung Electronics Co., Ltd
5 *
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 *           GirishAshok Joshi <girish.joshi@samsung.com>
8 *           DoHyun Pyun <dh79.pyun@samsung.com>
9 *
10 * Licensed under the Flora License, Version 1.1 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.tizenopensource.org/license
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 */
23
24 #include "bt-debug.h"
25 #include "bt-main-ug.h"
26 #include "bt-main-view.h"
27 #include "bt-util.h"
28 #include "bt-ipc-handler.h"
29 #include "bt-widget.h"
30 #include "bt-net-connection.h"
31 #include "bt-string-define.h"
32 #include "bt-callback.h"
33
34 /**********************************************************************
35 *                                                 Static Functions
36 ***********************************************************************/
37
38 void __bt_cb_profile_state_changed(connection_profile_state_e state, void *user_data)
39 {
40         FN_START;
41
42         bt_address_t address = { { 0 } };
43         bt_dev_t *dev;
44
45         ret_if(!user_data);
46
47         dev = (bt_dev_t *)user_data;
48         bt_ug_data *ugd = dev->ugd;
49         ret_if(!ugd);
50         ret_if(ugd->op_status == BT_DEACTIVATING || ugd->op_status == BT_DEACTIVATED);
51
52         BT_DBG("profile state: %d", state);
53
54         memcpy(address.bd_addr, dev->bd_addr, BT_ADDRESS_LENGTH_MAX);
55
56         if (state == CONNECTION_PROFILE_STATE_CONNECTED) {
57                 _bt_ipc_update_connected_status(dev->ugd, BT_NETWORK_CONNECTED,
58                                         TRUE, dev->pan_connection_result, &address);
59         } else if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
60                 _bt_ipc_update_connected_status(dev->ugd, BT_NETWORK_CONNECTED,
61                                 FALSE, dev->pan_connection_result, &address);
62         }
63         FN_END;
64 }
65
66 static void __bt_cb_net_opened(connection_error_e result, void* user_data)
67 {
68         FN_START;
69         bt_address_t address = { { 0 } };
70         bt_dev_t *dev;
71
72         ret_if(!user_data);
73
74         dev = (bt_dev_t *)user_data;
75         bt_ug_data *ugd = dev->ugd;
76         ret_if(!ugd);
77
78         BT_DBG("result: %d", result);
79
80         if (result != 0) {
81                 dev->pan_connection_result = BT_UG_FAIL;
82                 memcpy(address.bd_addr, dev->bd_addr, BT_ADDRESS_LENGTH_MAX);
83                 _bt_ipc_update_connected_status(dev->ugd, BT_NETWORK_CONNECTED,
84                                 FALSE, dev->pan_connection_result, &address);
85         } else {
86                 dev->pan_connection_result = BT_UG_ERROR_NONE;
87         }
88
89         FN_END;
90 }
91
92 static void __bt_cb_net_closed(connection_error_e result, void* user_data)
93 {
94         FN_START;
95         bt_dev_t *dev;
96
97         ret_if(!user_data);
98
99         dev = (bt_dev_t *)user_data;
100         bt_ug_data *ugd = dev->ugd;
101         ret_if(!ugd);
102
103         BT_DBG("result: %d", result);
104
105         if (result != 0)
106                 dev->pan_connection_result = BT_UG_FAIL;
107         else
108                 dev->pan_connection_result = BT_UG_ERROR_NONE;
109
110         FN_END;
111 }
112
113 static void *__bt_get_net_profile_list(void *connection,
114                         connection_iterator_type_e type)
115 {
116         int result;
117         Eina_List *ret_list = NULL;
118         gchar **split_string;
119         char *profile_name = NULL;
120         connection_profile_iterator_h profile_iter;
121         connection_profile_h profile_h;
122         connection_profile_type_e profile_type;
123
124         retv_if(connection == NULL, NULL);
125
126         result = connection_get_profile_iterator(connection,
127                                 type,
128                                 &profile_iter);
129         if (result != CONNECTION_ERROR_NONE) {
130                 BT_ERR("Fail to get profile iterator [%d]", result);
131                 return NULL;
132         }
133
134         while (connection_profile_iterator_has_next(profile_iter)) {
135                 profile_name = NULL;
136                 profile_h = NULL;
137                 split_string = NULL;
138
139                 if (connection_profile_iterator_next(profile_iter,
140                                         &profile_h) != CONNECTION_ERROR_NONE) {
141                         BT_ERR("Fail to get profile handle");
142                         continue;
143                 }
144
145                 if (connection_profile_get_type(profile_h,
146                                         &profile_type) != CONNECTION_ERROR_NONE) {
147                         BT_ERR("Fail to get profile type");
148                         continue;
149                 }
150
151                 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
152                         continue;
153
154                 if (connection_profile_get_name(profile_h,
155                                         &profile_name) != CONNECTION_ERROR_NONE) {
156                         BT_ERR("Fail to get profile name");
157                         continue;
158                 }
159
160                 split_string = (gchar **)g_strsplit(profile_name, "_", 3);
161
162                 g_free(profile_name);
163
164                 if (g_strv_length(split_string) < 3)
165                         continue;
166
167                 bt_net_profile_t *profile_data =
168                         (bt_net_profile_t *)g_malloc0(sizeof(bt_net_profile_t));
169
170                 if (profile_data == NULL)
171                         continue;
172
173                 profile_data->profile_h = profile_h;
174                 profile_data->address = (unsigned char *)g_strdup(split_string[2]);
175                 ret_list = eina_list_append(ret_list, profile_data);
176                 g_strfreev(split_string);
177         }
178
179         FN_END;
180
181         return ret_list;
182 }
183
184 static connection_profile_h __bt_get_net_profile(void *connection,
185                         connection_iterator_type_e type,
186                         unsigned char *address)
187 {
188         int result;
189         gchar **split_string;
190         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
191         char *profile_name = NULL;
192         connection_profile_iterator_h profile_iter;
193         connection_profile_h profile_h;
194         connection_profile_type_e profile_type;
195
196         retv_if(connection == NULL, NULL);
197         retv_if(address == NULL, NULL);
198
199         _bt_util_addr_type_to_addr_net_string(net_address, address);
200
201         result = connection_get_profile_iterator(connection,
202                                 type,
203                                 &profile_iter);
204         if (result != CONNECTION_ERROR_NONE) {
205                 BT_ERR("Fail to get profile iterator [%d]", result);
206                 return NULL;
207         }
208
209         while (connection_profile_iterator_has_next(profile_iter)) {
210                 profile_name = NULL;
211                 profile_h = NULL;
212                 split_string = NULL;
213
214                 if (connection_profile_iterator_next(profile_iter,
215                                         &profile_h) != CONNECTION_ERROR_NONE) {
216                         BT_ERR("Fail to get profile handle");
217                         return NULL;
218                 }
219
220                 if (connection_profile_get_type(profile_h,
221                                         &profile_type) != CONNECTION_ERROR_NONE) {
222                         BT_ERR("Fail to get profile type");
223                         continue;
224                 }
225
226                 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
227                         continue;
228
229                 if (connection_profile_get_name(profile_h,
230                                         &profile_name) != CONNECTION_ERROR_NONE) {
231                         BT_ERR("Fail to get profile name");
232                         return NULL;
233                 }
234
235                 split_string = g_strsplit(profile_name, "_", 3);
236
237                 g_free(profile_name);
238
239                 if (g_strv_length(split_string) < 3)
240                         continue;
241
242                 if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
243                         BT_DBG("matched profile");
244                         g_strfreev(split_string);
245                         return profile_h;
246                 }
247
248                 g_strfreev(split_string);
249         }
250
251         FN_END;
252
253         return NULL;
254 }
255
256 /**********************************************************************
257 *                                                Common Functions
258 ***********************************************************************/
259
260 int _bt_create_net_connection(void **net_connection)
261 {
262         FN_START;
263
264         int result;
265         connection_h connection = NULL;
266
267         result = connection_create(&connection);
268
269         if (result != CONNECTION_ERROR_NONE ||
270              connection == NULL) {
271                 BT_ERR("connection_create() failed: %d", result);
272                 *net_connection = NULL;
273                 return BT_UG_FAIL;
274         }
275
276         *net_connection = connection;
277
278         FN_END;
279         return BT_UG_ERROR_NONE;
280 }
281
282 int _bt_destroy_net_connection(void *net_connection)
283 {
284         FN_START;
285
286         int result;
287
288         retv_if(net_connection == NULL, BT_UG_FAIL);
289
290         connection_unset_type_changed_cb(net_connection);
291         result = connection_destroy(net_connection);
292
293         FN_END;
294
295         return (result == CONNECTION_ERROR_NONE) ?
296                 BT_UG_ERROR_NONE : BT_UG_FAIL;
297 }
298
299 void _bt_set_profile_state_changed_cb(void *profile, void *user_data)
300 {
301         FN_START;
302
303         connection_profile_h profile_clone = NULL;
304         bt_dev_t *dev;
305
306         ret_if(profile == NULL);
307         ret_if(user_data == NULL);
308
309         dev = (bt_dev_t *)user_data;
310
311         if (connection_profile_clone(&profile_clone,
312                                 profile) != CONNECTION_ERROR_NONE) {
313                 BT_ERR("Fail to clone the profile");
314                 return;
315         }
316
317         if (connection_profile_set_state_changed_cb(profile,
318                         __bt_cb_profile_state_changed,
319                         dev) != CONNECTION_ERROR_NONE) {
320                 connection_profile_destroy(profile_clone);
321                 return;
322         }
323
324         dev->net_profile = profile_clone;
325
326         FN_END;
327 }
328
329 void _bt_unset_profile_state_changed_cb(void *profile)
330 {
331         FN_START;
332
333         ret_if(profile == NULL);
334         connection_profile_unset_state_changed_cb(profile);
335         connection_profile_destroy(profile);
336
337         FN_END;
338 }
339
340 void *_bt_get_registered_net_profile(void *connection, unsigned char *address)
341 {
342         FN_START;
343
344         return __bt_get_net_profile(connection,
345                         CONNECTION_ITERATOR_TYPE_REGISTERED,
346                         address);
347 }
348
349 void *_bt_get_registered_net_profile_list(void *connection)
350 {
351         FN_START;
352
353         return __bt_get_net_profile_list(connection,
354                         CONNECTION_ITERATOR_TYPE_REGISTERED);
355 }
356
357 void _bt_free_net_profile_list(void *list)
358 {
359         FN_START;
360         ret_if(!list);
361         Eina_List *l = NULL;
362         bt_net_profile_t *profile_data = NULL;
363
364         EINA_LIST_FOREACH(list, l, profile_data) {
365                 if (profile_data && profile_data->address)
366                         g_free(profile_data->address);
367         }
368         eina_list_free(list);
369 }
370
371 int _bt_connect_net_profile(void *connection, void *profile, void *user_data)
372 {
373         FN_START;
374
375         int result;
376         bt_dev_t *dev;
377         connection_wifi_state_e wifi_state;
378
379         retv_if(connection == NULL, BT_UG_FAIL);
380         retv_if(profile == NULL, BT_UG_FAIL);
381         retv_if(user_data == NULL, BT_UG_FAIL);
382
383         dev = (bt_dev_t *)user_data;
384         result = connection_get_wifi_state(connection, &wifi_state);
385         if (result != CONNECTION_ERROR_NONE) {
386                 BT_ERR("connection_get_wifi_state  Failed: %d", result);
387                 return BT_UG_FAIL;
388         }
389
390         if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
391                 bt_address_t address = { { 0 } };
392
393                 /*dislpay pop up */
394                 BT_INFO("wifi_state: %d", wifi_state);
395                 result = notification_status_message_post(BT_STR_BLUETOOTH_TETHERING_CONNECTION_ERROR);
396                 if (result != NOTIFICATION_ERROR_NONE)
397                         BT_ERR("notification_status_message_post() ERROR [%d]", result);
398
399                 /* Set PAN Connection as Disconnected to Update the Checkbox*/
400                 _bt_util_addr_string_to_addr_type(address.bd_addr, (const char *)&dev->addr_str);
401                 BT_DBG("Updating Checkbox as not connected");
402                 dev->network_checked = dev->connected_mask & BT_NETWORK_CONNECTED;
403                 bt_ug_data * ugd = dev->ugd;
404                 if (ugd->profile_vd == NULL) {
405                         BT_ERR("Profile view NULL");
406                         return BT_UG_FAIL;
407                 }
408                 /* No need to change connect_req and ugd status as they are set only when
409                   * this api is sussessfull */
410                 BT_DBG("As we didn't Initiated Connection only update the list");
411                 _bt_util_set_list_disabled(ugd->profile_vd->genlist,
412                                 EINA_FALSE);
413                 return BT_UG_FAIL;
414         }
415
416
417
418         /* Fix P121126-0868 */
419         /* 'dev' can be freed, if use try to unbond during connecting NAP */
420         /*clone_dev = g_malloc0(sizeof(bt_dev_t));
421         g_strlcpy(clone_dev->addr_str, dev->addr_str,
422                         BT_ADDRESS_STR_LEN + 1);
423         clone_dev->ugd = dev->ugd;
424         clone_dev->genlist_item = dev->genlist_item;*/
425
426         result = connection_open_profile(connection,
427                                 profile,
428                                 __bt_cb_net_opened,
429                                 dev);
430
431         if (result != CONNECTION_ERROR_NONE) {
432                 BT_ERR("Connection open Failed: %d", result);
433                 return BT_UG_FAIL;
434         }
435
436         FN_END;
437         return BT_UG_ERROR_NONE;
438 }
439
440 int _bt_disconnect_net_profile(void *connection, void *profile, void *user_data)
441 {
442         FN_START;
443
444         int result;
445
446         retv_if(connection == NULL, BT_UG_FAIL);
447         retv_if(profile == NULL, BT_UG_FAIL);
448
449         result = connection_close_profile(connection,
450                                 profile,
451                                 __bt_cb_net_closed,
452                                 user_data);
453
454         if (result != CONNECTION_ERROR_NONE) {
455                 BT_ERR("Connection close Failed: %d", result);
456                 return BT_UG_FAIL;
457         }
458
459         FN_END;
460         return BT_UG_ERROR_NONE;
461 }