2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
24 #include <syspopup_caller.h>
26 #include <net_connection.h>
28 #include "bluetooth-api.h"
29 #include "bt-service-network.h"
30 #include "bt-service-common.h"
31 #include "bt-service-event.h"
32 #include "bt-service-util.h"
33 #include "bt-internal-types.h"
35 void _bt_util_addr_type_to_addr_net_string(char *address,
38 ret_if(address == NULL);
41 snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
42 addr[1], addr[2], addr[3], addr[4], addr[5]);
45 static connection_profile_h __bt_get_net_profile(void *connection,
46 connection_iterator_type_e type,
47 unsigned char *address)
51 char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
52 char *profile_name = NULL;
53 connection_profile_iterator_h profile_iter;
54 connection_profile_h profile_h;
55 connection_profile_type_e profile_type;
57 retv_if(connection == NULL, NULL);
58 retv_if(address == NULL, NULL);
60 BT_DBG("net_conn: %x", connection);
62 _bt_util_addr_type_to_addr_net_string(net_address, address);
64 result = connection_get_profile_iterator(connection,
67 if (result != CONNECTION_ERROR_NONE) {
68 BT_ERR("Fail to get profile iterator [%d]", result);
72 while (connection_profile_iterator_has_next(profile_iter)) {
77 if (connection_profile_iterator_next(profile_iter,
78 &profile_h) != CONNECTION_ERROR_NONE) {
79 BT_ERR("Fail to get profile handle");
83 if (connection_profile_get_type(profile_h,
84 &profile_type) != CONNECTION_ERROR_NONE) {
85 BT_ERR("Fail to get profile type");
89 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
92 if (connection_profile_get_name(profile_h,
93 &profile_name) != CONNECTION_ERROR_NONE) {
94 BT_ERR("Fail to get profile name");
98 split_string = g_strsplit(profile_name, "_", 3);
100 g_free(profile_name);
102 if (g_strv_length(split_string) < 3)
105 if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
106 BT_DBG("matched profile");
107 g_strfreev(split_string);
111 g_strfreev(split_string);
117 int _bt_is_network_connected(void *connection, unsigned char *address,
118 gboolean *is_connected)
121 handle = __bt_get_net_profile(connection,
122 CONNECTION_ITERATOR_TYPE_CONNECTED,
125 *is_connected = TRUE;
127 *is_connected = FALSE;
129 return BLUETOOTH_ERROR_NONE;
132 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
135 GError *g_error = NULL;
136 GVariant *out_param1 = NULL;
137 GVariant *reply = NULL;
138 bluetooth_device_address_t device_addr = { {0} };
139 int result = BLUETOOTH_ERROR_NONE;
140 bt_function_data_t *func_data;
141 request_info_t *req_info;
143 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
144 g_object_unref(proxy);
147 BT_ERR("Network Connect Dbus Call Error");
149 BT_ERR("Error: %s\n", g_error->message);
150 g_clear_error(&g_error);
152 result = BLUETOOTH_ERROR_INTERNAL;
154 g_variant_unref(reply);
156 func_data = user_data;
157 if (func_data == NULL) {
159 BT_ERR("func_data == NULL");
163 BT_ERR("func_data->req_id: %d", func_data->req_id);
164 req_info = _bt_get_request_info(func_data->req_id);
165 if (req_info == NULL) {
166 BT_ERR("req_info == NULL");
170 if (req_info->context == NULL)
173 _bt_convert_addr_string_to_type(device_addr.addr,
176 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
177 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
179 g_dbus_method_invocation_return_value(req_info->context,
180 g_variant_new("iv", result, out_param1));
182 _bt_delete_request_list(req_info->req_id);
186 g_free(func_data->address);
191 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
194 GError *g_error = NULL;
195 GVariant *out_param1 = NULL;
196 GVariant *reply = NULL;
197 bluetooth_device_address_t device_addr = { {0} };
198 int result = BLUETOOTH_ERROR_NONE;
199 bt_function_data_t *func_data;
200 request_info_t *req_info;
202 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
203 g_object_unref(proxy);
206 BT_ERR("Network Disconnect Dbus Call Error");
208 BT_ERR("Error: %s\n", g_error->message);
209 g_clear_error(&g_error);
211 result = BLUETOOTH_ERROR_INTERNAL;
213 g_variant_unref(reply);
215 func_data = user_data;
216 if (func_data == NULL) {
218 BT_ERR("func_data == NULL");
221 BT_ERR("func_data->req_id: %d", func_data->req_id);
222 req_info = _bt_get_request_info(func_data->req_id);
223 if (req_info == NULL) {
224 BT_ERR("req_info == NULL");
228 if (g_error != NULL) {
229 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
230 result = BLUETOOTH_ERROR_INTERNAL;
233 if (req_info->context == NULL)
236 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
237 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
239 g_dbus_method_invocation_return_value(req_info->context,
240 g_variant_new("iv", result, out_param1));
242 _bt_delete_request_list(req_info->req_id);
246 g_free(func_data->address);
251 int _bt_network_activate(void)
253 int ret = BLUETOOTH_ERROR_NONE;
256 GDBusConnection *conn;
257 GDBusProxy *server_proxy;
259 conn = _bt_get_system_gconn();
260 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
262 adapter_path = _bt_get_adapter_path();
263 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
265 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
267 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
268 g_free(adapter_path);
270 if (server_proxy == NULL) {
271 BT_ERR("Failed to get the network server proxy\n");
272 return BLUETOOTH_ERROR_INTERNAL;
275 g_dbus_proxy_call_sync(server_proxy, "Register",
276 g_variant_new("(ss)", NAP_UUID_NAME, NET_BRIDGE_INTERFACE),
277 G_DBUS_CALL_FLAGS_NONE,
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;
287 ret = BLUETOOTH_ERROR_INTERNAL;
291 g_object_unref(server_proxy);
296 int _bt_network_deactivate(void)
300 GDBusConnection *conn;
301 GDBusProxy *server_proxy;
302 int ret = BLUETOOTH_ERROR_NONE;
304 conn = _bt_get_system_gconn();
305 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
307 adapter_path = _bt_get_adapter_path();
308 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
310 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
312 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
313 g_free(adapter_path);
315 if (server_proxy == NULL) {
316 BT_ERR("Failed to get the network server proxy\n");
317 return BLUETOOTH_ERROR_INTERNAL;
320 g_dbus_proxy_call_sync(server_proxy, "Unregister",
321 g_variant_new("(s)", NAP_UUID_NAME),
322 G_DBUS_CALL_FLAGS_NONE,
327 g_dbus_error_strip_remote_error(err);
328 BT_ERR("Network server unregister Error: %s\n", err->message);
329 if (g_strcmp0(err->message,
330 "Operation currently not available") == 0) {
331 ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
333 ret = BLUETOOTH_ERROR_INTERNAL;
337 g_object_unref(server_proxy);
342 int _bt_network_connect(int request_id, int role,
343 bluetooth_device_address_t *device_address)
345 const gchar *device_path = NULL;
346 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
347 char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
348 bt_function_data_t *func_data;
349 GDBusProxy *adapter_proxy;
350 GDBusProxy *profile_proxy;
351 GDBusConnection *conn;
352 GVariant *result = NULL;
355 BT_CHECK_PARAMETER(device_address, return);
358 case BLUETOOTH_NETWORK_PANU_ROLE:
359 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
362 case BLUETOOTH_NETWORK_NAP_ROLE:
363 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
366 case BLUETOOTH_NETWORK_GN_ROLE:
367 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
370 BT_ERR("Unknown role");
371 return BLUETOOTH_ERROR_INTERNAL;
374 adapter_proxy = _bt_get_adapter_proxy();
375 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
377 conn = _bt_get_system_gconn();
378 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
380 _bt_convert_addr_type_to_string(address, device_address->addr);
382 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
383 g_variant_new("(s)", address),
384 G_DBUS_CALL_FLAGS_NONE,
386 if (result == NULL) {
387 BT_ERR("Error occurred in call to FindDevice");
389 BT_ERR("Error: %s", err->message);
392 return BLUETOOTH_ERROR_INTERNAL;
395 device_path = g_variant_get_string(result, NULL);
396 if (device_path == NULL) {
397 BT_ERR("No paired device");
398 g_variant_unref(result);
399 return BLUETOOTH_ERROR_NOT_PAIRED;
402 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
404 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
406 g_variant_unref(result);
407 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
408 func_data = g_malloc0(sizeof(bt_function_data_t));
410 func_data->address = g_strdup(address);
411 func_data->req_id = request_id;
413 g_dbus_proxy_call(profile_proxy, "Connect",
414 g_variant_new("(s)", remote_role),
415 G_DBUS_CALL_FLAGS_NONE,
418 (GAsyncReadyCallback)__bt_network_connect_cb,
421 return BLUETOOTH_ERROR_NONE;
424 int _bt_network_disconnect(int request_id,
425 bluetooth_device_address_t *device_address)
427 const gchar *device_path = NULL;
428 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
429 bt_function_data_t *func_data;
430 GDBusProxy *adapter_proxy;
431 GDBusProxy *profile_proxy;
432 GDBusConnection *conn;
433 GVariant *result = NULL;
436 BT_CHECK_PARAMETER(device_address, return);
438 adapter_proxy = _bt_get_adapter_proxy();
439 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
441 conn = _bt_get_system_gconn();
442 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
444 _bt_convert_addr_type_to_string(address, device_address->addr);
446 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
447 g_variant_new("(s)", address),
448 G_DBUS_CALL_FLAGS_NONE,
450 if (result == NULL) {
451 BT_ERR("Error occurred in call to FindDevice");
453 BT_ERR("Error: %s", err->message);
456 return BLUETOOTH_ERROR_INTERNAL;
459 device_path = g_variant_get_string(result, NULL);
460 if (device_path == NULL) {
461 BT_ERR("No paired device");
462 return BLUETOOTH_ERROR_NOT_PAIRED;
465 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
467 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
469 g_variant_unref(result);
470 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
471 func_data = g_malloc0(sizeof(bt_function_data_t));
473 func_data->address = g_strdup(address);
474 func_data->req_id = request_id;
476 g_dbus_proxy_call(profile_proxy, "Disconnect",
478 G_DBUS_CALL_FLAGS_NONE,
481 (GAsyncReadyCallback)__bt_network_disconnect_cb,
484 return BLUETOOTH_ERROR_NONE;
487 int _bt_network_server_disconnect(int request_id,
488 bluetooth_device_address_t *device_address)
490 gchar *adapter_path = NULL;
491 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
492 bt_function_data_t *func_data;
493 GDBusProxy *profile_proxy;
494 GDBusConnection *conn;
496 BT_CHECK_PARAMETER(device_address, return);
498 conn = _bt_get_system_gconn();
499 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
501 adapter_path = _bt_get_adapter_path();
502 if (adapter_path == NULL) {
503 BT_ERR("No adapter found");
504 return BLUETOOTH_ERROR_INTERNAL;
507 _bt_convert_addr_type_to_string(address, device_address->addr);
509 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
511 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
512 g_free(adapter_path);
513 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
514 func_data = g_malloc0(sizeof(bt_function_data_t));
516 func_data->address = g_strdup(address);
517 func_data->req_id = request_id;
519 g_dbus_proxy_call(profile_proxy, "Disconnect",
520 g_variant_new("(s)", address),
521 G_DBUS_CALL_FLAGS_NONE,
524 (GAsyncReadyCallback)__bt_network_disconnect_cb,
527 return BLUETOOTH_ERROR_NONE;