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.
28 #include <vconf-keys.h>
30 #include "bt-internal-types.h"
31 #include "bt-service-common.h"
32 #include "bt-service-agent.h"
33 #include "bt-service-gap-agent.h"
34 #include "bt-service-adapter.h"
35 #include "bt-service-device.h"
37 static GDBusConnection *connection = NULL;
40 GAP_AGENT_ERROR_REJECT,
41 GAP_AGENT_ERROR_CANCEL,
42 GAP_AGENT_ERROR_TIMEOUT,
45 #define GAP_AGENT_ERROR (gap_agent_error_quark())
47 static GQuark gap_agent_error_quark(void)
49 static GQuark quark = 0;
51 quark = g_quark_from_static_string("agent");
56 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
58 static gint gap_agent_id = -1;
60 static bt_agent_osp_server_t *__gap_agent_find_server(GSList *servers,
65 bt_agent_osp_server_t *transfer;
67 for (l = servers; l != NULL; l = l->next) {
73 /* No uuid in obex server */
74 if (type == BT_OBEX_SERVER &&
75 transfer->type == BT_OBEX_SERVER)
78 if (g_strcmp0(transfer->uuid, uuid) == 0)
85 static void __gap_agent_remove_osp_servers(GSList *osp_servers)
88 bt_agent_osp_server_t *server;
90 for (l = osp_servers; l != NULL; l = g_slist_next(l)) {
101 gboolean _gap_agent_register_osp_server(GapAgentPrivate *agent,
107 bt_agent_osp_server_t *server;
111 GapAgentPrivate *priv = agent;
116 /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
117 if (type > BT_RFCOMM_SERVER)
120 server = g_malloc0(sizeof(bt_agent_osp_server_t));
122 /* Fix : NULL_RETURNS */
123 retv_if(server == NULL, FALSE);
126 if (type == BT_RFCOMM_SERVER) {
127 server->uuid = g_strdup(uuid);
128 server->path = g_strdup(path);
132 priv->osp_servers = g_slist_append(priv->osp_servers, server);
139 gboolean _gap_agent_unregister_osp_server(GapAgentPrivate *agent,
143 bt_agent_osp_server_t *server;
147 GapAgentPrivate *priv = agent;
152 /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
153 if (type > BT_RFCOMM_SERVER)
156 server = __gap_agent_find_server(priv->osp_servers, type, uuid);
161 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
163 g_free(server->uuid);
171 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
172 const char *pin_code,
173 GDBusMethodInvocation *context)
177 GapAgentPrivate *priv = agent;
179 /* Fix : NULL_RETURNS */
180 retv_if(priv == NULL, FALSE);
182 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
183 priv->reply_context != NULL) {
184 if (accept == GAP_AGENT_ACCEPT) {
185 g_dbus_method_invocation_return_value(priv->reply_context,
186 g_variant_new("(s)", pin_code));
187 priv->canceled = FALSE;
190 case GAP_AGENT_CANCEL:
191 g_dbus_method_invocation_return_error(priv->reply_context,
192 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
194 priv->canceled = TRUE;
196 case GAP_AGENT_TIMEOUT:
197 case GAP_AGENT_REJECT:
199 g_dbus_method_invocation_return_error(priv->reply_context,
200 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
201 "Pairing request rejected");
202 priv->canceled = FALSE;
208 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
209 priv->reply_context = NULL;
210 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
217 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
219 GDBusMethodInvocation *context)
223 GapAgentPrivate *priv = agent;
225 /* Fix : NULL_RETURNS */
226 retv_if(priv == NULL, FALSE);
228 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
229 priv->reply_context != NULL) {
230 if (accept == GAP_AGENT_ACCEPT) {
231 guint pass_key = atoi(passkey);
232 g_dbus_method_invocation_return_value(priv->reply_context,
233 g_variant_new("(u)", pass_key));
234 priv->canceled = FALSE;
237 case GAP_AGENT_CANCEL:
238 g_dbus_method_invocation_return_error(priv->reply_context,
239 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
241 priv->canceled = TRUE;
243 case GAP_AGENT_TIMEOUT:
244 case GAP_AGENT_REJECT:
246 g_dbus_method_invocation_return_error(priv->reply_context,
247 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
248 "Passkey request rejected");
249 priv->canceled = FALSE;
255 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
256 priv->reply_context = NULL;
257 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
264 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
265 GDBusMethodInvocation *context)
269 GapAgentPrivate *priv = agent;
271 /* Fix : NULL_RETURNS */
272 retv_if(priv == NULL, FALSE);
274 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
275 priv->reply_context != NULL) {
276 if (accept == GAP_AGENT_ACCEPT) {
277 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
278 priv->canceled = FALSE;
281 case GAP_AGENT_CANCEL:
282 g_dbus_method_invocation_return_error(priv->reply_context,
283 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
285 priv->canceled = TRUE;
287 case GAP_AGENT_TIMEOUT:
288 case GAP_AGENT_REJECT:
290 g_dbus_method_invocation_return_error(priv->reply_context,
291 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
292 "Confirmation request rejected");
293 priv->canceled = FALSE;
299 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
300 priv->reply_context = NULL;
301 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
308 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
309 GDBusMethodInvocation *context)
315 GapAgentPrivate *priv = agent;
317 /* Fix : NULL_RETURNS */
318 retv_if(priv == NULL, FALSE);
320 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
321 priv->reply_context != NULL) {
322 if (accept == GAP_AGENT_ACCEPT) {
323 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
324 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
325 bluetooth_device_address_t addr = {{0,}};
328 _bt_convert_addr_string_to_type(addr.addr,
329 priv->authorize_addr);
331 result = _bt_set_authorization(&addr, TRUE);
332 if (result == BLUETOOTH_ERROR_NONE) {
333 BT_INFO("[%s] Device added to trusted", priv->authorize_addr);
336 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
339 case GAP_AGENT_CANCEL:
340 g_dbus_method_invocation_return_error(priv->reply_context,
341 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
344 case GAP_AGENT_TIMEOUT:
345 case GAP_AGENT_REJECT:
347 g_dbus_method_invocation_return_error(priv->reply_context,
348 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
349 "Authorization request rejected");
355 g_dbus_method_invocation_return_value(context, NULL);
357 BT_ERR("No context");
360 g_dbus_method_invocation_return_error(context,
361 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
366 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
367 priv->reply_context = NULL;
368 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
375 gboolean _gap_agent_register(GapAgentPrivate *agent)
377 GapAgentPrivate *priv = agent;
378 GDBusProxy *agent_manager;
379 GError *error = NULL;
382 retv_if(priv == NULL, FALSE);
383 retv_if(connection == NULL, FALSE);
385 if (priv->agent_manager == NULL) {
386 agent_manager = g_dbus_proxy_new_sync(connection,
387 G_DBUS_PROXY_FLAGS_NONE, NULL,
388 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
389 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
390 if (!agent_manager) {
392 ERR("Unable to create proxy: %s", error->message);
393 g_clear_error(&error);
398 agent_manager = priv->agent_manager;
401 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
402 g_variant_new("(os)", priv->path, "DisplayYesNo"),
403 G_DBUS_CALL_FLAGS_NONE, -1,
406 BT_ERR("Agent registration failed");
408 BT_ERR("Agent registration failed: errCode[%x], message[%s]",
409 error->code, error->message);
410 g_clear_error(&error);
412 g_object_unref(agent_manager);
413 priv->agent_manager = NULL;
416 g_variant_unref(reply);
419 /* Set the defalut agent */
420 BT_DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
421 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
422 g_variant_new("(o)", priv->path),
423 G_DBUS_CALL_FLAGS_NONE, -1,
426 ERR("Request Default Agent failed");
428 ERR("Request Default Agent failed: errCode[%x], message[%s]",
429 error->code, error->message);
430 g_clear_error(&error);
432 g_object_unref(agent_manager);
433 priv->agent_manager = NULL;
436 g_variant_unref(reply);
438 priv->agent_manager = agent_manager;
443 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
445 GapAgentPrivate *priv = agent;
446 GDBusProxy *agent_manager;
447 GError *error = NULL;
450 retv_if(priv == NULL, FALSE);
451 retv_if(priv->path == NULL, FALSE);
452 retv_if(connection == NULL, FALSE);
454 if (priv->agent_manager == NULL) {
455 agent_manager = g_dbus_proxy_new_sync(connection,
456 G_DBUS_PROXY_FLAGS_NONE, NULL,
457 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
458 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
459 if (!agent_manager) {
461 ERR("Unable to create proxy: %s", error->message);
462 g_clear_error(&error);
467 agent_manager = priv->agent_manager;
470 reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
471 g_variant_new("o", priv->path),
472 G_DBUS_CALL_FLAGS_NONE, -1,
474 g_object_unref(agent_manager);
475 priv->agent_manager = NULL;
478 ERR("Agent unregistration failed");
480 ERR("Agent unregistration failed: errCode[%x], message[%s]",
481 error->code, error->message);
482 g_clear_error(&error);
486 g_variant_unref(reply);
491 static const gchar gap_agent_bluez_introspection_xml[] =
493 " <interface name='org.bluez.Agent1'>"
494 " <method name='RequestPinCode'>"
495 " <arg type='o' name='device' direction='in'/>"
496 " <arg type='s' name='pincode' direction='out'/>"
498 " <method name='RequestPasskey'>"
499 " <arg type='o' name='device' direction='in'/>"
500 " <arg type='u' name='passkey' direction='out'/>"
502 " <method name='DisplayPasskey'>"
503 " <arg type='o' name='device' direction='in'/>"
504 " <arg type='u' name='passkey' direction='in'/>"
505 " <arg type='q' name='entered' direction='in'/>"
507 " <method name='RequestConfirmation'>"
508 " <arg type='o' name='device' direction='in'/>"
509 " <arg type='u' name='passkey' direction='in'/>"
511 " <method name='RequestAuthorization'>"
512 " <arg type='o' name='device' direction='in'/>"
514 " <method name='AuthorizeService'>"
515 " <arg type='o' name='device' direction='in'/>"
516 " <arg type='s' name='uuid' direction='in'/>"
518 " <method name='Cancel'>"
520 " <method name='Release'>"
522 " <method name='ReplyPinCode'>"
523 " <arg type='u' name='accept' direction='in'/>"
524 " <arg type='s' name='pincode' direction='in'/>"
526 " <method name='ReplyPasskey'>"
527 " <arg type='u' name='accept' direction='in'/>"
528 " <arg type='s' name='passkey' direction='in'/>"
530 " <method name='ReplyConfirmation'>"
531 " <arg type='u' name='accept' direction='in'/>"
533 " <method name='ReplyAuthorize'>"
534 " <arg type='u' name='accept' direction='in'/>"
536 " <method name='ConfirmModeChange'>"
537 " <arg type='s' name='mode' direction='in'/>"
539 " <method name='GetDiscoverableTimeout'>"
540 " <arg type='u' name='timeout' direction='out'/>"
545 static GDBusNodeInfo *__bt_service_create_method_node_info
546 (const gchar *introspection_data)
549 GDBusNodeInfo *node_info = NULL;
551 if (introspection_data == NULL)
554 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
557 ERR("Unable to create node: %s", err->message);
563 static void __bt_gap_agent_method(GDBusConnection *connection,
565 const gchar *object_path,
566 const gchar *interface_name,
567 const gchar *method_name,
568 GVariant *parameters,
569 GDBusMethodInvocation *invocation,
574 BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
575 method_name, object_path, interface_name);
579 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
580 GapAgentPrivate *agent = user_data;
581 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
585 GDBusConnection *conn;
590 g_variant_get(parameters, "(&o)", &path);
591 BT_INFO("Request pin code, Device Path :%s", path);
594 if (g_strcmp0(sender, agent->busname) != 0)
598 if (!agent->cb.passkey_func)
601 conn = _bt_get_system_gconn();
605 device = g_dbus_proxy_new_sync(conn,
606 G_DBUS_PROXY_FLAGS_NONE, NULL,
608 BT_PROPERTIES_INTERFACE, NULL, &err);
611 BT_ERR("Fail to make device proxy");
613 g_dbus_method_invocation_return_error(invocation,
614 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
615 "No proxy for device");
618 ERR("Unable to create proxy: %s", err->message);
625 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
626 agent->reply_context = invocation;
628 addr = strstr(path, "dev_");
632 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
634 while ((pos = strchr(agent->pairing_addr, '_')) != NULL) {
639 agent->cb.pincode_func(agent, device);
641 g_object_unref(device);
644 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
645 GapAgentPrivate *priv = user_data;
646 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
650 GDBusConnection *conn;
655 g_variant_get(parameters, "(&o)", &path);
656 BT_INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
657 sender, priv->busname, path);
660 if (g_strcmp0(sender, agent->busname) != 0)
664 if (!priv->cb.passkey_func)
667 conn = _bt_get_system_gconn();
671 device = g_dbus_proxy_new_sync(conn,
672 G_DBUS_PROXY_FLAGS_NONE, NULL,
674 BT_PROPERTIES_INTERFACE, NULL, &err);
677 BT_ERR("Fail to make device proxy");
679 g_dbus_method_invocation_return_error(invocation,
680 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
681 "No proxy for device");
684 ERR("Unable to create proxy: %s", err->message);
691 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
692 priv->reply_context = invocation;
694 addr = strstr(path, "dev_");
698 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
700 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
705 priv->cb.passkey_func(priv, device);
707 g_object_unref(device);
710 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
711 GapAgentPrivate *priv = user_data;
712 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
717 GDBusConnection *conn;
722 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
723 BT_INFO("Request passkey display :sender %s priv->busname %s"
724 " Device Path :%s, Passkey: %d, Entered: %d",
725 sender, priv->busname, path, passkey, entered);
727 /* Do not show popup for Key event while typing*/
732 if (g_strcmp0(sender, agent->busname) != 0)
736 if (!priv->cb.display_func)
739 conn = _bt_get_system_gconn();
743 device = g_dbus_proxy_new_sync(conn,
744 G_DBUS_PROXY_FLAGS_NONE, NULL,
746 BT_PROPERTIES_INTERFACE, NULL, &err);
749 BT_ERR("Fail to make device proxy");
751 g_dbus_method_invocation_return_error(invocation,
752 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
753 "No proxy for device");
756 ERR("Unable to create proxy: %s", err->message);
763 g_dbus_method_invocation_return_value(invocation, NULL);
765 priv->cb.display_func(priv, device, passkey);
767 g_object_unref(device);
770 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
771 GapAgentPrivate *priv = user_data;
772 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
777 GDBusConnection *conn;
782 g_variant_get(parameters, "(&ou)", &path, &passkey);
783 BT_INFO("Request passkey confirmation, Device Path :%s, Passkey: %d",
786 BT_DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
788 if (g_strcmp0(sender, agent->busname) != 0)
792 BT_DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
793 if (!priv->cb.confirm_func)
796 conn = _bt_get_system_gconn();
800 device = g_dbus_proxy_new_sync(conn,
801 G_DBUS_PROXY_FLAGS_NONE, NULL,
803 BT_PROPERTIES_INTERFACE, NULL, &err);
806 BT_ERR("Fail to make device proxy");
808 g_dbus_method_invocation_return_error(invocation,
809 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
810 "No proxy for device");
813 ERR("Unable to create proxy: %s", err->message);
820 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
821 priv->reply_context = invocation;
823 addr = strstr(path, "dev_");
827 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
829 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
834 priv->cb.confirm_func(priv, device, passkey);
836 g_object_unref(device);
839 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
840 GapAgentPrivate *priv = user_data;
841 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
843 GDBusConnection *conn;
851 g_variant_get(parameters, "(&o&s)", &path, &uuid);
852 BT_DBG("Request authorization :sender %s priv->busname %s "
853 "Device Path :%s UUID: %s",
854 sender, priv->busname, path, uuid);
857 if (g_strcmp0(sender, agent->busname) != 0)
861 if (!priv->cb.authorize_func)
864 conn = _bt_get_system_gconn();
868 device = g_dbus_proxy_new_sync(conn,
869 G_DBUS_PROXY_FLAGS_NONE, NULL,
871 BT_PROPERTIES_INTERFACE, NULL, &err);
874 BT_ERR("Fail to make device proxy");
876 g_dbus_method_invocation_return_error(invocation,
877 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
878 "No proxy for device");
881 ERR("Unable to create proxy: %s", err->message);
888 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
889 priv->reply_context = invocation;
891 addr = strstr(path, "dev_");
895 g_strlcpy(priv->authorize_addr, addr,
896 sizeof(priv->authorize_addr));
898 while ((pos = strchr(priv->authorize_addr, '_')) != NULL) {
903 priv->cb.authorize_func(priv, device, uuid);
905 g_object_unref(device);
908 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
909 g_dbus_method_invocation_return_value(invocation, NULL);
910 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
911 g_dbus_method_invocation_return_value(invocation, NULL);
912 } else if (g_strcmp0(method_name, "Cancel") == 0) {
913 GapAgentPrivate *priv = user_data;
914 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
919 BT_DBG("Cancelled : agent %p sender %s", sender);
922 if (g_strcmp0(sender, agent->busname) != 0)
926 if (priv->cb.authorization_cancel_func &&
927 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
928 priv->cb.authorization_cancel_func(priv,
929 priv->authorize_addr);
930 memset(priv->authorize_addr, 0x00,
931 sizeof(priv->authorize_addr));
932 } else if (priv->cb.pairing_cancel_func &&
933 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
934 priv->cb.pairing_cancel_func(priv,
936 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
939 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
940 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
941 priv->reply_context != NULL) {
943 g_dbus_method_invocation_return_error(priv->reply_context,
944 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
945 "Rejected by remote cancel");
948 /* Canceled flag is set when user cancels pairing request
949 * Since here bluez has cancelled pairing request, we set the flag to false
951 priv->canceled = FALSE;
952 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
953 priv->reply_context = NULL;
956 } else if (g_strcmp0(method_name, "Release") == 0) {
957 GapAgentPrivate *priv = user_data;
958 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
963 BT_DBG("Released : sender %s\n", sender);
966 if (g_strcmp0(sender, agent->busname) != 0)
970 g_dbus_method_invocation_return_value(invocation, NULL);
972 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
973 priv->reply_context = NULL;
975 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
976 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
979 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
984 _bt_get_timeout_value(&timeout);
986 g_dbus_method_invocation_return_value(invocation,
987 g_variant_new("(i)", timeout));
992 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
993 GapAgentPrivate *priv = user_data;
994 const char *pin_code;
997 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
998 BT_DBG("Accept: %d PinCode: %s", accept, pin_code);
999 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
1000 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
1001 GapAgentPrivate *priv = user_data;
1002 const char *passkey;
1005 g_variant_get(parameters, "(u&s)", &accept, &passkey);
1006 BT_DBG("Accept: %d PinCode: %s", accept, passkey);
1007 gap_agent_reply_passkey(priv, accept, passkey, invocation);
1008 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
1009 GapAgentPrivate *priv = user_data;
1012 g_variant_get(parameters, "(u)", &accept);
1013 BT_DBG("Accept: %d", accept);
1014 gap_agent_reply_confirmation(priv, accept, invocation);
1015 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
1016 GapAgentPrivate *priv = user_data;
1019 g_variant_get(parameters, "(u)", &accept);
1020 BT_DBG("Accept: %d", accept);
1021 gap_agent_reply_authorize(priv, accept, invocation);
1025 static const GDBusInterfaceVTable method_table = {
1026 __bt_gap_agent_method,
1031 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
1033 GDBusProxy *adapter)
1035 GapAgentPrivate *priv = agent;
1037 GDBusNodeInfo *node_info;
1038 GError *error = NULL;
1041 priv->path = g_strdup(path);
1044 node_info = __bt_service_create_method_node_info(
1045 gap_agent_bluez_introspection_xml);
1046 if (node_info == NULL)
1049 BT_DBG("path is [%s]", path);
1051 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1054 ERR("Unable to connect to gdbus: %s", error->message);
1055 g_clear_error(&error);
1060 if (gap_agent_id == -1) {
1061 gap_agent_id = g_dbus_connection_register_object(connection, path,
1062 node_info->interfaces[0],
1063 &method_table, priv,
1067 g_dbus_node_info_unref(node_info);
1069 if (gap_agent_id == 0) {
1070 BT_ERR("Failed to register for Path: %s", path);
1072 BT_ERR("Failed to register: %s", error->message);
1073 g_clear_error(&error);
1078 memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
1080 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1081 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1082 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1083 priv->reply_context = NULL;
1085 BT_DBG("path: %s", path);
1087 proxy = g_dbus_proxy_new_sync(connection,
1088 G_DBUS_PROXY_FLAGS_NONE, NULL,
1089 BT_BLUEZ_NAME, path,
1090 BT_AGENT_INTERFACE, NULL, &error);
1093 ERR("Unable to create proxy");
1095 ERR("Error: %s", error->message);
1096 g_clear_error(&error);
1098 priv->busname = NULL;
1100 priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
1101 g_object_unref(proxy);
1102 BT_DBG("Busname: %s", priv->busname);
1107 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
1109 GapAgentPrivate *priv = agent;
1111 /* Fix : NULL_RETURNS */
1115 __gap_agent_unregister(agent);
1117 if (gap_agent_id > 0) {
1118 g_dbus_connection_unregister_object(connection,
1123 if (priv->osp_servers) {
1124 __gap_agent_remove_osp_servers(priv->osp_servers);
1125 g_slist_free(priv->osp_servers);
1126 priv->osp_servers = NULL;
1129 g_object_ref(priv->adapter);
1130 priv->adapter = NULL;
1135 g_free(priv->busname);
1136 priv->busname = NULL;
1139 gboolean _gap_agent_exist_osp_server(GapAgentPrivate *agent, int type, char *uuid)
1141 GapAgentPrivate *priv = agent;
1143 /* Fix : NULL_RETURNS */
1144 retv_if(priv == NULL, FALSE);
1146 if (__gap_agent_find_server(priv->osp_servers,
1147 type, uuid) != NULL) {
1154 bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgentPrivate *agent, int type,
1157 GapAgentPrivate *priv = agent;
1158 bt_agent_osp_server_t *osp_serv = NULL;
1162 osp_serv = __gap_agent_find_server(priv->osp_servers,
1171 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
1173 GapAgentPrivate *priv = agent;
1175 /* Fix : NULL_RETURNS */
1182 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
1184 GapAgentPrivate *priv = agent;
1186 /* Fix : NULL_RETURNS */
1187 retv_if(priv == NULL, FALSE);
1189 return priv->canceled;
1192 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
1194 GapAgentPrivate *priv = agent;
1196 /* Fix : NULL_RETURNS */
1200 priv->canceled = value;