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