Prevent issues are fixed and unnecessary BT API call is removed
[framework/connectivity/mobileap-agent.git] / src / mobileap_bluetooth.c
1 /*
2  * mobileap-agent
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hocheol Seo <hocheol.seo@samsung.com>,
7  *          Injun Yang <injun.yang@samsung.com>,
8  *          Seungyoun Ju <sy39.ju@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * 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 <stdio.h>
25 #include <glib.h>
26 #include <dbus/dbus.h>
27 #include <dbus/dbus-glib.h>
28 #include <dbus/dbus-glib-lowlevel.h>
29 #include <bluetooth.h>
30
31 #include "mobileap_agent.h"
32 #include "mobileap_common.h"
33 #include "mobileap_bluetooth.h"
34
35 typedef struct {
36         bt_device_info_s *info;
37         char *intf_name;
38         const in_addr_t intf_ip;
39 } __bt_remote_device_s;
40
41 static __bt_remote_device_s __bt_remote_devices[MOBILE_AP_MAX_BT_STA] = {
42         {NULL, NULL, IP_ADDRESS_BT_1},
43         {NULL, NULL, IP_ADDRESS_BT_2},
44         {NULL, NULL, IP_ADDRESS_BT_3},
45         {NULL, NULL, IP_ADDRESS_BT_4},
46         {NULL, NULL, IP_ADDRESS_BT_5},
47         {NULL, NULL, IP_ADDRESS_BT_6},
48         {NULL, NULL, IP_ADDRESS_BT_7}};
49
50 static __bt_remote_device_s *__find_bt_remote(const char *mac)
51 {
52         int i;
53
54         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
55                 if (__bt_remote_devices[i].info == NULL)
56                         continue;
57
58                 if (!g_ascii_strcasecmp(__bt_remote_devices[i].info->remote_address, mac))
59                         break;
60         }
61
62         if (i == MOBILE_AP_MAX_BT_STA) {
63                 ERR("Not found : %s\n", mac);
64                 return NULL;
65         }
66
67         return &__bt_remote_devices[i];
68 }
69
70 static __bt_remote_device_s *__add_bt_remote(bt_device_info_s *info, const char *intf_name)
71 {
72         int i;
73
74         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
75                 if (__bt_remote_devices[i].info == NULL)
76                         break;
77         }
78
79         if (i == MOBILE_AP_MAX_BT_STA) {
80                 ERR("Too many BT devices are connected\n");
81                 return NULL;
82         }
83
84         __bt_remote_devices[i].intf_name = g_strdup(intf_name);
85         if (__bt_remote_devices[i].intf_name == NULL) {
86                 ERR("Memory allocation failed\n");
87                 return NULL;
88         }
89
90         __bt_remote_devices[i].info = info;
91
92         return &__bt_remote_devices[i];
93 }
94
95 static gboolean __del_bt_remote(const char *mac)
96 {
97         int i;
98
99         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
100                 if (__bt_remote_devices[i].info == NULL)
101                         continue;
102
103                 if (!g_ascii_strcasecmp(__bt_remote_devices[i].info->remote_address, mac))
104                         break;
105         }
106
107         if (i == MOBILE_AP_MAX_BT_STA) {
108                 ERR("Not found : %s\n", mac);
109                 return FALSE;
110         }
111
112          bt_adapter_free_device_info(__bt_remote_devices[i].info);
113          g_free(__bt_remote_devices[i].intf_name);
114
115          __bt_remote_devices[i].info = NULL;
116          __bt_remote_devices[i].intf_name = NULL;
117
118         return TRUE;
119 }
120
121 static void __del_bt_remote_all(void)
122 {
123         int i;
124
125         for (i = 0; i < MOBILE_AP_MAX_BT_STA; i++) {
126                 if (__bt_remote_devices[i].info) {
127                         bt_adapter_free_device_info(__bt_remote_devices[i].info);
128                         __bt_remote_devices[i].info = NULL;
129                 }
130
131                 if (__bt_remote_devices[i].intf_name) {
132                         g_free(__bt_remote_devices[i].intf_name);
133                         __bt_remote_devices[i].intf_name = NULL;
134                 }
135         }
136
137         return;
138 }
139
140 static void __bt_nap_connection_changed(bool connected, const char *remote_address, const char *interface_name, void *user_data)
141 {
142         if (remote_address == NULL || interface_name == NULL || user_data == NULL) {
143                 ERR("Invalid param\n");
144                 return;
145         }
146
147         __bt_remote_device_s *remote;
148         bt_device_info_s *info;
149         int ret;
150
151         DBG("Remote address : %s, Interface : %s, %s\n",
152                         remote_address, interface_name,
153                         connected ? "Connected" : "Disconnected");
154
155         if (connected) {
156                 ret = bt_adapter_get_bonded_device_info(remote_address, &info);
157                 if (ret != BT_ERROR_NONE) {
158                         ERR("bt_adapter_get_bonded_device_info is failed : %d\n", ret);
159                         return;
160                 }
161
162                 remote = __add_bt_remote(info, interface_name);
163                 if (remote == NULL) {
164                         ERR("__add_bt_remote is failed\n");
165                          bt_adapter_free_device_info(info);
166                         return;
167                 }
168
169                 ret = _mh_core_set_ip_address(interface_name, remote->intf_ip);
170                 if (ret != MOBILE_AP_ERROR_NONE) {
171                         ERR("Setting ip address error : %d\n", ret);
172                 }
173         } else {
174                 _remove_station_info(remote_address, _slist_find_station_by_mac);
175                 if (__del_bt_remote(remote_address) == FALSE)
176                         ERR("__del_bt_remote is failed\n");
177         }
178
179         return;
180 }
181
182 static mobile_ap_error_code_e __activate_bt_nap(MobileAPObject *obj)
183 {
184         int bt_ret = BT_ERROR_NONE;
185
186         bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
187         if (bt_ret != BT_ERROR_NONE) {
188                 ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
189                 return MOBILE_AP_ERROR_RESOURCE;
190         }
191
192         bt_ret = bt_nap_activate();
193         if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
194                 bt_nap_unset_connection_state_changed_cb();
195                 ERR("bt_nap_activate is failed : %d\n", bt_ret);
196                 return MOBILE_AP_ERROR_RESOURCE;
197         }
198
199         return MOBILE_AP_ERROR_NONE;
200 }
201
202 static void __deactivate_bt_nap(void)
203 {
204         int bt_ret;
205
206         bt_ret = bt_nap_deactivate();
207         if (bt_ret != BT_ERROR_NONE)
208                 ERR("bt_nap_deactivate is failed : %d\n", bt_ret);
209
210         bt_ret = bt_nap_unset_connection_state_changed_cb();
211         if (bt_ret != BT_ERROR_NONE)
212                 ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
213
214         return;
215 }
216
217 static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data)
218 {
219         if (user_data == NULL) {
220                 ERR("Invalid param\n");
221                 return;
222         }
223
224         if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT))
225                 return;
226
227         int ret;
228         MobileAPObject *obj = (MobileAPObject *)user_data;
229         DBusGMethodInvocation *context = obj->bt_context;
230
231         obj->bt_context = NULL;
232         if (result != BT_ERROR_NONE) {
233                 ERR("BT Adapter operation is failed : %d\n", result);
234                 if (context) {
235                         ret = MOBILE_AP_ERROR_RESOURCE;
236                         dbus_g_method_return(context,
237                                         MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
238                         _mobileap_clear_state(MOBILE_AP_STATE_BT);
239                 }
240                 return;
241         }
242
243         DBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
244                         "enabled" : "disabled");
245         if (adapter_state == BT_ADAPTER_DISABLED) {
246                 _disable_bt_tethering(obj);
247                 _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_OFF,
248                                 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
249                 return;
250         }
251
252         ret = __activate_bt_nap(obj);
253         if (ret != MOBILE_AP_ERROR_NONE) {
254                 bt_adapter_unset_state_changed_cb();
255                 bt_deinitialize();
256                 _deinit_tethering(obj);
257                 dbus_g_method_return(context,
258                                 MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
259                 _mobileap_clear_state(MOBILE_AP_STATE_BT);
260                 return;
261         }
262
263         _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
264         if (context)
265                 dbus_g_method_return(context,
266                                 MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
267         return;
268 }
269
270 void _bt_get_remote_device_name(MobileAPObject *obj, const char *mac, char **name)
271 {
272         if (obj == NULL || mac == NULL || name == NULL) {
273                 ERR("Invalid param\n");
274                 return;
275         }
276
277         __bt_remote_device_s *remote = NULL;
278
279         remote = __find_bt_remote(mac);
280         if (remote == NULL)
281                 return;
282
283         *name = g_strdup(remote->info->remote_name);
284         if (*name == NULL) {
285                 ERR("Memory allocation failed\n");
286                 return;
287         }
288
289         return;
290 }
291
292 mobile_ap_error_code_e _disable_bt_tethering(MobileAPObject *obj)
293 {
294         int bt_ret;
295
296         if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
297                 ERR("BT tethering has not been enabled\n");
298                 return MOBILE_AP_ERROR_NOT_ENABLED;
299         }
300
301         __deactivate_bt_nap();
302
303         bt_ret = bt_adapter_unset_state_changed_cb();
304         if (bt_ret != BT_ERROR_NONE)
305                 ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", bt_ret);
306
307         bt_ret = bt_deinitialize();
308         if (bt_ret != BT_ERROR_NONE)
309                 ERR("bt_deinitialize is failed : %d\n", bt_ret);
310
311         _remove_station_info_all(MOBILE_AP_TYPE_BT);
312         __del_bt_remote_all();
313
314         _deinit_tethering(obj);
315         _mobileap_clear_state(MOBILE_AP_STATE_BT);
316
317         return MOBILE_AP_ERROR_NONE;
318 }
319
320 gboolean mobileap_enable_bt_tethering(MobileAPObject *obj,
321                 DBusGMethodInvocation *context)
322 {
323         int ret;
324         int bt_ret;
325         bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
326
327         DBG("+\n");
328
329         g_assert(obj != NULL);
330         g_assert(context != NULL);
331
332
333         if (_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
334                 ERR("Bluetooth tethering is already enabled\n");
335                 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
336                 dbus_g_method_return(context,
337                                 MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
338                 return FALSE;
339         }
340
341         if (obj->bt_context != NULL) {
342                 ERR("Bluetooth tethering request is progressing\n");
343                 ret = MOBILE_AP_ERROR_IN_PROGRESS;
344                 dbus_g_method_return(context,
345                                 MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
346                 return FALSE;
347         }
348
349         if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
350                 ret = MOBILE_AP_ERROR_RESOURCE;
351                 goto FAIL;
352         }
353
354         if (!_init_tethering(obj)) {
355                 ret = MOBILE_AP_ERROR_RESOURCE;
356                 goto FAIL;
357         }
358
359         bt_ret = bt_initialize();
360         if (bt_ret != BT_ERROR_NONE) {
361                 ERR("bt_initialize is failed : %d\n", bt_ret);
362                 _deinit_tethering(obj);
363                 ret = MOBILE_AP_ERROR_RESOURCE;
364                 goto FAIL;
365         }
366
367         bt_ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
368         if (bt_ret != BT_ERROR_NONE) {
369                 ERR("bt_adapter_set_state_changed_cb is failed : %d\n", bt_ret);
370                 bt_deinitialize();
371                 _deinit_tethering(obj);
372                 ret = MOBILE_AP_ERROR_RESOURCE;
373                 goto FAIL;
374         }
375
376         bt_ret = bt_adapter_get_state(&adapter_state);
377         if (bt_ret != BT_ERROR_NONE) {
378                 ERR("bt_adapter_get_state is failed : %d\n", bt_ret);
379                 bt_adapter_unset_state_changed_cb();
380                 bt_deinitialize();
381                 _deinit_tethering(obj);
382                 ret = MOBILE_AP_ERROR_RESOURCE;
383                 goto FAIL;
384         }
385
386         if (adapter_state == BT_ADAPTER_DISABLED) {
387                 bt_ret = bt_adapter_enable();
388                 if (bt_ret != BT_ERROR_NONE) {
389                         ERR("bt_adapter_enable is failed : %d\n", bt_ret);
390                         bt_adapter_unset_state_changed_cb();
391                         bt_deinitialize();
392                         _deinit_tethering(obj);
393                         ret = MOBILE_AP_ERROR_RESOURCE;
394                         goto FAIL;
395                 }
396                 obj->bt_context = context;
397                 return TRUE;
398         }
399
400         ret = __activate_bt_nap(obj);
401         if (ret != MOBILE_AP_ERROR_NONE) {
402                 bt_adapter_unset_state_changed_cb();
403                 bt_deinitialize();
404                 _deinit_tethering(obj);
405                 ret = MOBILE_AP_ERROR_RESOURCE;
406                 goto FAIL;
407         }
408
409         _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
410         dbus_g_method_return(context, MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
411         return TRUE;
412
413 FAIL:
414         _mobileap_clear_state(MOBILE_AP_STATE_BT);
415         dbus_g_method_return(context, MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
416         return FALSE;
417 }
418
419
420 gboolean mobileap_disable_bt_tethering(MobileAPObject *obj,
421                 DBusGMethodInvocation *context)
422 {
423         mobile_ap_error_code_e ret;
424
425         DBG("+\n");
426
427         g_assert(obj != NULL);
428         g_assert(context != NULL);
429
430         ret = _disable_bt_tethering(obj);
431         if (ret != MOBILE_AP_ERROR_NONE) {
432                 dbus_g_method_return(context, MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
433                 return FALSE;
434         }
435
436         _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_OFF, NULL);
437         dbus_g_method_return(context, MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
438         return TRUE;
439 }