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));
116 if (type == BT_RFCOMM_SERVER) {
117 server->uuid = g_strdup(uuid);
118 server->path = g_strdup(path);
122 priv->osp_servers = g_slist_append(priv->osp_servers, server);
129 gboolean _gap_agent_unregister_osp_server(GapAgentPrivate *agent,
133 bt_agent_osp_server_t *server;
137 GapAgentPrivate *priv = agent;
142 /* type: BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
143 if (type > BT_RFCOMM_SERVER)
146 server = __gap_agent_find_server(priv->osp_servers, type, uuid);
151 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
153 g_free(server->uuid);
161 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
162 const char *pin_code,
163 GDBusMethodInvocation *context)
167 GapAgentPrivate *priv = agent;
168 retv_if(priv == NULL, FALSE);
170 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
171 priv->reply_context != NULL) {
172 if (accept == GAP_AGENT_ACCEPT) {
173 g_dbus_method_invocation_return_value(priv->reply_context,
174 g_variant_new("(s)", pin_code));
175 priv->canceled = FALSE;
178 case GAP_AGENT_CANCEL:
179 g_dbus_method_invocation_return_error(priv->reply_context,
180 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
182 priv->canceled = TRUE;
184 case GAP_AGENT_TIMEOUT:
185 case GAP_AGENT_REJECT:
187 g_dbus_method_invocation_return_error(priv->reply_context,
188 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
189 "Pairing request rejected");
190 priv->canceled = FALSE;
196 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
197 priv->reply_context = NULL;
198 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
205 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
207 GDBusMethodInvocation *context)
211 GapAgentPrivate *priv = agent;
212 retv_if(priv == NULL, FALSE);
214 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
215 priv->reply_context != NULL) {
216 if (accept == GAP_AGENT_ACCEPT) {
217 guint pass_key = atoi(passkey);
218 g_dbus_method_invocation_return_value(priv->reply_context,
219 g_variant_new("(u)", pass_key));
220 priv->canceled = FALSE;
223 case GAP_AGENT_CANCEL:
224 g_dbus_method_invocation_return_error(priv->reply_context,
225 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
227 priv->canceled = TRUE;
229 case GAP_AGENT_TIMEOUT:
230 case GAP_AGENT_REJECT:
232 g_dbus_method_invocation_return_error(priv->reply_context,
233 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
234 "Passkey request rejected");
235 priv->canceled = FALSE;
241 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
242 priv->reply_context = NULL;
243 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
250 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
251 GDBusMethodInvocation *context)
255 GapAgentPrivate *priv = agent;
256 retv_if(priv == NULL, FALSE);
258 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
259 priv->reply_context != NULL) {
260 if (accept == GAP_AGENT_ACCEPT) {
261 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
262 priv->canceled = FALSE;
265 case GAP_AGENT_CANCEL:
266 g_dbus_method_invocation_return_error(priv->reply_context,
267 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
269 priv->canceled = TRUE;
271 case GAP_AGENT_TIMEOUT:
272 case GAP_AGENT_REJECT:
274 g_dbus_method_invocation_return_error(priv->reply_context,
275 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
276 "Confirmation request rejected");
277 priv->canceled = FALSE;
283 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
284 priv->reply_context = NULL;
285 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
292 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
293 GDBusMethodInvocation *context)
299 GapAgentPrivate *priv = agent;
300 retv_if(priv == NULL, FALSE);
302 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
303 priv->reply_context != NULL) {
304 if (accept == GAP_AGENT_ACCEPT) {
305 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
306 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
307 bluetooth_device_address_t addr = { { 0, } };
310 _bt_convert_addr_string_to_type(addr.addr,
311 priv->authorize_addr);
313 /* Do not set device as Trusted*/
314 /* result = _bt_set_authorization(&addr, TRUE); */
315 result = _bt_set_trust_profile(&addr,
316 _bt_get_trusted_profile_enum(priv->uuid),
318 if (result == BLUETOOTH_ERROR_NONE) {
319 BT_INFO("[%s] Profile added as trusted for Device[%s]",
320 priv->uuid, priv->authorize_addr);
323 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
326 case GAP_AGENT_CANCEL:
327 g_dbus_method_invocation_return_error(priv->reply_context,
328 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
331 case GAP_AGENT_REJECT: {
332 bluetooth_device_address_t addr = { { 0, } };
335 _bt_convert_addr_string_to_type(addr.addr,
336 priv->authorize_addr);
338 /* Set Profile as blocked */
339 result = _bt_set_trust_profile(&addr,
340 _bt_get_trusted_profile_enum(priv->uuid),
342 if (result == BLUETOOTH_ERROR_NONE) {
343 BT_INFO("[%s] Profile added as blocked for Device[%s]",
344 priv->uuid, priv->authorize_addr);
347 g_dbus_method_invocation_return_error(priv->reply_context,
348 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
349 "Authorization request rejected");
352 case GAP_AGENT_TIMEOUT:
354 g_dbus_method_invocation_return_error(priv->reply_context,
355 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
356 "Authorization request rejected");
362 g_dbus_method_invocation_return_value(context, NULL);
364 BT_ERR("No context");
367 g_dbus_method_invocation_return_error(context,
368 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
373 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION) {
374 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
375 priv->reply_context = NULL;
376 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
386 gboolean _gap_agent_register(GapAgentPrivate *agent)
388 GapAgentPrivate *priv = agent;
389 GDBusProxy *agent_manager;
390 GError *error = NULL;
393 retv_if(priv == NULL, FALSE);
394 retv_if(connection == NULL, FALSE);
396 if (priv->agent_manager == NULL) {
397 agent_manager = g_dbus_proxy_new_sync(connection,
398 G_DBUS_PROXY_FLAGS_NONE, NULL,
399 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
400 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
401 if (!agent_manager) {
403 ERR("Unable to create proxy: %s", error->message);
404 g_clear_error(&error);
409 agent_manager = priv->agent_manager;
412 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
413 #ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
414 g_variant_new("(os)", priv->path, "NoInputNoOutput"),
415 #elif defined(TIZEN_BT_IO_CAPA_DISPLAY_ONLY)
416 g_variant_new("(os)", priv->path, "DisplayOnly"),
418 g_variant_new("(os)", priv->path, "KeyboardDisplay"),
420 G_DBUS_CALL_FLAGS_NONE, -1,
423 BT_ERR("Agent registration failed");
425 BT_ERR("Agent registration failed: errCode[%x], message[%s]",
426 error->code, error->message);
427 g_clear_error(&error);
429 g_object_unref(agent_manager);
430 priv->agent_manager = NULL;
433 g_variant_unref(reply);
436 /* Set the defalut agent */
437 BT_DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
438 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
439 g_variant_new("(o)", priv->path),
440 G_DBUS_CALL_FLAGS_NONE, -1,
443 ERR("Request Default Agent failed");
445 ERR("Request Default Agent failed: errCode[%x], message[%s]",
446 error->code, error->message);
447 g_clear_error(&error);
449 g_object_unref(agent_manager);
450 priv->agent_manager = NULL;
453 g_variant_unref(reply);
455 priv->agent_manager = agent_manager;
460 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
462 GapAgentPrivate *priv = agent;
463 GDBusProxy *agent_manager;
464 GError *error = NULL;
467 retv_if(priv == NULL, FALSE);
468 retv_if(priv->path == NULL, FALSE);
469 retv_if(connection == NULL, FALSE);
471 if (priv->agent_manager == NULL) {
472 agent_manager = g_dbus_proxy_new_sync(connection,
473 G_DBUS_PROXY_FLAGS_NONE, NULL,
474 BT_BLUEZ_NAME, BT_BLUEZ_PATH,
475 BT_AGENT_MANAGER_INTERFACE, NULL, &error);
476 if (!agent_manager) {
478 ERR("Unable to create proxy: %s", error->message);
479 g_clear_error(&error);
484 agent_manager = priv->agent_manager;
487 reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
488 g_variant_new("(o)", priv->path),
489 G_DBUS_CALL_FLAGS_NONE, -1,
491 g_object_unref(agent_manager);
492 priv->agent_manager = NULL;
495 ERR("Agent unregistration failed");
497 ERR("Agent unregistration failed: errCode[%x], message[%s]",
498 error->code, error->message);
499 g_clear_error(&error);
503 g_variant_unref(reply);
508 static const gchar gap_agent_bluez_introspection_xml[] =
510 " <interface name='org.bluez.Agent1'>"
511 " <method name='RequestConfirmation'>"
512 " <arg type='o' name='target' direction='in'/>"
513 " <arg type='u' name='passkey' direction='in'/>"
515 " <method name='RequestPinCode'>"
516 " <arg type='o' name='target' direction='in'/>"
517 " <arg type='s' name='pincode' direction='out'/>"
519 " <method name='RequestAuthorization'>"
520 " <arg type='o' name='target' direction='in'/>"
522 " <method name='RequestPasskey'>"
523 " <arg type='o' name='target' direction='in'/>"
524 " <arg type='u' name='passkey' direction='out'/>"
526 " <method name='AuthorizeService'>"
527 " <arg type='o' name='target' direction='in'/>"
528 " <arg type='s' name='uuid' direction='in'/>"
530 " <method name='DisplayPasskey'>"
531 " <arg type='o' name='target' direction='in'/>"
532 " <arg type='u' name='passkey' direction='in'/>"
533 " <arg type='q' name='entered' direction='in'/>"
535 " <method name='ReplyConfirmation'>"
536 " <arg type='u' name='accept' direction='in'/>"
538 " <method name='ReplyPinCode'>"
539 " <arg type='u' name='accept' direction='in'/>"
540 " <arg type='s' name='pincode' direction='in'/>"
542 " <method name='ReplyAuthorize'>"
543 " <arg type='u' name='accept' direction='in'/>"
545 " <method name='ReplyPasskey'>"
546 " <arg type='u' name='accept' direction='in'/>"
547 " <arg type='s' name='passkey' direction='in'/>"
549 " <method name='GetDiscoverableTimeout'>"
550 " <arg type='u' name='timeout' direction='out'/>"
552 " <method name='ConfirmModeChange'>"
553 " <arg type='s' name='mode' direction='in'/>"
555 " <method name='Cancel'>"
557 " <method name='Release'>"
562 static GDBusNodeInfo *__bt_service_create_method_node_info
563 (const gchar *introspection_data)
566 GDBusNodeInfo *node_info = NULL;
568 if (introspection_data == NULL)
571 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
574 ERR("Unable to create node: %s", err->message);
580 static void __bt_gap_agent_method(GDBusConnection *connection,
582 const gchar *object_path,
583 const gchar *interface_name,
584 const gchar *method_name,
585 GVariant *parameters,
586 GDBusMethodInvocation *invocation,
591 BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
592 method_name, object_path, interface_name);
596 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
597 GapAgentPrivate *agent = user_data;
598 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
602 GDBusConnection *conn;
607 g_variant_get(parameters, "(&o)", &path);
608 BT_INFO("Request pin code, Device Path :%s", path);
611 if (g_strcmp0(sender, agent->busname) != 0)
615 if (!agent->cb.passkey_func)
618 conn = _bt_gdbus_get_system_gconn();
622 device = g_dbus_proxy_new_sync(conn,
623 G_DBUS_PROXY_FLAGS_NONE, NULL,
625 BT_PROPERTIES_INTERFACE, NULL, &err);
628 BT_ERR("Fail to make device proxy");
630 g_dbus_method_invocation_return_error(invocation,
631 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
632 "No proxy for device");
635 ERR("Unable to create proxy: %s", err->message);
642 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
643 agent->reply_context = invocation;
645 addr = strstr(path, "dev_");
649 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
651 while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
655 agent->cb.pincode_func(agent, device);
657 g_object_unref(device);
660 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
661 GapAgentPrivate *priv = user_data;
662 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
666 GDBusConnection *conn;
671 g_variant_get(parameters, "(&o)", &path);
672 BT_INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
673 sender, priv->busname, path);
676 if (g_strcmp0(sender, agent->busname) != 0)
680 if (!priv->cb.passkey_func)
683 conn = _bt_gdbus_get_system_gconn();
687 device = g_dbus_proxy_new_sync(conn,
688 G_DBUS_PROXY_FLAGS_NONE, NULL,
690 BT_PROPERTIES_INTERFACE, NULL, &err);
693 BT_ERR("Fail to make device proxy");
695 g_dbus_method_invocation_return_error(invocation,
696 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
697 "No proxy for device");
700 ERR("Unable to create proxy: %s", err->message);
707 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
708 priv->reply_context = invocation;
710 addr = strstr(path, "dev_");
714 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
716 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
720 priv->cb.passkey_func(priv, device);
722 g_object_unref(device);
725 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
726 GapAgentPrivate *priv = user_data;
727 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
732 GDBusConnection *conn;
737 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
738 BT_INFO("Request passkey display :sender %s priv->busname %s"
739 " Device Path :%s, Passkey: %06d, Entered: %d",
740 sender, priv->busname, path, passkey, entered);
742 /* Do not show popup for Key event while typing*/
747 if (g_strcmp0(sender, agent->busname) != 0)
751 if (!priv->cb.display_func)
754 conn = _bt_gdbus_get_system_gconn();
758 device = g_dbus_proxy_new_sync(conn,
759 G_DBUS_PROXY_FLAGS_NONE, NULL,
761 BT_PROPERTIES_INTERFACE, NULL, &err);
764 BT_ERR("Fail to make device proxy");
766 g_dbus_method_invocation_return_error(invocation,
767 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
768 "No proxy for device");
771 ERR("Unable to create proxy: %s", err->message);
778 g_dbus_method_invocation_return_value(invocation, NULL);
780 priv->cb.display_func(priv, device, passkey);
782 g_object_unref(device);
785 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
786 GapAgentPrivate *priv = user_data;
787 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
792 GDBusConnection *conn;
797 g_variant_get(parameters, "(&ou)", &path, &passkey);
798 BT_INFO_C("### Request passkey confirmation");
799 INFO_SECURE("Device Path :%s, Passkey: %d", path, passkey);
801 BT_DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
803 if (g_strcmp0(sender, agent->busname) != 0)
807 BT_DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
808 if (!priv->cb.confirm_func)
811 conn = _bt_gdbus_get_system_gconn();
815 device = g_dbus_proxy_new_sync(conn,
816 G_DBUS_PROXY_FLAGS_NONE, NULL,
818 BT_PROPERTIES_INTERFACE, NULL, &err);
821 BT_ERR("Fail to make device proxy");
823 g_dbus_method_invocation_return_error(invocation,
824 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
825 "No proxy for device");
828 ERR("Unable to create proxy: %s", err->message);
835 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
836 priv->reply_context = invocation;
838 addr = strstr(path, "dev_");
842 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
844 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
848 priv->cb.confirm_func(priv, device, passkey);
850 g_object_unref(device);
853 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
854 GapAgentPrivate *priv = user_data;
855 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
857 GDBusConnection *conn;
865 g_variant_get(parameters, "(&o&s)", &path, &uuid);
866 BT_DBG("Request authorization :sender %s priv->busname %s "
867 "Device Path :%s UUID: %s",
868 sender, priv->busname, path, uuid);
871 if (g_strcmp0(sender, agent->busname) != 0)
875 if (!priv->cb.authorize_func)
878 conn = _bt_gdbus_get_system_gconn();
882 device = g_dbus_proxy_new_sync(conn,
883 G_DBUS_PROXY_FLAGS_NONE, NULL,
885 BT_PROPERTIES_INTERFACE, NULL, &err);
888 BT_ERR("Fail to make device proxy");
890 g_dbus_method_invocation_return_error(invocation,
891 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
892 "No proxy for device");
895 ERR("Unable to create proxy: %s", err->message);
902 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
903 priv->reply_context = invocation;
904 priv->uuid = g_strdup(uuid);
906 addr = strstr(path, "dev_");
910 g_strlcpy(priv->authorize_addr, addr,
911 sizeof(priv->authorize_addr));
913 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
917 priv->cb.authorize_func(priv, device, uuid);
919 g_object_unref(device);
922 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
923 g_dbus_method_invocation_return_value(invocation, NULL);
924 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
925 g_dbus_method_invocation_return_value(invocation, NULL);
926 } else if (g_strcmp0(method_name, "Cancel") == 0) {
927 GapAgentPrivate *priv = user_data;
928 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
933 BT_DBG("Cancelled : agent %p sender %s", sender);
936 if (g_strcmp0(sender, agent->busname) != 0)
940 if (priv->cb.authorization_cancel_func &&
941 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
942 priv->cb.authorization_cancel_func(priv,
943 priv->authorize_addr);
944 memset(priv->authorize_addr, 0x00,
945 sizeof(priv->authorize_addr));
946 } else if (priv->cb.pairing_cancel_func &&
947 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
948 priv->cb.pairing_cancel_func(priv,
950 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
953 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
954 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
955 priv->reply_context != NULL) {
957 g_dbus_method_invocation_return_error(priv->reply_context,
958 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
959 "Rejected by remote cancel");
962 /* Canceled flag is set when user cancels pairing request
963 * Since here bluez has cancelled pairing request, we set the flag to false
965 priv->canceled = FALSE;
966 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
967 priv->reply_context = NULL;
970 } else if (g_strcmp0(method_name, "Release") == 0) {
971 GapAgentPrivate *priv = user_data;
972 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
977 BT_DBG("Released : sender %s\n", sender);
980 if (g_strcmp0(sender, agent->busname) != 0)
984 g_dbus_method_invocation_return_value(invocation, NULL);
986 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
987 priv->reply_context = NULL;
989 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
990 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
993 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
998 _bt_get_timeout_value(&timeout);
1000 g_dbus_method_invocation_return_value(invocation,
1001 g_variant_new("(i)", timeout));
1006 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
1007 GapAgentPrivate *priv = user_data;
1008 const char *pin_code;
1011 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
1012 BT_DBG("Accept: %d PinCode: %s", accept, pin_code);
1013 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
1014 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
1015 GapAgentPrivate *priv = user_data;
1016 const char *passkey;
1019 g_variant_get(parameters, "(u&s)", &accept, &passkey);
1020 BT_DBG("Accept: %d PinCode: %s", accept, passkey);
1021 gap_agent_reply_passkey(priv, accept, passkey, invocation);
1022 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
1023 GapAgentPrivate *priv = user_data;
1026 g_variant_get(parameters, "(u)", &accept);
1027 BT_DBG("Accept: %d", accept);
1028 gap_agent_reply_confirmation(priv, accept, invocation);
1029 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
1030 GapAgentPrivate *priv = user_data;
1033 g_variant_get(parameters, "(u)", &accept);
1034 BT_DBG("Accept: %d", accept);
1035 gap_agent_reply_authorize(priv, accept, invocation);
1039 static const GDBusInterfaceVTable method_table = {
1040 __bt_gap_agent_method,
1045 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
1047 GDBusProxy *adapter)
1049 GapAgentPrivate *priv = agent;
1051 GDBusNodeInfo *node_info;
1052 GError *error = NULL;
1054 priv->path = g_strdup(path);
1057 node_info = __bt_service_create_method_node_info(
1058 gap_agent_bluez_introspection_xml);
1059 if (node_info == NULL)
1062 BT_DBG("path is [%s]", path);
1064 if (connection == NULL) {
1065 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1068 ERR("Unable to connect to gdbus: %s", error->message);
1069 g_clear_error(&error);
1071 g_dbus_node_info_unref(node_info);
1076 if (gap_agent_id == -1) {
1077 gap_agent_id = g_dbus_connection_register_object(connection, path,
1078 node_info->interfaces[0],
1079 &method_table, priv,
1083 g_dbus_node_info_unref(node_info);
1085 if (gap_agent_id == 0) {
1086 BT_ERR("Failed to register for Path: %s", path);
1088 BT_ERR("Failed to register: %s", error->message);
1089 g_clear_error(&error);
1094 memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
1096 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1097 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1098 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1099 priv->reply_context = NULL;
1101 BT_DBG("path: %s", path);
1103 proxy = g_dbus_proxy_new_sync(connection,
1104 G_DBUS_PROXY_FLAGS_NONE, NULL,
1105 BT_BLUEZ_NAME, path,
1106 BT_AGENT_INTERFACE, NULL, &error);
1109 ERR("Unable to create proxy");
1111 ERR("Error: %s", error->message);
1112 g_clear_error(&error);
1114 priv->busname = NULL;
1116 priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
1117 BT_DBG("Busname: %s", priv->busname);
1118 g_object_unref(proxy);
1123 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
1125 GapAgentPrivate *priv = agent;
1129 __gap_agent_unregister(agent);
1131 if (gap_agent_id > 0) {
1132 g_dbus_connection_unregister_object(connection,
1138 g_object_unref(connection);
1142 if (priv->osp_servers) {
1143 __gap_agent_remove_osp_servers(priv->osp_servers);
1144 g_slist_free(priv->osp_servers);
1145 priv->osp_servers = NULL;
1151 g_free(priv->busname);
1152 priv->busname = NULL;
1155 gboolean _gap_agent_exist_osp_server(GapAgentPrivate *agent, int type, char *uuid)
1157 GapAgentPrivate *priv = agent;
1162 if (__gap_agent_find_server(priv->osp_servers,
1163 type, uuid) != NULL) {
1170 bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgentPrivate *agent, int type,
1173 GapAgentPrivate *priv = agent;
1174 bt_agent_osp_server_t *osp_serv = NULL;
1178 osp_serv = __gap_agent_find_server(priv->osp_servers,
1186 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
1188 GapAgentPrivate *priv = agent;
1195 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
1197 GapAgentPrivate *priv = agent;
1199 return priv->canceled;
1202 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
1204 GapAgentPrivate *priv = agent;
1208 priv->canceled = value;