4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <syspopup_caller.h>
30 #include <net_connection.h>
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"
39 void _bt_util_addr_type_to_addr_net_string(char *address,
42 ret_if(address == NULL);
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]);
49 static connection_profile_h __bt_get_net_profile(void *connection,
50 connection_iterator_type_e type,
51 unsigned char *address)
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;
61 retv_if(connection == NULL, NULL);
62 retv_if(address == NULL, NULL);
64 BT_DBG("net_conn: %x", connection);
66 _bt_util_addr_type_to_addr_net_string(net_address, address);
68 result = connection_get_profile_iterator(connection,
71 if (result != CONNECTION_ERROR_NONE) {
72 BT_ERR("Fail to get profile iterator [%d]", result);
76 while (connection_profile_iterator_has_next(profile_iter)) {
81 if (connection_profile_iterator_next(profile_iter,
82 &profile_h) != CONNECTION_ERROR_NONE) {
83 BT_ERR("Fail to get profile handle");
87 if (connection_profile_get_type(profile_h,
88 &profile_type) != CONNECTION_ERROR_NONE) {
89 BT_ERR("Fail to get profile type");
93 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
96 if (connection_profile_get_name(profile_h,
97 &profile_name) != CONNECTION_ERROR_NONE) {
98 BT_ERR("Fail to get profile name");
102 split_string = g_strsplit(profile_name, "_", 3);
104 g_free(profile_name);
106 if (g_strv_length(split_string) < 3)
109 if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
110 BT_DBG("matched profile");
111 g_strfreev(split_string);
115 g_strfreev(split_string);
121 int _bt_is_network_connected(void *connection, unsigned char *address,
122 gboolean *is_connected)
125 handle = __bt_get_net_profile(connection,
126 CONNECTION_ITERATOR_TYPE_CONNECTED,
129 *is_connected = TRUE;
131 *is_connected = FALSE;
133 return BLUETOOTH_ERROR_NONE;
136 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
147 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
148 g_object_unref(proxy);
151 BT_ERR("Network Connect Dbus Call Error");
153 BT_ERR("Error: %s\n", g_error->message);
154 g_clear_error(&g_error);
156 result = BLUETOOTH_ERROR_INTERNAL;
158 g_variant_unref(reply);
160 func_data = user_data;
161 if (func_data == NULL) {
163 BT_ERR("func_data == NULL");
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");
174 if (req_info->context == NULL)
177 _bt_convert_addr_string_to_type(device_addr.addr,
180 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
181 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
183 g_dbus_method_invocation_return_value(req_info->context,
184 g_variant_new("iv", result, out_param1));
186 _bt_delete_request_list(req_info->req_id);
190 g_free(func_data->address);
195 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
206 g_dbus_proxy_call_finish(proxy, res, &g_error);
207 g_object_unref(proxy);
210 BT_ERR("Network Disconnect Dbus Call Error");
212 BT_ERR("Error: %s\n", g_error->message);
213 g_clear_error(&g_error);
215 result = BLUETOOTH_ERROR_INTERNAL;
217 g_variant_unref(reply);
219 func_data = user_data;
220 if (func_data == NULL) {
222 BT_ERR("func_data == NULL");
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");
232 if (g_error != NULL) {
233 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
234 result = BLUETOOTH_ERROR_INTERNAL;
237 if (req_info->context == NULL)
240 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
241 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
243 g_dbus_method_invocation_return_value(req_info->context,
244 g_variant_new("iv", result, out_param1));
246 _bt_delete_request_list(req_info->req_id);
250 g_free(func_data->address);
255 int _bt_network_activate(void)
257 int ret = BLUETOOTH_ERROR_NONE;
260 GDBusConnection *conn;
261 GDBusProxy *server_proxy;
263 conn = _bt_get_system_gconn();
264 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
266 adapter_path = _bt_get_adapter_path();
267 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
269 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
271 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
272 g_free(adapter_path);
274 if (server_proxy == NULL) {
275 BT_ERR("Failed to get the network server proxy\n");
276 return BLUETOOTH_ERROR_INTERNAL;
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,
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;
290 ret = BLUETOOTH_ERROR_INTERNAL;
294 g_object_unref(server_proxy);
299 int _bt_network_deactivate(void)
303 GDBusConnection *conn;
304 GDBusProxy *server_proxy;
305 int ret = BLUETOOTH_ERROR_NONE;
307 conn = _bt_get_system_gconn();
308 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
310 adapter_path = _bt_get_adapter_path();
311 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
313 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
315 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
316 g_free(adapter_path);
318 if (server_proxy == NULL) {
319 BT_ERR("Failed to get the network server proxy\n");
320 return BLUETOOTH_ERROR_INTERNAL;
323 g_dbus_proxy_call_sync(server_proxy, "Unregister",
324 g_variant_new("(s)", NAP_UUID_NAME),
325 G_DBUS_CALL_FLAGS_NONE,
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;
335 ret = BLUETOOTH_ERROR_INTERNAL;
339 g_object_unref(server_proxy);
344 int _bt_network_connect(int request_id, int role,
345 bluetooth_device_address_t *device_address)
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;
357 BT_CHECK_PARAMETER(device_address, return);
360 case BLUETOOTH_NETWORK_PANU_ROLE:
361 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
364 case BLUETOOTH_NETWORK_NAP_ROLE:
365 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
368 case BLUETOOTH_NETWORK_GN_ROLE:
369 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
372 BT_ERR("Unknown role");
373 return BLUETOOTH_ERROR_INTERNAL;
376 adapter_proxy = _bt_get_adapter_proxy();
377 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
379 conn = _bt_get_system_gconn();
380 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
382 _bt_convert_addr_type_to_string(address, device_address->addr);
384 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
385 g_variant_new("(s)", address),
386 G_DBUS_CALL_FLAGS_NONE,
388 if (result == NULL) {
389 BT_ERR("Error occurred in call to FindDevice");
391 BT_ERR("Error: %s", err->message);
394 return BLUETOOTH_ERROR_INTERNAL;
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;
404 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
406 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
408 g_variant_unref(result);
409 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
410 func_data = g_malloc0(sizeof(bt_function_data_t));
412 func_data->address = g_strdup(address);
413 func_data->req_id = request_id;
415 g_dbus_proxy_call(profile_proxy, "Connect",
416 g_variant_new("(s)", remote_role),
417 G_DBUS_CALL_FLAGS_NONE,
420 (GAsyncReadyCallback)__bt_network_connect_cb,
423 return BLUETOOTH_ERROR_NONE;
426 int _bt_network_disconnect(int request_id,
427 bluetooth_device_address_t *device_address)
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;
438 BT_CHECK_PARAMETER(device_address, return);
440 adapter_proxy = _bt_get_adapter_proxy();
441 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
443 conn = _bt_get_system_gconn();
444 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
446 _bt_convert_addr_type_to_string(address, device_address->addr);
448 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
449 g_variant_new("(s)", address),
450 G_DBUS_CALL_FLAGS_NONE,
452 if (result == NULL) {
453 BT_ERR("Error occurred in call to FindDevice");
455 BT_ERR("Error: %s", err->message);
458 return BLUETOOTH_ERROR_INTERNAL;
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;
467 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
469 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
471 g_variant_unref(result);
472 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
473 func_data = g_malloc0(sizeof(bt_function_data_t));
475 func_data->address = g_strdup(address);
476 func_data->req_id = request_id;
478 g_dbus_proxy_call(profile_proxy, "Disconnect",
480 G_DBUS_CALL_FLAGS_NONE,
483 (GAsyncReadyCallback)__bt_network_disconnect_cb,
486 return BLUETOOTH_ERROR_NONE;
489 int _bt_network_server_disconnect(int request_id,
490 bluetooth_device_address_t *device_address)
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;
498 BT_CHECK_PARAMETER(device_address, return);
500 conn = _bt_get_system_gconn();
501 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
503 adapter_path = _bt_get_adapter_path();
504 if (adapter_path == NULL) {
505 BT_ERR("No adapter found");
506 return BLUETOOTH_ERROR_INTERNAL;
509 _bt_convert_addr_type_to_string(address, device_address->addr);
511 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
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));
518 func_data->address = g_strdup(address);
519 func_data->req_id = request_id;
521 g_dbus_proxy_call(profile_proxy, "Disconnect",
522 g_variant_new("(s)", address),
523 G_DBUS_CALL_FLAGS_NONE,
526 (GAsyncReadyCallback)__bt_network_disconnect_cb,
529 g_free(func_data->address);
532 return BLUETOOTH_ERROR_NONE;