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 <syspopup_caller.h>
24 #include <net_connection.h>
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"
33 void _bt_util_addr_type_to_addr_net_string(char *address,
36 ret_if(address == NULL);
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]);
43 static connection_profile_h __bt_get_net_profile(void *connection,
44 connection_iterator_type_e type,
45 unsigned char *address)
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;
55 retv_if(connection == NULL, NULL);
56 retv_if(address == NULL, NULL);
58 BT_DBG("net_conn: %x", connection);
60 _bt_util_addr_type_to_addr_net_string(net_address, address);
62 result = connection_get_profile_iterator(connection,
65 if (result != CONNECTION_ERROR_NONE) {
66 BT_ERR("Fail to get profile iterator [%d]", result);
70 while (connection_profile_iterator_has_next(profile_iter)) {
75 if (connection_profile_iterator_next(profile_iter,
76 &profile_h) != CONNECTION_ERROR_NONE) {
77 BT_ERR("Fail to get profile handle");
81 if (connection_profile_get_type(profile_h,
82 &profile_type) != CONNECTION_ERROR_NONE) {
83 BT_ERR("Fail to get profile type");
87 if (profile_type != CONNECTION_PROFILE_TYPE_BT)
90 if (connection_profile_get_name(profile_h,
91 &profile_name) != CONNECTION_ERROR_NONE) {
92 BT_ERR("Fail to get profile name");
96 split_string = g_strsplit(profile_name, "_", 3);
100 if (g_strv_length(split_string) < 3)
103 if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
104 BT_DBG("matched profile");
105 g_strfreev(split_string);
109 g_strfreev(split_string);
115 int _bt_is_network_connected(void *connection, unsigned char *address,
116 gboolean *is_connected)
119 handle = __bt_get_net_profile(connection,
120 CONNECTION_ITERATOR_TYPE_CONNECTED,
123 *is_connected = TRUE;
125 *is_connected = FALSE;
127 return BLUETOOTH_ERROR_NONE;
130 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
141 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
142 g_object_unref(proxy);
145 BT_ERR("Network Connect Dbus Call Error");
147 BT_ERR("Error: %s\n", g_error->message);
148 g_clear_error(&g_error);
150 result = BLUETOOTH_ERROR_INTERNAL;
152 g_variant_unref(reply);
154 func_data = user_data;
155 if (func_data == NULL) {
157 BT_ERR("func_data == NULL");
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");
168 if (req_info->context == NULL)
171 _bt_convert_addr_string_to_type(device_addr.addr,
174 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
175 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
177 g_dbus_method_invocation_return_value(req_info->context,
178 g_variant_new("iv", result, out_param1));
180 _bt_delete_request_list(req_info->req_id);
184 g_free(func_data->address);
189 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
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;
200 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
201 g_object_unref(proxy);
204 BT_ERR("Network Disconnect Dbus Call Error");
206 BT_ERR("Error: %s\n", g_error->message);
207 g_clear_error(&g_error);
209 result = BLUETOOTH_ERROR_INTERNAL;
211 g_variant_unref(reply);
213 func_data = user_data;
214 if (func_data == NULL) {
216 BT_ERR("func_data == NULL");
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");
226 if (g_error != NULL) {
227 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
228 result = BLUETOOTH_ERROR_INTERNAL;
231 if (req_info->context == NULL)
234 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
235 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
237 g_dbus_method_invocation_return_value(req_info->context,
238 g_variant_new("iv", result, out_param1));
240 _bt_delete_request_list(req_info->req_id);
244 g_free(func_data->address);
249 int _bt_network_activate(void)
251 int ret = BLUETOOTH_ERROR_NONE;
253 GVariant *result = NULL;
255 GDBusConnection *conn;
256 GDBusProxy *server_proxy;
258 conn = _bt_gdbus_get_system_gconn();
259 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
261 adapter_path = _bt_get_adapter_path();
262 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
264 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
266 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
267 g_free(adapter_path);
269 if (server_proxy == NULL) {
270 BT_ERR("Failed to get the network server proxy\n");
271 return BLUETOOTH_ERROR_INTERNAL;
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,
280 if (result == 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;
287 ret = BLUETOOTH_ERROR_INTERNAL;
292 g_variant_unref(result);
295 g_object_unref(server_proxy);
300 int _bt_network_deactivate(void)
303 GVariant *result = NULL;
305 GDBusConnection *conn;
306 GDBusProxy *server_proxy;
307 int ret = BLUETOOTH_ERROR_NONE;
309 conn = _bt_gdbus_get_system_gconn();
310 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
312 adapter_path = _bt_get_adapter_path();
313 retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
315 server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
317 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
318 g_free(adapter_path);
320 if (server_proxy == NULL) {
321 BT_ERR("Failed to get the network server proxy\n");
322 return BLUETOOTH_ERROR_INTERNAL;
325 result = g_dbus_proxy_call_sync(server_proxy, "Unregister",
326 g_variant_new("(s)", NAP_UUID_NAME),
327 G_DBUS_CALL_FLAGS_NONE,
331 if (result == 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;
339 ret = BLUETOOTH_ERROR_INTERNAL;
344 g_variant_unref(result);
347 g_object_unref(server_proxy);
352 int _bt_network_connect(int request_id, int role,
353 bluetooth_device_address_t *device_address)
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;
365 BT_CHECK_PARAMETER(device_address, return);
368 case BLUETOOTH_NETWORK_PANU_ROLE:
369 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
372 case BLUETOOTH_NETWORK_NAP_ROLE:
373 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
376 case BLUETOOTH_NETWORK_GN_ROLE:
377 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
380 BT_ERR("Unknown role");
381 return BLUETOOTH_ERROR_INTERNAL;
384 adapter_proxy = _bt_get_adapter_proxy();
385 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
387 conn = _bt_gdbus_get_system_gconn();
388 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
390 _bt_convert_addr_type_to_string(address, device_address->addr);
392 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
393 g_variant_new("(s)", address),
394 G_DBUS_CALL_FLAGS_NONE,
396 if (result == NULL) {
397 BT_ERR("Error occurred in call to FindDevice");
399 BT_ERR("Error: %s", err->message);
402 return BLUETOOTH_ERROR_INTERNAL;
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;
412 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
414 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
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 func_data->address = g_strdup(address);
420 func_data->req_id = request_id;
422 g_dbus_proxy_call(profile_proxy, "Connect",
423 g_variant_new("(s)", remote_role),
424 G_DBUS_CALL_FLAGS_NONE,
427 (GAsyncReadyCallback)__bt_network_connect_cb,
430 return BLUETOOTH_ERROR_NONE;
433 int _bt_network_disconnect(int request_id,
434 bluetooth_device_address_t *device_address)
436 const gchar *device_path = NULL;
437 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
438 bt_function_data_t *func_data;
439 GDBusProxy *adapter_proxy;
440 GDBusProxy *profile_proxy;
441 GDBusConnection *conn;
442 GVariant *result = NULL;
445 BT_CHECK_PARAMETER(device_address, return);
447 adapter_proxy = _bt_get_adapter_proxy();
448 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
450 conn = _bt_gdbus_get_system_gconn();
451 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
453 _bt_convert_addr_type_to_string(address, device_address->addr);
455 result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
456 g_variant_new("(s)", address),
457 G_DBUS_CALL_FLAGS_NONE,
459 if (result == NULL) {
460 BT_ERR("Error occurred in call to FindDevice");
462 BT_ERR("Error: %s", err->message);
465 return BLUETOOTH_ERROR_INTERNAL;
468 device_path = g_variant_get_string(result, NULL);
469 if (device_path == NULL) {
470 BT_ERR("No paired device");
471 g_variant_unref(result);
472 return BLUETOOTH_ERROR_NOT_PAIRED;
475 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
477 device_path, BT_NETWORK_CLIENT_INTERFACE, NULL, NULL);
479 g_variant_unref(result);
480 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
481 func_data = g_malloc0(sizeof(bt_function_data_t));
482 func_data->address = g_strdup(address);
483 func_data->req_id = request_id;
485 g_dbus_proxy_call(profile_proxy, "Disconnect",
487 G_DBUS_CALL_FLAGS_NONE,
490 (GAsyncReadyCallback)__bt_network_disconnect_cb,
493 return BLUETOOTH_ERROR_NONE;
496 int _bt_network_server_disconnect(int request_id,
497 bluetooth_device_address_t *device_address)
499 gchar *adapter_path = NULL;
500 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
501 bt_function_data_t *func_data;
502 GDBusProxy *profile_proxy;
503 GDBusConnection *conn;
505 BT_CHECK_PARAMETER(device_address, return);
507 conn = _bt_gdbus_get_system_gconn();
508 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
510 adapter_path = _bt_get_adapter_path();
511 if (adapter_path == NULL) {
512 BT_ERR("No adapter found");
513 return BLUETOOTH_ERROR_INTERNAL;
516 _bt_convert_addr_type_to_string(address, device_address->addr);
518 profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
520 adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
521 g_free(adapter_path);
522 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
523 func_data = g_malloc0(sizeof(bt_function_data_t));
525 func_data->address = g_strdup(address);
526 func_data->req_id = request_id;
528 g_dbus_proxy_call(profile_proxy, "Disconnect",
529 g_variant_new("(s)", address),
530 G_DBUS_CALL_FLAGS_NONE,
533 (GAsyncReadyCallback)__bt_network_disconnect_cb,
536 return BLUETOOTH_ERROR_NONE;