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.
22 #include <vconf-keys.h>
24 #include "bt-internal-types.h"
25 #include "bt-service-common.h"
26 #include "bt-service-agent.h"
27 #include "bt-service-gap-agent.h"
28 #include "bt-service-adapter.h"
29 #include "bt-service-device.h"
31 static GDBusConnection *connection = NULL;
34 GAP_AGENT_ERROR_REJECT,
35 GAP_AGENT_ERROR_CANCEL,
36 GAP_AGENT_ERROR_TIMEOUT,
39 #define GAP_AGENT_ERROR (gap_agent_error_quark())
41 static GQuark gap_agent_error_quark(void)
43 static GQuark quark = 0;
45 quark = g_quark_from_static_string("agent");
50 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
52 static gint gap_agent_id = -1;
54 static bt_agent_osp_server_t *__gap_agent_find_server(GSList *servers,
59 bt_agent_osp_server_t *transfer;
61 for (l = servers; l != NULL; l = l->next) {
67 /* No uuid in obex server */
68 if (type == BT_OBEX_SERVER &&
69 transfer->type == BT_OBEX_SERVER)
72 if (g_strcmp0(transfer->uuid, uuid) == 0)
79 static void __gap_agent_remove_osp_servers(GSList *osp_servers)
82 bt_agent_osp_server_t *server;
84 for (l = osp_servers; l != NULL; l = g_slist_next(l)) {
95 gboolean _gap_agent_register_osp_server(GapAgentPrivate *agent,
101 bt_agent_osp_server_t *server;
105 GapAgentPrivate *priv = agent;
110 /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
111 if (type > BT_RFCOMM_SERVER)
114 server = g_malloc0(sizeof(bt_agent_osp_server_t));
115 retv_if(server == NULL, FALSE);
118 if (type == BT_RFCOMM_SERVER) {
119 server->uuid = g_strdup(uuid);
120 server->path = g_strdup(path);
124 priv->osp_servers = g_slist_append(priv->osp_servers, server);
131 gboolean _gap_agent_unregister_osp_server(GapAgentPrivate *agent,
135 bt_agent_osp_server_t *server;
139 GapAgentPrivate *priv = agent;
144 /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
145 if (type > BT_RFCOMM_SERVER)
148 server = __gap_agent_find_server(priv->osp_servers, type, uuid);
153 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
155 g_free(server->uuid);
163 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
164 const char *pin_code,
165 GDBusMethodInvocation *context)
169 GapAgentPrivate *priv = agent;
170 retv_if(priv == NULL, FALSE);
172 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
173 priv->reply_context != NULL) {
174 if (accept == GAP_AGENT_ACCEPT) {
175 g_dbus_method_invocation_return_value(priv->reply_context,
176 g_variant_new("(s)", pin_code));
177 priv->canceled = FALSE;
180 case GAP_AGENT_CANCEL:
181 g_dbus_method_invocation_return_error(priv->reply_context,
182 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
184 priv->canceled = TRUE;
186 case GAP_AGENT_TIMEOUT:
187 case GAP_AGENT_REJECT:
189 g_dbus_method_invocation_return_error(priv->reply_context,
190 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
191 "Pairing request rejected");
192 priv->canceled = FALSE;
198 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
199 priv->reply_context = NULL;
200 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
207 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
209 GDBusMethodInvocation *context)
213 GapAgentPrivate *priv = agent;
214 retv_if(priv == NULL, FALSE);
216 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
217 priv->reply_context != NULL) {
218 if (accept == GAP_AGENT_ACCEPT) {
219 guint pass_key = atoi(passkey);
220 g_dbus_method_invocation_return_value(priv->reply_context,
221 g_variant_new("(u)", pass_key));
222 priv->canceled = FALSE;
225 case GAP_AGENT_CANCEL:
226 g_dbus_method_invocation_return_error(priv->reply_context,
227 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
229 priv->canceled = TRUE;
231 case GAP_AGENT_TIMEOUT:
232 case GAP_AGENT_REJECT:
234 g_dbus_method_invocation_return_error(priv->reply_context,
235 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
236 "Passkey request rejected");
237 priv->canceled = FALSE;
243 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
244 priv->reply_context = NULL;
245 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
252 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
253 GDBusMethodInvocation *context)
257 GapAgentPrivate *priv = agent;
258 retv_if(priv == NULL, FALSE);
260 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
261 priv->reply_context != NULL) {
262 if (accept == GAP_AGENT_ACCEPT) {
263 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
264 priv->canceled = FALSE;
267 case GAP_AGENT_CANCEL:
268 g_dbus_method_invocation_return_error(priv->reply_context,
269 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
271 priv->canceled = TRUE;
273 case GAP_AGENT_TIMEOUT:
274 case GAP_AGENT_REJECT:
276 g_dbus_method_invocation_return_error(priv->reply_context,
277 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
278 "Confirmation request rejected");
279 priv->canceled = FALSE;
285 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
286 priv->reply_context = NULL;
287 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
294 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
295 GDBusMethodInvocation *context)
301 GapAgentPrivate *priv = agent;
302 retv_if(priv == NULL, FALSE);
304 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
305 priv->reply_context != NULL) {
306 if (accept == GAP_AGENT_ACCEPT) {
307 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
308 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
309 bluetooth_device_address_t addr = { { 0, } };
312 _bt_convert_addr_string_to_type(addr.addr,
313 priv->authorize_addr);
315 /* Do not set device as Trusted*/
316 /* result = _bt_set_authorization(&addr, TRUE); */
317 result = _bt_set_trust_profile(&addr,
318 _bt_get_trusted_profile_enum(priv->uuid),
320 if (result == BLUETOOTH_ERROR_NONE) {
321 BT_INFO("[%s] Profile added as trusted for Device[%s]",
322 priv->uuid, priv->authorize_addr);
325 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
328 case GAP_AGENT_CANCEL:
329 g_dbus_method_invocation_return_error(priv->reply_context,
330 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
333 case GAP_AGENT_REJECT: {
334 bluetooth_device_address_t addr = { { 0, } };
337 _bt_convert_addr_string_to_type(addr.addr,
338 priv->authorize_addr);
340 /* Set Profile as blocked */
341 result = _bt_set_trust_profile(&addr,
342 _bt_get_trusted_profile_enum(priv->uuid),
344 if (result == BLUETOOTH_ERROR_NONE) {
345 BT_INFO("[%s] Profile added as blocked for Device[%s]",
346 priv->uuid, priv->authorize_addr);
349 g_dbus_method_invocation_return_error(priv->reply_context,
350 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
351 "Authorization request rejected");
354 case GAP_AGENT_TIMEOUT:
356 g_dbus_method_invocation_return_error(priv->reply_context,
357 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
358 "Authorization request rejected");
364 g_dbus_method_invocation_return_value(context, NULL);
366 BT_ERR("No context");
369 g_dbus_method_invocation_return_error(context,
370 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
375 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION) {
376 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
377 priv->reply_context = NULL;
378 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
388 gboolean _gap_agent_register(GapAgentPrivate *agent)
390 GapAgentPrivate *priv = agent;
391 GDBusProxy *agent_manager;
392 GError *error = NULL;
395 retv_if(priv == NULL, FALSE);
396 retv_if(connection == NULL, FALSE);
398 if (priv->agent_manager == NULL) {
399 agent_manager = g_dbus_proxy_new_sync(connection,
400 G_DBUS_PROXY_FLAGS_NONE, NULL,
401 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
402 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
403 if (!agent_manager) {
405 ERR("Unable to create proxy: %s", error->message);
406 g_clear_error(&error);
411 agent_manager = priv->agent_manager;
414 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
415 #ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
416 g_variant_new("(os)", priv->path, "NoInputNoOutput"),
417 #elif defined(TIZEN_BT_IO_CAPA_DISPLAY_ONLY)
418 g_variant_new("(os)", priv->path, "DisplayOnly"),
420 g_variant_new("(os)", priv->path, "KeyboardDisplay"),
422 G_DBUS_CALL_FLAGS_NONE, -1,
425 BT_ERR("Agent registration failed");
427 BT_ERR("Agent registration failed: errCode[%x], message[%s]",
428 error->code, error->message);
429 g_clear_error(&error);
431 g_object_unref(agent_manager);
432 priv->agent_manager = NULL;
435 g_variant_unref(reply);
438 /* Set the defalut agent */
439 BT_DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
440 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
441 g_variant_new("(o)", priv->path),
442 G_DBUS_CALL_FLAGS_NONE, -1,
445 ERR("Request Default Agent failed");
447 ERR("Request Default Agent failed: errCode[%x], message[%s]",
448 error->code, error->message);
449 g_clear_error(&error);
451 g_object_unref(agent_manager);
452 priv->agent_manager = NULL;
455 g_variant_unref(reply);
457 priv->agent_manager = agent_manager;
462 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
464 GapAgentPrivate *priv = agent;
465 GDBusProxy *agent_manager;
466 GError *error = NULL;
469 retv_if(priv == NULL, FALSE);
470 retv_if(priv->path == NULL, FALSE);
471 retv_if(connection == NULL, FALSE);
473 if (priv->agent_manager == NULL) {
474 agent_manager = g_dbus_proxy_new_sync(connection,
475 G_DBUS_PROXY_FLAGS_NONE, NULL,
476 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
477 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
478 if (!agent_manager) {
480 ERR("Unable to create proxy: %s", error->message);
481 g_clear_error(&error);
486 agent_manager = priv->agent_manager;
489 reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
490 g_variant_new("(o)", priv->path),
491 G_DBUS_CALL_FLAGS_NONE, -1,
493 g_object_unref(agent_manager);
494 priv->agent_manager = NULL;
497 ERR("Agent unregistration failed");
499 ERR("Agent unregistration failed: errCode[%x], message[%s]",
500 error->code, error->message);
501 g_clear_error(&error);
505 g_variant_unref(reply);
510 static const gchar gap_agent_bluez_introspection_xml[] =
512 " <interface name='org.bluez.Agent1'>"
513 " <method name='RequestConfirmation'>"
514 " <arg type='o' name='target' direction='in'/>"
515 " <arg type='u' name='passkey' direction='in'/>"
517 " <method name='RequestPinCode'>"
518 " <arg type='o' name='target' direction='in'/>"
519 " <arg type='s' name='pincode' direction='out'/>"
521 " <method name='RequestAuthorization'>"
522 " <arg type='o' name='target' direction='in'/>"
524 " <method name='RequestPasskey'>"
525 " <arg type='o' name='target' direction='in'/>"
526 " <arg type='u' name='passkey' direction='out'/>"
528 " <method name='AuthorizeService'>"
529 " <arg type='o' name='target' direction='in'/>"
530 " <arg type='s' name='uuid' direction='in'/>"
532 " <method name='DisplayPasskey'>"
533 " <arg type='o' name='target' direction='in'/>"
534 " <arg type='u' name='passkey' direction='in'/>"
535 " <arg type='q' name='entered' direction='in'/>"
537 " <method name='ReplyConfirmation'>"
538 " <arg type='u' name='accept' direction='in'/>"
540 " <method name='ReplyPinCode'>"
541 " <arg type='u' name='accept' direction='in'/>"
542 " <arg type='s' name='pincode' direction='in'/>"
544 " <method name='ReplyAuthorize'>"
545 " <arg type='u' name='accept' direction='in'/>"
547 " <method name='ReplyPasskey'>"
548 " <arg type='u' name='accept' direction='in'/>"
549 " <arg type='s' name='passkey' direction='in'/>"
551 " <method name='GetDiscoverableTimeout'>"
552 " <arg type='u' name='timeout' direction='out'/>"
554 " <method name='ConfirmModeChange'>"
555 " <arg type='s' name='mode' direction='in'/>"
557 " <method name='Cancel'>"
559 " <method name='Release'>"
564 static GDBusNodeInfo *__bt_service_create_method_node_info
565 (const gchar *introspection_data)
568 GDBusNodeInfo *node_info = NULL;
570 if (introspection_data == NULL)
573 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
576 ERR("Unable to create node: %s", err->message);
582 static void __bt_gap_agent_method(GDBusConnection *connection,
584 const gchar *object_path,
585 const gchar *interface_name,
586 const gchar *method_name,
587 GVariant *parameters,
588 GDBusMethodInvocation *invocation,
593 BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
594 method_name, object_path, interface_name);
598 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
599 GapAgentPrivate *agent = user_data;
600 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
604 GDBusConnection *conn;
609 g_variant_get(parameters, "(&o)", &path);
610 BT_INFO("Request pin code, Device Path :%s", path);
613 if (g_strcmp0(sender, agent->busname) != 0)
617 if (!agent->cb.passkey_func)
620 conn = _bt_gdbus_get_system_gconn();
624 device = g_dbus_proxy_new_sync(conn,
625 G_DBUS_PROXY_FLAGS_NONE, NULL,
627 BT_PROPERTIES_INTERFACE, NULL, &err);
630 BT_ERR("Fail to make device proxy");
632 g_dbus_method_invocation_return_error(invocation,
633 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
634 "No proxy for device");
637 ERR("Unable to create proxy: %s", err->message);
644 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
645 agent->reply_context = invocation;
647 addr = strstr(path, "dev_");
651 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
653 while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
657 agent->cb.pincode_func(agent, device);
659 g_object_unref(device);
662 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
663 GapAgentPrivate *priv = user_data;
664 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
668 GDBusConnection *conn;
673 g_variant_get(parameters, "(&o)", &path);
674 BT_INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
675 sender, priv->busname, path);
678 if (g_strcmp0(sender, agent->busname) != 0)
682 if (!priv->cb.passkey_func)
685 conn = _bt_gdbus_get_system_gconn();
689 device = g_dbus_proxy_new_sync(conn,
690 G_DBUS_PROXY_FLAGS_NONE, NULL,
692 BT_PROPERTIES_INTERFACE, NULL, &err);
695 BT_ERR("Fail to make device proxy");
697 g_dbus_method_invocation_return_error(invocation,
698 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
699 "No proxy for device");
702 ERR("Unable to create proxy: %s", err->message);
709 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
710 priv->reply_context = invocation;
712 addr = strstr(path, "dev_");
716 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
718 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
722 priv->cb.passkey_func(priv, device);
724 g_object_unref(device);
727 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
728 GapAgentPrivate *priv = user_data;
729 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
734 GDBusConnection *conn;
739 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
740 BT_INFO("Request passkey display :sender %s priv->busname %s"
741 " Device Path :%s, Passkey: %06d, Entered: %d",
742 sender, priv->busname, path, passkey, entered);
744 /* Do not show popup for Key event while typing*/
749 if (g_strcmp0(sender, agent->busname) != 0)
753 if (!priv->cb.display_func)
756 conn = _bt_gdbus_get_system_gconn();
760 device = g_dbus_proxy_new_sync(conn,
761 G_DBUS_PROXY_FLAGS_NONE, NULL,
763 BT_PROPERTIES_INTERFACE, NULL, &err);
766 BT_ERR("Fail to make device proxy");
768 g_dbus_method_invocation_return_error(invocation,
769 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
770 "No proxy for device");
773 ERR("Unable to create proxy: %s", err->message);
780 g_dbus_method_invocation_return_value(invocation, NULL);
782 priv->cb.display_func(priv, device, passkey);
784 g_object_unref(device);
787 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
788 GapAgentPrivate *priv = user_data;
789 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
794 GDBusConnection *conn;
799 g_variant_get(parameters, "(&ou)", &path, &passkey);
800 BT_INFO_C("### Request passkey confirmation");
801 INFO_SECURE("Device Path :%s, Passkey: %d", path, passkey);
803 BT_DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
805 if (g_strcmp0(sender, agent->busname) != 0)
809 BT_DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
810 if (!priv->cb.confirm_func)
813 conn = _bt_gdbus_get_system_gconn();
817 device = g_dbus_proxy_new_sync(conn,
818 G_DBUS_PROXY_FLAGS_NONE, NULL,
820 BT_PROPERTIES_INTERFACE, NULL, &err);
823 BT_ERR("Fail to make device proxy");
825 g_dbus_method_invocation_return_error(invocation,
826 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
827 "No proxy for device");
830 ERR("Unable to create proxy: %s", err->message);
837 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
838 priv->reply_context = invocation;
840 addr = strstr(path, "dev_");
844 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
846 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
850 priv->cb.confirm_func(priv, device, passkey);
852 g_object_unref(device);
855 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
856 GapAgentPrivate *priv = user_data;
857 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
859 GDBusConnection *conn;
867 g_variant_get(parameters, "(&o&s)", &path, &uuid);
868 BT_DBG("Request authorization :sender %s priv->busname %s "
869 "Device Path :%s UUID: %s",
870 sender, priv->busname, path, uuid);
873 if (g_strcmp0(sender, agent->busname) != 0)
877 if (!priv->cb.authorize_func)
880 conn = _bt_gdbus_get_system_gconn();
884 device = g_dbus_proxy_new_sync(conn,
885 G_DBUS_PROXY_FLAGS_NONE, NULL,
887 BT_PROPERTIES_INTERFACE, NULL, &err);
890 BT_ERR("Fail to make device proxy");
892 g_dbus_method_invocation_return_error(invocation,
893 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
894 "No proxy for device");
897 ERR("Unable to create proxy: %s", err->message);
904 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
905 priv->reply_context = invocation;
906 priv->uuid = g_strdup(uuid);
908 addr = strstr(path, "dev_");
912 g_strlcpy(priv->authorize_addr, addr,
913 sizeof(priv->authorize_addr));
915 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
919 priv->cb.authorize_func(priv, device, uuid);
921 g_object_unref(device);
924 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
925 g_dbus_method_invocation_return_value(invocation, NULL);
926 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
927 g_dbus_method_invocation_return_value(invocation, NULL);
928 } else if (g_strcmp0(method_name, "Cancel") == 0) {
929 GapAgentPrivate *priv = user_data;
930 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
935 BT_DBG("Cancelled : agent %p sender %s", sender);
938 if (g_strcmp0(sender, agent->busname) != 0)
942 if (priv->cb.authorization_cancel_func &&
943 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
944 priv->cb.authorization_cancel_func(priv,
945 priv->authorize_addr);
946 memset(priv->authorize_addr, 0x00,
947 sizeof(priv->authorize_addr));
948 } else if (priv->cb.pairing_cancel_func &&
949 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
950 priv->cb.pairing_cancel_func(priv,
952 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
955 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
956 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
957 priv->reply_context != NULL) {
959 g_dbus_method_invocation_return_error(priv->reply_context,
960 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
961 "Rejected by remote cancel");
964 /* Canceled flag is set when user cancels pairing request
965 * Since here bluez has cancelled pairing request, we set the flag to false
967 priv->canceled = FALSE;
968 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
969 priv->reply_context = NULL;
972 } else if (g_strcmp0(method_name, "Release") == 0) {
973 GapAgentPrivate *priv = user_data;
974 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
979 BT_DBG("Released : sender %s\n", sender);
982 if (g_strcmp0(sender, agent->busname) != 0)
986 g_dbus_method_invocation_return_value(invocation, NULL);
988 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
989 priv->reply_context = NULL;
991 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
992 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
995 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
1000 _bt_get_timeout_value(&timeout);
1002 g_dbus_method_invocation_return_value(invocation,
1003 g_variant_new("(i)", timeout));
1008 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
1009 GapAgentPrivate *priv = user_data;
1010 const char *pin_code;
1013 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
1014 BT_DBG("Accept: %d PinCode: %s", accept, pin_code);
1015 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
1016 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
1017 GapAgentPrivate *priv = user_data;
1018 const char *passkey;
1021 g_variant_get(parameters, "(u&s)", &accept, &passkey);
1022 BT_DBG("Accept: %d PinCode: %s", accept, passkey);
1023 gap_agent_reply_passkey(priv, accept, passkey, invocation);
1024 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
1025 GapAgentPrivate *priv = user_data;
1028 g_variant_get(parameters, "(u)", &accept);
1029 BT_DBG("Accept: %d", accept);
1030 gap_agent_reply_confirmation(priv, accept, invocation);
1031 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
1032 GapAgentPrivate *priv = user_data;
1035 g_variant_get(parameters, "(u)", &accept);
1036 BT_DBG("Accept: %d", accept);
1037 gap_agent_reply_authorize(priv, accept, invocation);
1041 static const GDBusInterfaceVTable method_table = {
1042 __bt_gap_agent_method,
1047 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
1049 GDBusProxy *adapter)
1051 GapAgentPrivate *priv = agent;
1053 GDBusNodeInfo *node_info;
1054 GError *error = NULL;
1056 priv->path = g_strdup(path);
1059 node_info = __bt_service_create_method_node_info(
1060 gap_agent_bluez_introspection_xml);
1061 if (node_info == NULL)
1064 BT_DBG("path is [%s]", path);
1066 if (connection == NULL) {
1067 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1070 ERR("Unable to connect to gdbus: %s", error->message);
1071 g_clear_error(&error);
1073 g_dbus_node_info_unref(node_info);
1078 if (gap_agent_id == -1) {
1079 gap_agent_id = g_dbus_connection_register_object(connection, path,
1080 node_info->interfaces[0],
1081 &method_table, priv,
1085 g_dbus_node_info_unref(node_info);
1087 if (gap_agent_id == 0) {
1088 BT_ERR("Failed to register for Path: %s", path);
1090 BT_ERR("Failed to register: %s", error->message);
1091 g_clear_error(&error);
1096 memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
1098 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1099 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1100 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1101 priv->reply_context = NULL;
1103 BT_DBG("path: %s", path);
1105 proxy = g_dbus_proxy_new_sync(connection,
1106 G_DBUS_PROXY_FLAGS_NONE, NULL,
1107 BT_BLUEZ_NAME, path,
1108 BT_AGENT_INTERFACE, NULL, &error);
1111 ERR("Unable to create proxy");
1113 ERR("Error: %s", error->message);
1114 g_clear_error(&error);
1116 priv->busname = NULL;
1118 priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
1119 g_object_unref(proxy);
1120 BT_DBG("Busname: %s", priv->busname);
1125 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
1127 GapAgentPrivate *priv = agent;
1131 __gap_agent_unregister(agent);
1133 if (gap_agent_id > 0) {
1134 g_dbus_connection_unregister_object(connection,
1140 g_object_unref(connection);
1144 if (priv->osp_servers) {
1145 __gap_agent_remove_osp_servers(priv->osp_servers);
1146 g_slist_free(priv->osp_servers);
1147 priv->osp_servers = NULL;
1153 g_free(priv->busname);
1154 priv->busname = NULL;
1157 gboolean _gap_agent_exist_osp_server(GapAgentPrivate *agent, int type, char *uuid)
1159 GapAgentPrivate *priv = agent;
1164 if (__gap_agent_find_server(priv->osp_servers,
1165 type, uuid) != NULL) {
1172 bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgentPrivate *agent, int type,
1175 GapAgentPrivate *priv = agent;
1176 bt_agent_osp_server_t *osp_serv = NULL;
1180 osp_serv = __gap_agent_find_server(priv->osp_servers,
1188 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
1190 GapAgentPrivate *priv = agent;
1197 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
1199 GapAgentPrivate *priv = agent;
1201 return priv->canceled;
1204 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
1206 GapAgentPrivate *priv = agent;
1210 priv->canceled = value;