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