3.0 specific patch: enable to build after tizen 2.4 code sync.
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-network.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@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 <glib.h>
25 #include <gio/gio.h>
26 #include <dlog.h>
27 #include <string.h>
28 #include <stdio.h>
29 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
30 #include <syspopup_caller.h>
31 #endif
32 #include <net_connection.h>
33
34 #include "bluetooth-api.h"
35 #include "bt-service-network.h"
36 #include "bt-service-common.h"
37 #include "bt-service-event.h"
38 #include "bt-service-util.h"
39 #include "bt-internal-types.h"
40
41 void _bt_util_addr_type_to_addr_net_string(char *address,
42                                         unsigned char *addr)
43 {
44         ret_if(address == NULL);
45         ret_if(addr == NULL);
46
47         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
48                         addr[1], addr[2], addr[3], addr[4], addr[5]);
49 }
50
51 static connection_profile_h __bt_get_net_profile(void *connection,
52                                                 connection_iterator_type_e type,
53                                                 unsigned char *address)
54 {
55         int result;
56         gchar **split_string;
57         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
58         char *profile_name = NULL;
59         connection_profile_iterator_h profile_iter;
60         connection_profile_h profile_h;
61         connection_profile_type_e profile_type;
62
63         retv_if(connection == NULL, NULL);
64         retv_if(address == NULL, NULL);
65
66         BT_DBG("net_conn: %x", connection);
67
68         _bt_util_addr_type_to_addr_net_string(net_address, address);
69
70         result = connection_get_profile_iterator(connection,
71                                                         type,
72                                                         &profile_iter);
73         if (result != CONNECTION_ERROR_NONE) {
74                 BT_ERR("Fail to get profile iterator [%d]", result);
75                 return NULL;
76         }
77
78         while (connection_profile_iterator_has_next(profile_iter)) {
79                         profile_name = NULL;
80                         profile_h = NULL;
81                         split_string = NULL;
82
83                         if (connection_profile_iterator_next(profile_iter,
84                                                 &profile_h) != CONNECTION_ERROR_NONE) {
85                                 BT_ERR("Fail to get profile handle");
86                                 return NULL;
87                         }
88
89                         if (connection_profile_get_type(profile_h,
90                                                 &profile_type) != CONNECTION_ERROR_NONE) {
91                                 BT_ERR("Fail to get profile type");
92                                 continue;
93                         }
94
95                         if (profile_type != CONNECTION_PROFILE_TYPE_BT)
96                                 continue;
97
98                         if (connection_profile_get_name(profile_h,
99                                                 &profile_name) != CONNECTION_ERROR_NONE) {
100                                 BT_ERR("Fail to get profile name");
101                                 return NULL;
102                         }
103
104                         split_string = g_strsplit(profile_name, "_", 3);
105
106                         g_free(profile_name);
107
108                         if (g_strv_length(split_string) < 3)
109                                 continue;
110
111                         if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
112                                 BT_DBG("matched profile");
113                                 g_strfreev(split_string);
114                                 return profile_h;
115                         }
116
117                         g_strfreev(split_string);
118         }
119
120         return NULL;
121 }
122
123 int _bt_is_network_connected(void *connection, unsigned char *address,
124                                         gboolean *is_connected)
125 {
126         void *handle = NULL;
127         handle = __bt_get_net_profile(connection,
128                                 CONNECTION_ITERATOR_TYPE_CONNECTED,
129                                 address);
130         if(handle)
131                 *is_connected = TRUE;
132         else
133                 *is_connected = FALSE;
134
135         return BLUETOOTH_ERROR_NONE;
136 }
137
138 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
139                                         gpointer user_data)
140 {
141         GError *g_error = NULL;
142         GVariant *out_param1 = NULL;
143         GVariant *reply = NULL;
144         bluetooth_device_address_t device_addr = { {0} };
145         int result = BLUETOOTH_ERROR_NONE;
146         bt_function_data_t *func_data;
147         request_info_t *req_info;
148
149         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
150         g_object_unref(proxy);
151
152         if (reply == NULL) {
153                 BT_ERR("Network Connect Dbus Call Error");
154                 if (g_error) {
155                         BT_ERR("Error: %s\n", g_error->message);
156                         g_clear_error(&g_error);
157                 }
158                 result = BLUETOOTH_ERROR_INTERNAL;
159         }
160         g_variant_unref(reply);
161
162         func_data = user_data;
163         if (func_data == NULL) {
164                 /* Send reply */
165                 BT_ERR("func_data == NULL");
166                 goto done;
167         }
168
169         BT_ERR("func_data->req_id: %d", func_data->req_id);
170         req_info = _bt_get_request_info(func_data->req_id);
171         if (req_info == NULL) {
172                 BT_ERR("req_info == NULL");
173                 goto done;
174         }
175
176         if (req_info->context == NULL)
177                 goto done;
178
179         _bt_convert_addr_string_to_type(device_addr.addr,
180                                         func_data->address);
181
182         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
183                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
184
185         g_dbus_method_invocation_return_value(req_info->context,
186                         g_variant_new("iv", result, out_param1));
187
188         _bt_delete_request_list(req_info->req_id);
189
190 done:
191         if (func_data) {
192                 g_free(func_data->address);
193                 g_free(func_data);
194         }
195 }
196
197 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
198                                         gpointer user_data)
199 {
200         GError *g_error = NULL;
201         GVariant *out_param1 = NULL;
202         GVariant *reply = NULL;
203         bluetooth_device_address_t device_addr = { {0} };
204         int result = BLUETOOTH_ERROR_NONE;
205         bt_function_data_t *func_data;
206         request_info_t *req_info;
207
208         g_dbus_proxy_call_finish(proxy, res, &g_error);
209         g_object_unref(proxy);
210
211         if (reply == NULL) {
212                 BT_ERR("Network Disconnect Dbus Call Error");
213                 if (g_error) {
214                         BT_ERR("Error: %s\n", g_error->message);
215                         g_clear_error(&g_error);
216                 }
217                 result = BLUETOOTH_ERROR_INTERNAL;
218         }
219         g_variant_unref(reply);
220
221         func_data = user_data;
222         if (func_data == NULL) {
223                 /* Send reply */
224                 BT_ERR("func_data == NULL");
225                 goto done;
226         }
227         BT_ERR("func_data->req_id: %d", func_data->req_id);
228         req_info = _bt_get_request_info(func_data->req_id);
229         if (req_info == NULL) {
230                 BT_ERR("req_info == NULL");
231                 goto done;
232         }
233
234         if (g_error != NULL) {
235                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
236                 result = BLUETOOTH_ERROR_INTERNAL;
237         }
238
239         if (req_info->context == NULL)
240                 goto done;
241
242         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
243                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
244
245         g_dbus_method_invocation_return_value(req_info->context,
246                         g_variant_new("iv", result, out_param1));
247
248         _bt_delete_request_list(req_info->req_id);
249
250 done:
251         if (func_data) {
252                 g_free(func_data->address);
253                 g_free(func_data);
254         }
255 }
256
257 int _bt_network_activate(void)
258 {
259         int ret = BLUETOOTH_ERROR_NONE;
260         char *adapter_path;
261         GError *err = NULL;
262         GDBusConnection *conn;
263         GDBusProxy *server_proxy;
264
265         conn = _bt_get_system_gconn();
266         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
267
268         adapter_path = _bt_get_adapter_path();
269         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
270
271         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
272                         NULL, BT_BLUEZ_NAME,
273                         adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
274         g_free(adapter_path);
275
276         if (server_proxy == NULL) {
277                 BT_ERR("Failed to get the network server proxy\n");
278                 return BLUETOOTH_ERROR_INTERNAL;
279         }
280
281         g_dbus_proxy_call_sync(server_proxy, "Register",
282                                  g_variant_new("(ss)", NAP_UUID_NAME, NET_BRIDGE_INTERFACE),
283                                  G_DBUS_CALL_FLAGS_NONE,
284                                  -1,
285                                  NULL,
286                                  &err);
287         if (err != NULL) {
288                 BT_ERR("Network server register Error: %s\n", err->message);
289                 if (g_strcmp0(err->message, "Already Exists") == 0) {
290                         ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
291                 } else {
292                         ret = BLUETOOTH_ERROR_INTERNAL;
293                 }
294                 g_error_free(err);
295         }
296         g_object_unref(server_proxy);
297
298         return ret;
299 }
300
301 int _bt_network_deactivate(void)
302 {
303         char *adapter_path;
304         GError *err = NULL;
305         GDBusConnection *conn;
306         GDBusProxy *server_proxy;
307         int ret = BLUETOOTH_ERROR_NONE;
308
309         conn = _bt_get_system_gconn();
310         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
311
312         adapter_path = _bt_get_adapter_path();
313         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
314
315         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
316                                                                 NULL, BT_BLUEZ_NAME,
317                                                                 adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
318         g_free(adapter_path);
319
320         if (server_proxy == NULL) {
321                 BT_ERR("Failed to get the network server proxy\n");
322                 return BLUETOOTH_ERROR_INTERNAL;
323         }
324
325         g_dbus_proxy_call_sync(server_proxy, "Unregister",
326                                  g_variant_new("(s)", NAP_UUID_NAME),
327                                  G_DBUS_CALL_FLAGS_NONE,
328                                  -1,
329                                  NULL,
330                                  &err);
331         if (err != NULL) {
332                 BT_ERR("Network server unregister Error: %s\n", err->message);
333                 if (g_strcmp0(err->message,
334                                 "Operation currently not available") == 0) {
335                         ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
336                 } else {
337                         ret = BLUETOOTH_ERROR_INTERNAL;
338                 }
339                 g_error_free(err);
340         }
341         g_object_unref(server_proxy);
342
343         return ret;
344 }
345
346 int _bt_network_connect(int request_id, int role,
347                 bluetooth_device_address_t *device_address)
348 {
349         const gchar *device_path = NULL;
350         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
351         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
352         bt_function_data_t *func_data;
353         GDBusProxy *adapter_proxy;
354         GDBusProxy *profile_proxy;
355         GDBusConnection *conn;
356         GVariant *result = NULL;
357         GError*err = NULL;
358
359         BT_CHECK_PARAMETER(device_address, return);
360
361         switch (role) {
362         case BLUETOOTH_NETWORK_PANU_ROLE:
363                 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
364                 break;
365
366         case BLUETOOTH_NETWORK_NAP_ROLE:
367                 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
368                 break;
369
370         case BLUETOOTH_NETWORK_GN_ROLE:
371                 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
372                 break;
373         default:
374                 BT_ERR("Unknown role");
375                 return BLUETOOTH_ERROR_INTERNAL;
376         }
377
378         adapter_proxy = _bt_get_adapter_proxy();
379         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
380
381         conn = _bt_get_system_gconn();
382         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
383
384         _bt_convert_addr_type_to_string(address, device_address->addr);
385
386         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
387                         g_variant_new("(s)", address),
388                         G_DBUS_CALL_FLAGS_NONE,
389                         -1, NULL, &err);
390         if (result == NULL) {
391                 BT_ERR("Error occurred in call to FindDevice");
392                 if (err) {
393                         BT_ERR("Error: %s", err->message);
394                         g_clear_error(&err);
395                 }
396                 return BLUETOOTH_ERROR_INTERNAL;
397         }
398
399         device_path =  g_variant_get_string(result, NULL);
400         if (device_path == NULL) {
401                 BT_ERR("No paired device");
402                 g_variant_unref(result);
403                 return BLUETOOTH_ERROR_NOT_PAIRED;
404         }
405
406         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
407                         NULL, BT_BLUEZ_NAME,
408                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
409
410         g_variant_unref(result);
411         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
412         func_data = g_malloc0(sizeof(bt_function_data_t));
413
414         func_data->address = g_strdup(address);
415         func_data->req_id = request_id;
416
417         g_dbus_proxy_call(profile_proxy, "Connect",
418                                 g_variant_new("(s)", remote_role),
419                                 G_DBUS_CALL_FLAGS_NONE,
420                                 BT_MAX_DBUS_TIMEOUT,
421                                 NULL,
422                                 (GAsyncReadyCallback)__bt_network_connect_cb,
423                                 func_data);
424
425         return BLUETOOTH_ERROR_NONE;
426 }
427
428 int _bt_network_disconnect(int request_id,
429                 bluetooth_device_address_t *device_address)
430 {
431         const gchar *device_path = NULL;
432         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
433         bt_function_data_t *func_data;
434         GDBusProxy *adapter_proxy;
435         GDBusProxy *profile_proxy;
436         GDBusConnection *conn;
437         GVariant *result = NULL;
438         GError*err = NULL;
439
440         BT_CHECK_PARAMETER(device_address, return);
441
442         adapter_proxy = _bt_get_adapter_proxy();
443         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
444
445         conn = _bt_get_system_gconn();
446         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
447
448         _bt_convert_addr_type_to_string(address, device_address->addr);
449
450         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
451                                  g_variant_new("(s)", address),
452                                  G_DBUS_CALL_FLAGS_NONE,
453                                  -1, NULL, &err);
454         if (result == NULL) {
455                 BT_ERR("Error occurred in call to FindDevice");
456                 if (err) {
457                         BT_ERR("Error: %s", err->message);
458                         g_clear_error(&err);
459                 }
460                 return BLUETOOTH_ERROR_INTERNAL;
461         }
462
463         device_path =  g_variant_get_string(result, NULL);
464         if (device_path == NULL) {
465                 BT_ERR("No paired device");
466                 return BLUETOOTH_ERROR_NOT_PAIRED;
467         }
468
469         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
470                         NULL, BT_BLUEZ_NAME,
471                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
472
473         g_variant_unref(result);
474         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
475         func_data = g_malloc0(sizeof(bt_function_data_t));
476
477         func_data->address = g_strdup(address);
478         func_data->req_id = request_id;
479
480         g_dbus_proxy_call(profile_proxy, "Disconnect",
481                         NULL,
482                         G_DBUS_CALL_FLAGS_NONE,
483                         BT_MAX_DBUS_TIMEOUT,
484                         NULL,
485                         (GAsyncReadyCallback)__bt_network_disconnect_cb,
486                         func_data);
487
488         return BLUETOOTH_ERROR_NONE;
489 }
490
491 int _bt_network_server_disconnect(int request_id,
492                 bluetooth_device_address_t *device_address)
493 {
494         gchar *adapter_path = NULL;
495         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
496         bt_function_data_t *func_data;
497         GDBusProxy *profile_proxy;
498         GDBusConnection *conn;
499
500         BT_CHECK_PARAMETER(device_address, return);
501
502         conn = _bt_get_system_gconn();
503         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
504
505         adapter_path = _bt_get_adapter_path();
506         if (adapter_path == NULL) {
507                 BT_ERR("No adapter found");
508                 return BLUETOOTH_ERROR_INTERNAL;
509         }
510
511         _bt_convert_addr_type_to_string(address, device_address->addr);
512
513         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
514                         NULL, BT_BLUEZ_NAME,
515                         adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
516         g_free(adapter_path);
517         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
518         func_data = g_malloc0(sizeof(bt_function_data_t));
519
520         func_data->address = g_strdup(address);
521         func_data->req_id = request_id;
522
523         g_dbus_proxy_call(profile_proxy, "Disconnect",
524                                  g_variant_new("(s)", address),
525                                 G_DBUS_CALL_FLAGS_NONE,
526                                 BT_MAX_DBUS_TIMEOUT,
527                                 NULL,
528                                 (GAsyncReadyCallback)__bt_network_disconnect_cb,
529                                 func_data);
530
531         g_free(func_data->address);
532         g_free(func_data);
533
534         return BLUETOOTH_ERROR_NONE;
535 }