tizen 2.4 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_bluetooth.c
1 /*
2  * mobileap-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>
19 #include <glib.h>
20 #include <dbus/dbus.h>
21 #include <bluetooth.h>
22 #ifndef TIZEN_TV
23 #include <bluetooth_internal.h>
24 #endif
25
26 #include "mobileap_softap.h"
27 #include "mobileap_common.h"
28 #include "mobileap_bluetooth.h"
29 #include "mobileap_handler.h"
30 #include "mobileap_notification.h"
31
32 typedef struct {
33         bt_device_info_s *info;
34         char *intf_name;
35         const in_addr_t intf_ip;
36 } __bt_remote_device_s;
37
38 static __bt_remote_device_s __bt_remote_devices[MOBILE_AP_MAX_BT_STA] = {
39         {NULL, NULL, IP_ADDRESS_BT_1},
40         {NULL, NULL, IP_ADDRESS_BT_2},
41         {NULL, NULL, IP_ADDRESS_BT_3},
42         {NULL, NULL, IP_ADDRESS_BT_4}};
43
44 static GDBusMethodInvocation *g_context = NULL;
45
46 static void __bt_nap_connection_changed(bool connected, const char *remote_address,
47                                 const char *interface_name, void *user_data);
48 static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data);
49 static void __handle_bt_adapter_visibility();
50
51 int __recheck_bt_adapter_timer = 0;
52
53 static __bt_remote_device_s *__find_bt_remote(const char *mac)
54 {
55         int i;
56
57         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
58                 if (__bt_remote_devices[i].info == NULL)
59                         continue;
60
61                 if (!g_ascii_strcasecmp(__bt_remote_devices[i].info->remote_address, mac))
62                         break;
63         }
64
65         if (i == MOBILE_AP_MAX_BT_STA) {
66                 SERR("Not found : %s\n", mac);
67                 return NULL;
68         }
69
70         return &__bt_remote_devices[i];
71 }
72
73 static __bt_remote_device_s *__add_bt_remote(bt_device_info_s *info, const char *intf_name)
74 {
75         int i;
76
77         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
78                 if (__bt_remote_devices[i].info == NULL)
79                         break;
80         }
81
82         if (i == MOBILE_AP_MAX_BT_STA) {
83                 ERR("Too many BT devices are connected\n");
84                 return NULL;
85         }
86
87         __bt_remote_devices[i].intf_name = g_strdup(intf_name);
88         if (__bt_remote_devices[i].intf_name == NULL) {
89                 ERR("Memory allocation failed\n");
90                 return NULL;
91         }
92
93         _add_interface_routing(__bt_remote_devices[i].intf_name,
94                         __bt_remote_devices[i].intf_ip);
95         _add_routing_rule(__bt_remote_devices[i].intf_name);
96         __bt_remote_devices[i].info = info;
97
98         return &__bt_remote_devices[i];
99 }
100
101 static gboolean __del_bt_remote(const char *mac)
102 {
103         int i;
104
105         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
106                 if (__bt_remote_devices[i].info == NULL)
107                         continue;
108
109                 if (!g_ascii_strcasecmp(__bt_remote_devices[i].info->remote_address, mac))
110                         break;
111         }
112
113         if (i == MOBILE_AP_MAX_BT_STA) {
114                 SERR("Not found : %s\n", mac);
115                 return FALSE;
116         }
117
118         _del_routing_rule(__bt_remote_devices[i].intf_name);
119         _del_interface_routing(__bt_remote_devices[i].intf_name,
120                         __bt_remote_devices[i].intf_ip);
121          bt_adapter_free_device_info(__bt_remote_devices[i].info);
122          g_free(__bt_remote_devices[i].intf_name);
123
124          __bt_remote_devices[i].info = NULL;
125          __bt_remote_devices[i].intf_name = NULL;
126
127         return TRUE;
128 }
129
130 static void __del_bt_remote_all(void)
131 {
132         int i;
133
134         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
135                 if (__bt_remote_devices[i].info) {
136                         bt_adapter_free_device_info(__bt_remote_devices[i].info);
137                         __bt_remote_devices[i].info = NULL;
138                 }
139
140                 if (__bt_remote_devices[i].intf_name) {
141                         _del_routing_rule(__bt_remote_devices[i].intf_name);
142                         _del_interface_routing(__bt_remote_devices[i].intf_name,
143                                 __bt_remote_devices[i].intf_ip);
144                         g_free(__bt_remote_devices[i].intf_name);
145                         __bt_remote_devices[i].intf_name = NULL;
146                 }
147         }
148
149         return;
150 }
151
152 static mobile_ap_error_code_e __init_bt(Tethering *obj)
153 {
154         int ret;
155
156         ret = bt_initialize();
157         if (ret != BT_ERROR_NONE) {
158                 ERR("bt_initialize is failed : %d\n", ret);
159                 return MOBILE_AP_ERROR_RESOURCE;
160         }
161
162         ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
163         if (ret != BT_ERROR_NONE) {
164                 ERR("bt_adapter_set_state_changed_cb is failed : %d\n", ret);
165                 bt_deinitialize();
166                 return MOBILE_AP_ERROR_RESOURCE;
167         }
168
169         return MOBILE_AP_ERROR_NONE;
170 }
171
172 static void __deinit_bt(void)
173 {
174         int ret;
175
176         ret = bt_adapter_unset_state_changed_cb();
177         if (ret != BT_ERROR_NONE)
178                 ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", ret);
179
180         ret = bt_deinitialize();
181         if (ret != BT_ERROR_NONE)
182                 ERR("bt_deinitialize is failed : %d\n", ret);
183
184         return;
185 }
186
187 static gboolean __is_bt_adapter_on(void)
188 {
189         int ret;
190         bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
191
192         ret = bt_adapter_get_state(&adapter_state);
193         if (ret != BT_ERROR_NONE) {
194                 ERR("bt_adapter_get_state is failed : %d\n", ret);
195                 return FALSE;
196         }
197
198         if (adapter_state == BT_ADAPTER_ENABLED)
199                 return TRUE;
200         else
201                 return FALSE;
202 }
203
204 gboolean __bt_adapter_timeout_cb(Tethering *obj)
205 {
206         DBG("+\n");
207
208         static int retry_count = 0;
209         if (__is_bt_adapter_on() == TRUE) {
210                 DBG("BT Adapter is enabled by other process \n");
211                 retry_count = 0;
212                 DBG("-\n");
213                 return FALSE;
214         } else {
215                 if (++retry_count >= PS_RECHECK_COUNT_MAX) {
216                         retry_count = 0;
217                         ERR("_enable_bt_tethering() is failed because of bt_adapter_eanbled() failed:n");
218                         _mobileap_clear_state(MOBILE_AP_STATE_BT);
219                         __deinit_bt();
220                         tethering_complete_enable_bt_tethering(obj, g_context, MOBILE_AP_ERROR_INTERNAL);
221                         g_context = NULL;
222                         _unblock_device_sleep();
223                         DBG("-\n");
224                         return FALSE;
225                 } else {
226                         DBG("-\n");
227                         return TRUE;
228                 }
229         }
230 }
231
232 static mobile_ap_error_code_e __turn_on_bt_adapter(gpointer data)
233 {
234         int ret;
235
236         Tethering *obj = (Tethering *)data;
237
238         ret = bt_adapter_enable();
239         if (ret == BT_ERROR_NOW_IN_PROGRESS) {
240                 if (__recheck_bt_adapter_timer) {
241                         g_source_remove(__recheck_bt_adapter_timer);
242                 }
243                 __recheck_bt_adapter_timer = g_timeout_add(PS_RECHECK_INTERVAL,
244                                 __bt_adapter_timeout_cb, obj);
245                 return MOBILE_AP_ERROR_NONE;
246         }
247
248         if (ret != BT_ERROR_NONE && ret != BT_ERROR_ALREADY_DONE) {
249                 ERR("bt_adapter_enable is failed : %d\n", ret);
250 #ifndef TIZEN_TV
251                 if (ret == BT_ERROR_PERMISSION_DENIED)
252                         return MOBILE_AP_ERROR_PERMISSION_DENIED;
253                 else
254 #endif
255                         return MOBILE_AP_ERROR_RESOURCE;
256         }
257
258         return MOBILE_AP_ERROR_NONE;
259 }
260
261 static mobile_ap_error_code_e __turn_on_bt_nap(Tethering *obj)
262 {
263         int bt_ret = BT_ERROR_NONE;
264
265         bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
266         if (bt_ret != BT_ERROR_NONE) {
267                 ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
268                 return MOBILE_AP_ERROR_RESOURCE;
269         }
270
271         bt_ret = bt_nap_activate();
272         if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
273                 bt_nap_unset_connection_state_changed_cb();
274                 ERR("bt_nap_activate is failed : %d\n", bt_ret);
275 #ifndef TIZEN_TV
276                 if (bt_ret == BT_ERROR_PERMISSION_DENIED)
277                         return MOBILE_AP_ERROR_PERMISSION_DENIED;
278                 else
279 #endif
280                         return MOBILE_AP_ERROR_RESOURCE;
281         }
282
283         return MOBILE_AP_ERROR_NONE;
284 }
285
286 static void __turn_off_bt_nap(void)
287 {
288         int bt_ret;
289
290         bt_ret = bt_nap_deactivate();
291         if (bt_ret != BT_ERROR_NONE)
292                 ERR("bt_nap_deactivate is failed : %d\n", bt_ret);
293         else
294                 DBG("bt_nap_deactivate is called\n");
295
296         bt_ret = bt_nap_unset_connection_state_changed_cb();
297         if (bt_ret != BT_ERROR_NONE)
298                 ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
299
300         return;
301 }
302
303 mobile_ap_error_code_e _enable_bt_tethering(Tethering *obj)
304 {
305         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
306
307         DBG("+\n");
308         if (__recheck_bt_adapter_timer) {
309                 g_source_remove(__recheck_bt_adapter_timer);
310                 __recheck_bt_adapter_timer = 0;
311         }
312
313         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
314                 ERR("Wi-Fi AP is enabled\n");
315                 return MOBILE_AP_ERROR_RESOURCE;
316         }
317
318         ret = _init_tethering();
319         if (ret != MOBILE_AP_ERROR_NONE) {
320                 return ret;
321         }
322
323         ret = __turn_on_bt_nap(obj);
324         if (ret != MOBILE_AP_ERROR_NONE) {
325                 _deinit_tethering();
326                 return ret;
327         }
328         _delete_timeout_noti();
329         _init_timeout_cb(MOBILE_AP_TYPE_BT, (void *)obj);
330         _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
331
332         DBG("-\n");
333         return ret;
334 }
335
336 mobile_ap_error_code_e _disable_bt_tethering(Tethering *obj)
337 {
338         int ret = BT_ERROR_NONE;
339         if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
340                 ERR("BT tethering has not been enabled\n");
341                 return MOBILE_AP_ERROR_NOT_ENABLED;
342         }
343         ret = bt_adapter_unset_visibility_mode_changed_cb();
344         if (ret != BT_ERROR_NONE)
345                 ERR("bt_adapter_unset_visibility_mode_changed_cb is failed : %d\n", ret);
346
347         _block_device_sleep();
348         if (__is_bt_adapter_on()) {
349                 __turn_off_bt_nap();
350                 __deinit_bt();
351         }
352
353         _remove_station_info_all(MOBILE_AP_TYPE_BT);
354         __del_bt_remote_all();
355         _deinit_timeout_cb(MOBILE_AP_TYPE_BT);
356
357         _deinit_tethering();
358         _mobileap_clear_state(MOBILE_AP_STATE_BT);
359         _unblock_device_sleep();
360
361         return MOBILE_AP_ERROR_NONE;
362 }
363
364
365 static void __bt_nap_connection_changed(bool connected, const char *remote_address, const char *interface_name, void *user_data)
366 {
367         if (remote_address == NULL || interface_name == NULL || user_data == NULL) {
368                 ERR("Invalid param\n");
369                 return;
370         }
371
372         __bt_remote_device_s *remote;
373         bt_device_info_s *info;
374         int ret;
375         int n_station = 0;
376
377         SDBG("Remote address : %s, Interface : %s, %s\n",
378                         remote_address, interface_name,
379                         connected ? "Connected" : "Disconnected");
380
381         if (connected) {
382                 ret = bt_adapter_get_bonded_device_info(remote_address, &info);
383                 if (ret != BT_ERROR_NONE) {
384                         ERR("bt_adapter_get_bonded_device_info is failed : %d\n", ret);
385                         return;
386                 }
387
388                 remote = __add_bt_remote(info, interface_name);
389                 if (remote == NULL) {
390                         ERR("__add_bt_remote is failed\n");
391                          bt_adapter_free_device_info(info);
392                         return;
393                 }
394
395                 ret = _mh_core_set_ip_address(interface_name, remote->intf_ip);
396                 if (ret != MOBILE_AP_ERROR_NONE) {
397                         ERR("Setting ip address error : %d\n", ret);
398                 }
399         } else {
400                 _remove_station_info(remote_address, _slist_find_station_by_mac);
401                 if (__del_bt_remote(remote_address) == FALSE) {
402                         ERR("__del_bt_remote is failed\n");
403                 }
404
405                 _get_station_count((gconstpointer)MOBILE_AP_TYPE_BT,
406                                 _slist_find_station_by_interface, &n_station);
407                 if (n_station == 0)
408                         _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
409         }
410
411         return;
412 }
413
414 static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data)
415 {
416         if (user_data == NULL) {
417                 ERR("Invalid param\n");
418                 return;
419         }
420
421         DBG("+\n");
422
423         if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT))
424                 return;
425
426         int ret = MOBILE_AP_ERROR_RESOURCE;
427         Tethering *obj = (Tethering *)user_data;
428
429         if (result != BT_ERROR_NONE) {
430                 ERR("BT Adapter operation is failed : %d\n", result);
431                 goto FAIL;
432         }
433
434         SDBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
435                         "enabled" : "disabled");
436         if (adapter_state == BT_ADAPTER_DISABLED) {
437                 _disable_bt_tethering(obj);
438                 tethering_emit_bluetooth_off(obj, SIGNAL_MSG_NOT_AVAIL_INTERFACE);
439                 return;
440         } else {
441                 ret = _enable_bt_tethering(obj);
442                 if (ret != MOBILE_AP_ERROR_NONE) {
443                         ERR("_enable_bt_tethering() is failed : %d\n", ret);
444                         __deinit_bt();
445                         goto FAIL;
446                 }
447
448                 tethering_emit_bluetooth_on(obj);
449                 _create_tethering_active_noti();
450                 tethering_complete_enable_bt_tethering(obj, g_context, ret);
451                 __handle_bt_adapter_visibility();
452                 g_context = NULL;
453                 _unblock_device_sleep();
454
455                 return;
456         }
457
458 FAIL:
459         tethering_complete_enable_bt_tethering(obj, g_context, ret);
460         g_context = NULL;
461         _mobileap_clear_state(MOBILE_AP_STATE_BT);
462         _unblock_device_sleep();
463
464         return;
465 }
466
467 void _bt_get_remote_device_name(const char *mac, char **name)
468 {
469         if (mac == NULL || name == NULL) {
470                 ERR("Invalid param\n");
471                 return;
472         }
473
474         __bt_remote_device_s *remote = NULL;
475
476         remote = __find_bt_remote(mac);
477         if (remote == NULL)
478                 return;
479
480         *name = g_strdup(remote->info->remote_name);
481         if (*name == NULL) {
482                 ERR("Memory allocation failed\n");
483                 return;
484         }
485
486         return;
487 }
488
489 static void __bt_adapter_visibility_changed_cb(int result,
490                                 bt_adapter_visibility_mode_e visibility_mode, void *user_data)
491 {
492         DBG("+\n");
493
494         int ret;
495         int duration;
496         bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
497
498         ret = bt_adapter_get_visibility(&mode, &duration);
499         if (ret != BT_ERROR_NONE) {
500                 ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
501         }
502
503         if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
504                         ERR("_launch_toast_popup() is failed\n");
505         }
506
507         DBG("-\n");
508 }
509
510 static void __handle_bt_adapter_visibility()
511 {
512         DBG("+\n");
513
514         int ret;
515         int duration;
516         bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
517
518         ret = bt_adapter_get_visibility(&mode, &duration);
519         if (ret != BT_ERROR_NONE) {
520                 ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
521         }
522
523         if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
524                 ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE, 120);
525                 if (ret != BT_ERROR_NONE) {
526                         ERR("bt_adapter_set_visibility is failed 0x[%X]\n", ret);
527                 }
528         }
529         bt_adapter_set_visibility_mode_changed_cb(__bt_adapter_visibility_changed_cb, NULL);
530         DBG("-\n");
531 }
532
533 gboolean tethering_enable_bt_tethering(Tethering *obj,
534                 GDBusMethodInvocation *context)
535 {
536         mobile_ap_error_code_e ret;
537         gboolean ret_val = FALSE;
538
539         DBG("+\n");
540
541         g_assert(obj != NULL);
542         g_assert(context != NULL);
543
544         if (g_context) {
545                 DBG("It is turnning on\n");
546                 tethering_complete_enable_bt_tethering(obj, context,
547                                 MOBILE_AP_ERROR_IN_PROGRESS);
548                 return FALSE;
549         }
550
551         g_context = context;
552
553         _block_device_sleep();
554
555         ret = __init_bt(obj);
556         if (ret != MOBILE_AP_ERROR_NONE)
557                 goto DONE;
558
559         if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
560                 ret = MOBILE_AP_ERROR_RESOURCE;
561                 __deinit_bt();
562                 goto DONE;
563         }
564
565         if (__is_bt_adapter_on() == FALSE) {
566                 DBG("Bluetooth is deactivated\n");
567                 if (__turn_on_bt_adapter((gpointer)obj) != MOBILE_AP_ERROR_NONE) {
568                         ERR("__turn_on_bt_adapter is failed\n");
569                         ret = MOBILE_AP_ERROR_INTERNAL;
570                         _mobileap_clear_state(MOBILE_AP_STATE_BT);
571                         __deinit_bt();
572                         goto DONE;
573                 }
574
575                 return TRUE;
576         }
577
578         ret = _enable_bt_tethering(obj);
579         if (ret != MOBILE_AP_ERROR_NONE) {
580                 ERR("_enable_bt_tethering() is failed : %d\n", ret);
581                 _mobileap_clear_state(MOBILE_AP_STATE_BT);
582                 __deinit_bt();
583         } else {
584                 tethering_emit_bluetooth_on(obj);
585                 _create_tethering_active_noti();
586                 __handle_bt_adapter_visibility();
587                 ret_val = TRUE;
588         }
589
590 DONE:
591         tethering_complete_enable_bt_tethering(obj, g_context, ret);
592         g_context = NULL;
593
594         _unblock_device_sleep();
595         DBG("-\n");
596         return ret_val;
597 }
598
599 gboolean tethering_disable_bt_tethering(Tethering *obj,
600                 GDBusMethodInvocation *context)
601 {
602         mobile_ap_error_code_e ret;
603
604         DBG("+\n");
605
606         g_assert(obj != NULL);
607         g_assert(context != NULL);
608
609         ret = _disable_bt_tethering(obj);
610         if (ret != MOBILE_AP_ERROR_NONE) {
611                 tethering_complete_disable_bt_tethering(obj, context,
612                                 MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
613                 return FALSE;
614         }
615
616         tethering_emit_bluetooth_off(obj, NULL);
617         tethering_complete_disable_bt_tethering(obj, context,
618                         MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
619         return TRUE;
620 }
621
622 gboolean _is_trying_bt_operation(void)
623 {
624         return (g_context ? TRUE : FALSE);
625 }