Merge the code from tizen_2.4
[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         reply = 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                 g_dbus_error_strip_remote_error(err);
289                 BT_ERR("Network server register Error: %s\n", err->message);
290                 if (g_strcmp0(err->message, "Already Exists") == 0) {
291                         ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
292                 } else {
293                         ret = BLUETOOTH_ERROR_INTERNAL;
294                 }
295                 g_error_free(err);
296         }
297         g_object_unref(server_proxy);
298
299         return ret;
300 }
301
302 int _bt_network_deactivate(void)
303 {
304         char *adapter_path;
305         GError *err = NULL;
306         GDBusConnection *conn;
307         GDBusProxy *server_proxy;
308         int ret = BLUETOOTH_ERROR_NONE;
309
310         conn = _bt_get_system_gconn();
311         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
312
313         adapter_path = _bt_get_adapter_path();
314         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
315
316         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
317                                                                 NULL, BT_BLUEZ_NAME,
318                                                                 adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
319         g_free(adapter_path);
320
321         if (server_proxy == NULL) {
322                 BT_ERR("Failed to get the network server proxy\n");
323                 return BLUETOOTH_ERROR_INTERNAL;
324         }
325
326         g_dbus_proxy_call_sync(server_proxy, "Unregister",
327                                  g_variant_new("(s)", NAP_UUID_NAME),
328                                  G_DBUS_CALL_FLAGS_NONE,
329                                  -1,
330                                  NULL,
331                                  &err);
332         if (err != NULL) {
333                 g_dbus_error_strip_remote_error(err);
334                 BT_ERR("Network server unregister Error: %s\n", err->message);
335                 if (g_strcmp0(err->message,
336                                 "Operation currently not available") == 0) {
337                         ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
338                 } else {
339                         ret = BLUETOOTH_ERROR_INTERNAL;
340                 }
341                 g_error_free(err);
342         }
343         g_object_unref(server_proxy);
344
345         return ret;
346 }
347
348 int _bt_network_connect(int request_id, int role,
349                 bluetooth_device_address_t *device_address)
350 {
351         const gchar *device_path = NULL;
352         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
353         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
354         bt_function_data_t *func_data;
355         GDBusProxy *adapter_proxy;
356         GDBusProxy *profile_proxy;
357         GDBusConnection *conn;
358         GVariant *result = NULL;
359         GError*err = NULL;
360
361         BT_CHECK_PARAMETER(device_address, return);
362
363         switch (role) {
364         case BLUETOOTH_NETWORK_PANU_ROLE:
365                 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
366                 break;
367
368         case BLUETOOTH_NETWORK_NAP_ROLE:
369                 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
370                 break;
371
372         case BLUETOOTH_NETWORK_GN_ROLE:
373                 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
374                 break;
375         default:
376                 BT_ERR("Unknown role");
377                 return BLUETOOTH_ERROR_INTERNAL;
378         }
379
380         adapter_proxy = _bt_get_adapter_proxy();
381         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
382
383         conn = _bt_get_system_gconn();
384         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
385
386         _bt_convert_addr_type_to_string(address, device_address->addr);
387
388         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
389                         g_variant_new("(s)", address),
390                         G_DBUS_CALL_FLAGS_NONE,
391                         -1, NULL, &err);
392         if (result == NULL) {
393                 BT_ERR("Error occurred in call to FindDevice");
394                 if (err) {
395                         BT_ERR("Error: %s", err->message);
396                         g_clear_error(&err);
397                 }
398                 return BLUETOOTH_ERROR_INTERNAL;
399         }
400
401         device_path =  g_variant_get_string(result, NULL);
402         if (device_path == NULL) {
403                 BT_ERR("No paired device");
404                 g_variant_unref(result);
405                 return BLUETOOTH_ERROR_NOT_PAIRED;
406         }
407
408         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
409                         NULL, BT_BLUEZ_NAME,
410                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
411
412         g_variant_unref(result);
413         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
414         func_data = g_malloc0(sizeof(bt_function_data_t));
415
416         func_data->address = g_strdup(address);
417         func_data->req_id = request_id;
418
419         g_dbus_proxy_call(profile_proxy, "Connect",
420                                 g_variant_new("(s)", remote_role),
421                                 G_DBUS_CALL_FLAGS_NONE,
422                                 BT_MAX_DBUS_TIMEOUT,
423                                 NULL,
424                                 (GAsyncReadyCallback)__bt_network_connect_cb,
425                                 func_data);
426
427         return BLUETOOTH_ERROR_NONE;
428 }
429
430 int _bt_network_disconnect(int request_id,
431                 bluetooth_device_address_t *device_address)
432 {
433         const gchar *device_path = NULL;
434         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
435         bt_function_data_t *func_data;
436         GDBusProxy *adapter_proxy;
437         GDBusProxy *profile_proxy;
438         GDBusConnection *conn;
439         GVariant *result = NULL;
440         GError*err = NULL;
441
442         BT_CHECK_PARAMETER(device_address, return);
443
444         adapter_proxy = _bt_get_adapter_proxy();
445         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
446
447         conn = _bt_get_system_gconn();
448         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
449
450         _bt_convert_addr_type_to_string(address, device_address->addr);
451
452         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
453                                  g_variant_new("(s)", address),
454                                  G_DBUS_CALL_FLAGS_NONE,
455                                  -1, NULL, &err);
456         if (result == NULL) {
457                 BT_ERR("Error occurred in call to FindDevice");
458                 if (err) {
459                         BT_ERR("Error: %s", err->message);
460                         g_clear_error(&err);
461                 }
462                 return BLUETOOTH_ERROR_INTERNAL;
463         }
464
465         device_path =  g_variant_get_string(result, NULL);
466         if (device_path == NULL) {
467                 BT_ERR("No paired device");
468                 return BLUETOOTH_ERROR_NOT_PAIRED;
469         }
470
471         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
472                         NULL, BT_BLUEZ_NAME,
473                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
474
475         g_variant_unref(result);
476         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
477         func_data = g_malloc0(sizeof(bt_function_data_t));
478
479         func_data->address = g_strdup(address);
480         func_data->req_id = request_id;
481
482         g_dbus_proxy_call(profile_proxy, "Disconnect",
483                         NULL,
484                         G_DBUS_CALL_FLAGS_NONE,
485                         BT_MAX_DBUS_TIMEOUT,
486                         NULL,
487                         (GAsyncReadyCallback)__bt_network_disconnect_cb,
488                         func_data);
489
490         return BLUETOOTH_ERROR_NONE;
491 }
492
493 int _bt_network_server_disconnect(int request_id,
494                 bluetooth_device_address_t *device_address)
495 {
496         gchar *adapter_path = NULL;
497         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
498         bt_function_data_t *func_data;
499         GDBusProxy *profile_proxy;
500         GDBusConnection *conn;
501
502         BT_CHECK_PARAMETER(device_address, return);
503
504         conn = _bt_get_system_gconn();
505         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
506
507         adapter_path = _bt_get_adapter_path();
508         if (adapter_path == NULL) {
509                 BT_ERR("No adapter found");
510                 return BLUETOOTH_ERROR_INTERNAL;
511         }
512
513         _bt_convert_addr_type_to_string(address, device_address->addr);
514
515         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
516                         NULL, BT_BLUEZ_NAME,
517                         adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
518         g_free(adapter_path);
519         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
520         func_data = g_malloc0(sizeof(bt_function_data_t));
521
522         func_data->address = g_strdup(address);
523         func_data->req_id = request_id;
524
525         g_dbus_proxy_call(profile_proxy, "Disconnect",
526                                  g_variant_new("(s)", address),
527                                 G_DBUS_CALL_FLAGS_NONE,
528                                 BT_MAX_DBUS_TIMEOUT,
529                                 NULL,
530                                 (GAsyncReadyCallback)__bt_network_disconnect_cb,
531                                 func_data);
532
533         return BLUETOOTH_ERROR_NONE;
534 }