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