Add the sender name in signal subscribe function
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-network.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <syspopup_caller.h>
24 #include <net_connection.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-service-network.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-util.h"
31 #include "bt-internal-types.h"
32
33 void _bt_util_addr_type_to_addr_net_string(char *address,
34                                         unsigned char *addr)
35 {
36         ret_if(address == NULL);
37         ret_if(addr == NULL);
38
39         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
40                         addr[1], addr[2], addr[3], addr[4], addr[5]);
41 }
42
43 static connection_profile_h __bt_get_net_profile(void *connection,
44                                                 connection_iterator_type_e type,
45                                                 unsigned char *address)
46 {
47         int result;
48         gchar **split_string;
49         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
50         char *profile_name = NULL;
51         connection_profile_iterator_h profile_iter;
52         connection_profile_h profile_h;
53         connection_profile_type_e profile_type;
54
55         retv_if(connection == NULL, NULL);
56         retv_if(address == NULL, NULL);
57
58         BT_DBG("net_conn: %x", connection);
59
60         _bt_util_addr_type_to_addr_net_string(net_address, address);
61
62         result = connection_get_profile_iterator(connection,
63                                                         type,
64                                                         &profile_iter);
65         if (result != CONNECTION_ERROR_NONE) {
66                 BT_ERR("Fail to get profile iterator [%d]", result);
67                 return NULL;
68         }
69
70         while (connection_profile_iterator_has_next(profile_iter)) {
71                         profile_name = NULL;
72                         profile_h = NULL;
73                         split_string = NULL;
74
75                         if (connection_profile_iterator_next(profile_iter,
76                                                 &profile_h) != CONNECTION_ERROR_NONE) {
77                                 BT_ERR("Fail to get profile handle");
78                                 return NULL;
79                         }
80
81                         if (connection_profile_get_type(profile_h,
82                                                 &profile_type) != CONNECTION_ERROR_NONE) {
83                                 BT_ERR("Fail to get profile type");
84                                 continue;
85                         }
86
87                         if (profile_type != CONNECTION_PROFILE_TYPE_BT)
88                                 continue;
89
90                         if (connection_profile_get_name(profile_h,
91                                                 &profile_name) != CONNECTION_ERROR_NONE) {
92                                 BT_ERR("Fail to get profile name");
93                                 return NULL;
94                         }
95
96                         split_string = g_strsplit(profile_name, "_", 3);
97
98                         g_free(profile_name);
99
100                         if (g_strv_length(split_string) < 3)
101                                 continue;
102
103                         if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
104                                 BT_DBG("matched profile");
105                                 g_strfreev(split_string);
106                                 return profile_h;
107                         }
108
109                         g_strfreev(split_string);
110         }
111
112         return NULL;
113 }
114
115 int _bt_is_network_connected(void *connection, unsigned char *address,
116                                         gboolean *is_connected)
117 {
118         void *handle = NULL;
119         handle = __bt_get_net_profile(connection,
120                                 CONNECTION_ITERATOR_TYPE_CONNECTED,
121                                 address);
122         if (handle)
123                 *is_connected = TRUE;
124         else
125                 *is_connected = FALSE;
126
127         return BLUETOOTH_ERROR_NONE;
128 }
129
130 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
131                                         gpointer user_data)
132 {
133         GError *g_error = NULL;
134         GVariant *out_param1 = NULL;
135         GVariant *reply = NULL;
136         bluetooth_device_address_t device_addr = { {0} };
137         int result = BLUETOOTH_ERROR_NONE;
138         bt_function_data_t *func_data;
139         request_info_t *req_info;
140
141         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
142         g_object_unref(proxy);
143
144         if (reply == NULL) {
145                 BT_ERR("Network Connect Dbus Call Error");
146                 if (g_error) {
147                         BT_ERR("Error: %s\n", g_error->message);
148                         g_clear_error(&g_error);
149                 }
150                 result = BLUETOOTH_ERROR_INTERNAL;
151         }
152         g_variant_unref(reply);
153
154         func_data = user_data;
155         if (func_data == NULL) {
156                 /* Send reply */
157                 BT_ERR("func_data == NULL");
158                 goto done;
159         }
160
161         BT_ERR("func_data->req_id: %d", func_data->req_id);
162         req_info = _bt_get_request_info(func_data->req_id);
163         if (req_info == NULL) {
164                 BT_ERR("req_info == NULL");
165                 goto done;
166         }
167
168         if (req_info->context == NULL)
169                 goto done;
170
171         _bt_convert_addr_string_to_type(device_addr.addr,
172                                         func_data->address);
173
174         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
175                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
176
177         g_dbus_method_invocation_return_value(req_info->context,
178                         g_variant_new("iv", result, out_param1));
179
180         _bt_delete_request_list(req_info->req_id);
181
182 done:
183         if (func_data) {
184                 g_free(func_data->address);
185                 g_free(func_data);
186         }
187 }
188
189 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
190                                         gpointer user_data)
191 {
192         GError *g_error = NULL;
193         GVariant *out_param1 = NULL;
194         GVariant *reply = NULL;
195         bluetooth_device_address_t device_addr = { {0} };
196         int result = BLUETOOTH_ERROR_NONE;
197         bt_function_data_t *func_data;
198         request_info_t *req_info;
199
200         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
201         g_object_unref(proxy);
202
203         if (reply == NULL) {
204                 BT_ERR("Network Disconnect Dbus Call Error");
205                 if (g_error) {
206                         BT_ERR("Error: %s\n", g_error->message);
207                         g_clear_error(&g_error);
208                 }
209                 result = BLUETOOTH_ERROR_INTERNAL;
210         }
211         g_variant_unref(reply);
212
213         func_data = user_data;
214         if (func_data == NULL) {
215                 /* Send reply */
216                 BT_ERR("func_data == NULL");
217                 goto done;
218         }
219         BT_ERR("func_data->req_id: %d", func_data->req_id);
220         req_info = _bt_get_request_info(func_data->req_id);
221         if (req_info == NULL) {
222                 BT_ERR("req_info == NULL");
223                 goto done;
224         }
225
226         if (g_error != NULL) {
227                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
228                 result = BLUETOOTH_ERROR_INTERNAL;
229         }
230
231         if (req_info->context == NULL)
232                 goto done;
233
234         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
235                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
236
237         g_dbus_method_invocation_return_value(req_info->context,
238                         g_variant_new("iv", result, out_param1));
239
240         _bt_delete_request_list(req_info->req_id);
241
242 done:
243         if (func_data) {
244                 g_free(func_data->address);
245                 g_free(func_data);
246         }
247 }
248
249 int _bt_network_activate(void)
250 {
251         int ret = BLUETOOTH_ERROR_NONE;
252         char *adapter_path;
253         GVariant *result = NULL;
254         GError *err = NULL;
255         GDBusConnection *conn;
256         GDBusProxy *server_proxy;
257
258         conn = _bt_gdbus_get_system_gconn();
259         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
260
261         adapter_path = _bt_get_adapter_path();
262         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
263
264         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
265                         NULL, BT_BLUEZ_NAME,
266                         adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
267         g_free(adapter_path);
268
269         if (server_proxy == NULL) {
270                 BT_ERR("Failed to get the network server proxy\n");
271                 return BLUETOOTH_ERROR_INTERNAL;
272         }
273
274         result = g_dbus_proxy_call_sync(server_proxy, "Register",
275                                  g_variant_new("(ss)", NAP_UUID_NAME, NET_BRIDGE_INTERFACE),
276                                  G_DBUS_CALL_FLAGS_NONE,
277                                  -1,
278                                  NULL,
279                                  &err);
280         if (result == NULL) {
281                 if (err != NULL) {
282                         g_dbus_error_strip_remote_error(err);
283                         BT_ERR("Network server register Error: %s\n", err->message);
284                         if (g_strcmp0(err->message, "Already Exists") == 0)
285                                 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
286                         else
287                                 ret = BLUETOOTH_ERROR_INTERNAL;
288
289                         g_error_free(err);
290                 }
291         } else {
292                 g_variant_unref(result);
293         }
294
295         g_object_unref(server_proxy);
296
297         return ret;
298 }
299
300 int _bt_network_deactivate(void)
301 {
302         char *adapter_path;
303         GVariant *result = NULL;
304         GError *err = NULL;
305         GDBusConnection *conn;
306         GDBusProxy *server_proxy;
307         int ret = BLUETOOTH_ERROR_NONE;
308
309         conn = _bt_gdbus_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         result = 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 (result == NULL) {
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         } else {
344                 g_variant_unref(result);
345         }
346
347         g_object_unref(server_proxy);
348
349         return ret;
350 }
351
352 int _bt_network_connect(int request_id, int role,
353                 bluetooth_device_address_t *device_address)
354 {
355         const gchar *device_path = NULL;
356         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
357         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
358         bt_function_data_t *func_data;
359         GDBusProxy *adapter_proxy;
360         GDBusProxy *profile_proxy;
361         GDBusConnection *conn;
362         GVariant *result = NULL;
363         GError*err = NULL;
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_gdbus_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         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
393                         g_variant_new("(s)", address),
394                         G_DBUS_CALL_FLAGS_NONE,
395                         -1, NULL, &err);
396         if (result == NULL) {
397                 BT_ERR("Error occurred in call to FindDevice");
398                 if (err) {
399                         BT_ERR("Error: %s", err->message);
400                         g_clear_error(&err);
401                 }
402                 return BLUETOOTH_ERROR_INTERNAL;
403         }
404
405         device_path =  g_variant_get_string(result, NULL);
406         if (device_path == NULL) {
407                 BT_ERR("No paired device");
408                 g_variant_unref(result);
409                 return BLUETOOTH_ERROR_NOT_PAIRED;
410         }
411
412         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
413                         NULL, BT_BLUEZ_NAME,
414                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
415
416         g_variant_unref(result);
417         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
418         func_data = g_malloc0(sizeof(bt_function_data_t));
419         retv_if(func_data == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
420
421         func_data->address = g_strdup(address);
422         func_data->req_id = request_id;
423
424         g_dbus_proxy_call(profile_proxy, "Connect",
425                                 g_variant_new("(s)", remote_role),
426                                 G_DBUS_CALL_FLAGS_NONE,
427                                 BT_MAX_DBUS_TIMEOUT,
428                                 NULL,
429                                 (GAsyncReadyCallback)__bt_network_connect_cb,
430                                 func_data);
431
432         return BLUETOOTH_ERROR_NONE;
433 }
434
435 int _bt_network_disconnect(int request_id,
436                 bluetooth_device_address_t *device_address)
437 {
438         const gchar *device_path = NULL;
439         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
440         bt_function_data_t *func_data;
441         GDBusProxy *adapter_proxy;
442         GDBusProxy *profile_proxy;
443         GDBusConnection *conn;
444         GVariant *result = NULL;
445         GError*err = NULL;
446
447         BT_CHECK_PARAMETER(device_address, return);
448
449         adapter_proxy = _bt_get_adapter_proxy();
450         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
451
452         conn = _bt_gdbus_get_system_gconn();
453         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
454
455         _bt_convert_addr_type_to_string(address, device_address->addr);
456
457         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
458                                  g_variant_new("(s)", address),
459                                  G_DBUS_CALL_FLAGS_NONE,
460                                  -1, NULL, &err);
461         if (result == NULL) {
462                 BT_ERR("Error occurred in call to FindDevice");
463                 if (err) {
464                         BT_ERR("Error: %s", err->message);
465                         g_clear_error(&err);
466                 }
467                 return BLUETOOTH_ERROR_INTERNAL;
468         }
469
470         device_path =  g_variant_get_string(result, NULL);
471         if (device_path == NULL) {
472                 BT_ERR("No paired device");
473                 g_variant_unref(result);
474                 return BLUETOOTH_ERROR_NOT_PAIRED;
475         }
476
477         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
478                         NULL, BT_BLUEZ_NAME,
479                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
480
481         g_variant_unref(result);
482         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
483         func_data = g_malloc0(sizeof(bt_function_data_t));
484         retv_if(func_data == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
485
486         func_data->address = g_strdup(address);
487         func_data->req_id = request_id;
488
489         g_dbus_proxy_call(profile_proxy, "Disconnect",
490                         NULL,
491                         G_DBUS_CALL_FLAGS_NONE,
492                         BT_MAX_DBUS_TIMEOUT,
493                         NULL,
494                         (GAsyncReadyCallback)__bt_network_disconnect_cb,
495                         func_data);
496
497         return BLUETOOTH_ERROR_NONE;
498 }
499
500 int _bt_network_server_disconnect(int request_id,
501                 bluetooth_device_address_t *device_address)
502 {
503         gchar *adapter_path = NULL;
504         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
505         bt_function_data_t *func_data;
506         GDBusProxy *profile_proxy;
507         GDBusConnection *conn;
508
509         BT_CHECK_PARAMETER(device_address, return);
510
511         conn = _bt_gdbus_get_system_gconn();
512         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
513
514         adapter_path = _bt_get_adapter_path();
515         if (adapter_path == NULL) {
516                 BT_ERR("No adapter found");
517                 return BLUETOOTH_ERROR_INTERNAL;
518         }
519
520         _bt_convert_addr_type_to_string(address, device_address->addr);
521
522         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
523                         NULL, BT_BLUEZ_NAME,
524                         adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
525         g_free(adapter_path);
526         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
527         func_data = g_malloc0(sizeof(bt_function_data_t));
528
529         func_data->address = g_strdup(address);
530         func_data->req_id = request_id;
531
532         g_dbus_proxy_call(profile_proxy, "Disconnect",
533                                  g_variant_new("(s)", address),
534                                 G_DBUS_CALL_FLAGS_NONE,
535                                 BT_MAX_DBUS_TIMEOUT,
536                                 NULL,
537                                 (GAsyncReadyCallback)__bt_network_disconnect_cb,
538                                 func_data);
539
540         return BLUETOOTH_ERROR_NONE;
541 }