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 #include <net_connection.h>
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"
32 void _bt_util_addr_type_to_addr_net_string(char *address,
35 ret_if(address == NULL);
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]);
42 static connection_profile_h __bt_get_net_profile(void *connection,
43 connection_iterator_type_e type,
44 unsigned char *address)
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;
54 retv_if(connection == NULL, NULL);
55 retv_if(address == NULL, NULL);
57 BT_DBG("net_conn: %x", connection);
59 _bt_util_addr_type_to_addr_net_string(net_address, address);
61 result = connection_get_profile_iterator(connection,
64 if (result != CONNECTION_ERROR_NONE) {
65 BT_ERR("Fail to get profile iterator [%d]", result);
69 while (connection_profile_iterator_has_next(profile_iter)) {
74 if (connection_profile_iterator_next(profile_iter,
75 &profile_h) != CONNECTION_ERROR_NONE) {
76 BT_ERR("Fail to get profile handle");
80 if (connection_profile_get_type(profile_h,
81 &profile_type) != CONNECTION_ERROR_NONE) {
82 BT_ERR("Fail to get profile type");
86 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
89 if (connection_profile_get_name(profile_h,
90 &profile_name) != CONNECTION_ERROR_NONE) {
91 BT_ERR("Fail to get profile name");
95 split_string = g_strsplit(profile_name, "_", 3);
99 if (g_strv_length(split_string) < 3)
102 if (split_string[2] == NULL) {
103 BT_ERR("__bt_get_net_profile Error Parameter are NULL..\n");
105 } else 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);
118 int _bt_is_network_connected(void *connection, unsigned char *address,
119 gboolean *is_connected)
122 handle = __bt_get_net_profile(connection,
123 CONNECTION_ITERATOR_TYPE_CONNECTED,
126 *is_connected = TRUE;
128 *is_connected = FALSE;
130 return BLUETOOTH_ERROR_NONE;
133 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
144 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
145 g_object_unref(proxy);
148 BT_ERR("Network Connect Dbus Call Error");
150 BT_ERR("Error: %s\n", g_error->message);
151 g_clear_error(&g_error);
153 result = BLUETOOTH_ERROR_INTERNAL;
155 g_variant_unref(reply);
157 func_data = user_data;
158 if (func_data == NULL) {
160 BT_ERR("func_data == NULL");
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");
171 if (req_info->context == NULL)
174 _bt_convert_addr_string_to_type(device_addr.addr,
177 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
178 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
180 g_dbus_method_invocation_return_value(req_info->context,
181 g_variant_new("iv", result, out_param1));
183 _bt_delete_request_list(req_info->req_id);
187 g_free(func_data->address);
192 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
203 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
204 g_object_unref(proxy);
207 BT_ERR("Network Disconnect Dbus Call Error");
209 BT_ERR("Error: %s\n", g_error->message);
210 g_clear_error(&g_error);
212 result = BLUETOOTH_ERROR_INTERNAL;
214 g_variant_unref(reply);
216 func_data = user_data;
217 if (func_data == NULL) {
219 BT_ERR("func_data == NULL");
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");
229 if (g_error != NULL) {
230 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
231 result = BLUETOOTH_ERROR_INTERNAL;
234 if (req_info->context == NULL)
237 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
238 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
240 g_dbus_method_invocation_return_value(req_info->context,
241 g_variant_new("iv", result, out_param1));
243 _bt_delete_request_list(req_info->req_id);
247 g_free(func_data->address);
252 int _bt_network_activate(void)
254 int ret = BLUETOOTH_ERROR_NONE;
256 GVariant *result = NULL;
258 GDBusConnection *conn;
259 GDBusProxy *server_proxy;
261 conn = _bt_gdbus_get_system_gconn();
262 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
264 adapter_path = _bt_get_adapter_path();
265 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
267 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
269 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
270 g_free(adapter_path);
272 if (server_proxy == NULL) {
273 BT_ERR("Failed to get the network server proxy\n");
274 return BLUETOOTH_ERROR_INTERNAL;
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,
283 if (result == 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;
290 ret = BLUETOOTH_ERROR_INTERNAL;
295 g_variant_unref(result);
298 g_object_unref(server_proxy);
303 int _bt_network_deactivate(void)
306 GVariant *result = NULL;
308 GDBusConnection *conn;
309 GDBusProxy *server_proxy;
310 int ret = BLUETOOTH_ERROR_NONE;
312 conn = _bt_gdbus_get_system_gconn();
313 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
315 adapter_path = _bt_get_adapter_path();
316 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
318 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
320 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
321 g_free(adapter_path);
323 if (server_proxy == NULL) {
324 BT_ERR("Failed to get the network server proxy\n");
325 return BLUETOOTH_ERROR_INTERNAL;
328 result = g_dbus_proxy_call_sync(server_proxy, "Unregister",
329 g_variant_new("(s)", NAP_UUID_NAME),
330 G_DBUS_CALL_FLAGS_NONE,
334 if (result == 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;
342 ret = BLUETOOTH_ERROR_INTERNAL;
347 g_variant_unref(result);
350 g_object_unref(server_proxy);
355 int _bt_network_connect(int request_id, int role,
356 bluetooth_device_address_t *device_address)
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;
368 BT_CHECK_PARAMETER(device_address, return);
371 case BLUETOOTH_NETWORK_PANU_ROLE:
372 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
375 case BLUETOOTH_NETWORK_NAP_ROLE:
376 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
379 case BLUETOOTH_NETWORK_GN_ROLE:
380 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
383 BT_ERR("Unknown role");
384 return BLUETOOTH_ERROR_INTERNAL;
387 adapter_proxy = _bt_get_adapter_proxy();
388 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
390 conn = _bt_gdbus_get_system_gconn();
391 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
393 _bt_convert_addr_type_to_string(address, device_address->addr);
395 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
396 g_variant_new("(s)", address),
397 G_DBUS_CALL_FLAGS_NONE,
399 if (result == NULL) {
400 BT_ERR("Error occurred in call to FindDevice");
402 BT_ERR("Error: %s", err->message);
405 return BLUETOOTH_ERROR_INTERNAL;
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;
415 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
417 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
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;
425 g_dbus_proxy_call(profile_proxy, "Connect",
426 g_variant_new("(s)", remote_role),
427 G_DBUS_CALL_FLAGS_NONE,
430 (GAsyncReadyCallback)__bt_network_connect_cb,
433 return BLUETOOTH_ERROR_NONE;
436 int _bt_network_disconnect(int request_id,
437 bluetooth_device_address_t *device_address)
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;
448 BT_CHECK_PARAMETER(device_address, return);
450 adapter_proxy = _bt_get_adapter_proxy();
451 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
453 conn = _bt_gdbus_get_system_gconn();
454 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
456 _bt_convert_addr_type_to_string(address, device_address->addr);
458 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
459 g_variant_new("(s)", address),
460 G_DBUS_CALL_FLAGS_NONE,
462 if (result == NULL) {
463 BT_ERR("Error occurred in call to FindDevice");
465 BT_ERR("Error: %s", err->message);
468 return BLUETOOTH_ERROR_INTERNAL;
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;
478 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
480 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
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;
488 g_dbus_proxy_call(profile_proxy, "Disconnect",
490 G_DBUS_CALL_FLAGS_NONE,
493 (GAsyncReadyCallback)__bt_network_disconnect_cb,
496 return BLUETOOTH_ERROR_NONE;
499 int _bt_network_server_disconnect(int request_id,
500 bluetooth_device_address_t *device_address)
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;
508 BT_CHECK_PARAMETER(device_address, return);
510 conn = _bt_gdbus_get_system_gconn();
511 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
513 adapter_path = _bt_get_adapter_path();
514 if (adapter_path == NULL) {
515 BT_ERR("No adapter found");
516 return BLUETOOTH_ERROR_INTERNAL;
519 _bt_convert_addr_type_to_string(address, device_address->addr);
521 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
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));
528 func_data->address = g_strdup(address);
529 func_data->req_id = request_id;
531 g_dbus_proxy_call(profile_proxy, "Disconnect",
532 g_variant_new("(s)", address),
533 G_DBUS_CALL_FLAGS_NONE,
536 (GAsyncReadyCallback)__bt_network_disconnect_cb,
539 return BLUETOOTH_ERROR_NONE;
542 gboolean _bt_is_nap_panu_device_connected(bluetooth_device_address_t *address, int service_type)
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;
554 BT_DBG("+ %d", service_type);
556 conn = _bt_gdbus_get_system_gconn();
558 BT_DBG("_bt_gdbus_get_system_gconn returned NULL");
563 if (service_type == BLUETOOTH_NAP_SERVER_SERVICE) {
565 object_path = _bt_get_adapter_path();
566 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
568 object_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
570 if (device_proxy == NULL) {
571 BT_DBG("Device don't have this service");
575 result = g_dbus_proxy_call_sync(device_proxy, "GetProperties",
576 g_variant_new("(s)", address),
577 G_DBUS_CALL_FLAGS_NONE,
582 if (result == NULL) {
583 BT_ERR("[GetProperties] Error occured in Proxy call");
585 BT_ERR("%s", error->message);
588 is_connected = FALSE;
589 g_object_unref(device_proxy);
592 g_variant_get(result , "(@a{sv})", &value);
593 g_variant_unref(result);
596 tmp_value = g_variant_lookup_value(value,
598 G_VARIANT_TYPE_BOOLEAN);
600 is_connected = g_variant_get_boolean(tmp_value);
601 BT_ERR("%d IsConnected >>>>", is_connected);
602 g_variant_unref(tmp_value);
604 g_variant_unref(value);
606 BT_ERR("Value is NULL");
608 } else if (service_type == BLUETOOTH_NAP_SERVICE) {
609 _bt_is_network_connected(_bt_get_net_conn(),
610 address->addr, &is_connected);
614 return true; //force it till conenction manager is fully supported