4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
26 #include <vconf-keys.h>
28 #include <bt-hal-gap-agent.h>
29 #include <bt-hal-agent.h>
30 #include <bt-hal-internal.h>
33 #include "bt-hal-log.h"
34 #include "bt-hal-msg.h"
35 #include "bt-hal-utils.h"
41 #include "bt-hal-adapter-dbus-handler.h"
42 #include "bt-hal-dbus-common-utils.h"
44 static GDBusConnection *connection = NULL;
47 GAP_AGENT_ERROR_REJECT,
48 GAP_AGENT_ERROR_CANCEL,
49 GAP_AGENT_ERROR_TIMEOUT,
52 #define GAP_AGENT_ERROR (gap_agent_error_quark())
54 static GQuark gap_agent_error_quark(void)
56 static GQuark quark = 0;
58 quark = g_quark_from_static_string("agent");
64 /* Forward declaration */
65 static gboolean __gap_agent_unregister(GapAgentPrivate *agent);
66 static GDBusNodeInfo *__bt_service_create_method_node_info
67 (const gchar *introspection_data);
68 static void __bt_gap_agent_method(GDBusConnection *connection,
70 const gchar *object_path,
71 const gchar *interface_name,
72 const gchar *method_name,
74 GDBusMethodInvocation *invocation,
76 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
78 static gint gap_agent_id = -1;
81 static void __bt_hal_free_osp_server(gpointer data)
83 bt_hal_agent_osp_server_t *server = data;
90 /* TODO: Free additional elements if present */
96 static void __bt_hal_gap_agent_remove_osp_servers(GSList *osp_servers)
101 ERR("osp_servers is NULL");
106 g_slist_free_full(osp_servers, __bt_hal_free_osp_server);
112 gboolean _gap_agent_register(GapAgentPrivate *agent)
114 GapAgentPrivate *priv = agent;
115 GDBusProxy *agent_manager;
116 GError *error = NULL;
124 if (priv->agent_manager == NULL) {
125 agent_manager = g_dbus_proxy_new_sync(connection,
126 G_DBUS_PROXY_FLAGS_NONE, NULL,
127 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
128 BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
129 if (!agent_manager) {
131 ERR("Unable to create proxy: %s", error->message);
132 g_clear_error(&error);
137 agent_manager = priv->agent_manager;
140 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
141 #ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
142 g_variant_new("(os)", priv->path, "NoInputNoOutput"),
144 g_variant_new("(os)", priv->path, "DisplayYesNo"),
146 G_DBUS_CALL_FLAGS_NONE, -1,
149 ERR("Agent registration failed");
151 ERR("Agent registration failed: errCode[%x], message[%s]",
152 error->code, error->message);
153 g_clear_error(&error);
155 g_object_unref(agent_manager);
156 priv->agent_manager = NULL;
159 g_variant_unref(reply);
162 /* Set the defalut agent */
163 DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
164 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
165 g_variant_new("(o)", priv->path),
166 G_DBUS_CALL_FLAGS_NONE, -1,
169 ERR("Request Default Agent failed");
171 ERR("Request Default Agent failed: errCode[%x], message[%s]",
172 error->code, error->message);
173 g_clear_error(&error);
175 g_object_unref(agent_manager);
176 priv->agent_manager = NULL;
179 g_variant_unref(reply);
181 priv->agent_manager = agent_manager;
186 static const gchar gap_agent_bluez_introspection_xml[] =
188 " <interface name='org.bluez.Agent1'>"
189 " <method name='RequestPinCode'>"
190 " <arg type='o' name='device' direction='in'/>"
191 " <arg type='s' name='pincode' direction='out'/>"
193 " <method name='RequestPasskey'>"
194 " <arg type='o' name='device' direction='in'/>"
195 " <arg type='u' name='passkey' direction='out'/>"
197 " <method name='DisplayPasskey'>"
198 " <arg type='o' name='device' direction='in'/>"
199 " <arg type='u' name='passkey' direction='in'/>"
200 " <arg type='q' name='entered' direction='in'/>"
202 " <method name='RequestConfirmation'>"
203 " <arg type='o' name='device' direction='in'/>"
204 " <arg type='u' name='passkey' direction='in'/>"
206 " <method name='RequestAuthorization'>"
207 " <arg type='o' name='device' direction='in'/>"
209 " <method name='AuthorizeService'>"
210 " <arg type='o' name='device' direction='in'/>"
211 " <arg type='s' name='uuid' direction='in'/>"
213 " <method name='Cancel'>"
215 " <method name='Release'>"
217 " <method name='ReplyPinCode'>"
218 " <arg type='u' name='accept' direction='in'/>"
219 " <arg type='s' name='pincode' direction='in'/>"
221 " <method name='ReplyPasskey'>"
222 " <arg type='u' name='accept' direction='in'/>"
223 " <arg type='s' name='passkey' direction='in'/>"
225 " <method name='ReplyConfirmation'>"
226 " <arg type='u' name='accept' direction='in'/>"
228 " <method name='ReplyAuthorize'>"
229 " <arg type='u' name='accept' direction='in'/>"
231 " <method name='ConfirmModeChange'>"
232 " <arg type='s' name='mode' direction='in'/>"
234 " <method name='GetDiscoverableTimeout'>"
235 " <arg type='u' name='timeout' direction='out'/>"
241 static const GDBusInterfaceVTable method_table = {
242 __bt_gap_agent_method,
247 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
251 GapAgentPrivate *priv = agent;
253 GDBusNodeInfo *node_info;
254 GError *error = NULL;
257 priv->path = g_strdup(path);
259 node_info = __bt_service_create_method_node_info(
260 gap_agent_bluez_introspection_xml);
261 if (node_info == NULL)
264 DBG("path is [%s]", path);
266 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
269 ERR("Unable to connect to gdbus: %s", error->message);
270 g_clear_error(&error);
275 if (gap_agent_id == -1) {
276 gap_agent_id = g_dbus_connection_register_object(connection, path,
277 node_info->interfaces[0],
282 g_dbus_node_info_unref(node_info);
284 if (gap_agent_id == 0) {
285 ERR("Failed to register for Path: %s", path);
287 ERR("Failed to register: %s", error->message);
288 g_clear_error(&error);
293 memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
295 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
296 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
297 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
298 priv->reply_context = NULL;
300 DBG("path: %s", path);
302 proxy = g_dbus_proxy_new_sync(connection,
303 G_DBUS_PROXY_FLAGS_NONE, NULL,
304 BT_HAL_BLUEZ_NAME, path,
305 BT_HAL_AGENT_INTERFACE, NULL, &error);
308 ERR("Unable to create proxy");
310 ERR("Error: %s", error->message);
311 g_clear_error(&error);
313 priv->busname = NULL;
315 priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
316 g_object_unref(proxy);
317 DBG("Busname: %s", priv->busname);
322 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
324 GapAgentPrivate *priv = agent;
326 /* Fix : NULL_RETURNS */
330 __gap_agent_unregister(agent);
332 if (gap_agent_id > 0) {
335 g_dbus_connection_unregister_object(connection,
341 if (priv->osp_servers)
342 __bt_hal_gap_agent_remove_osp_servers(priv->osp_servers);
345 g_object_ref(priv->adapter);
346 priv->adapter = NULL;
351 g_free(priv->busname);
352 priv->busname = NULL;
355 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
357 GapAgentPrivate *priv = agent;
359 /* Fix : NULL_RETURNS */
366 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
368 GapAgentPrivate *priv = agent;
370 /* Fix : NULL_RETURNS */
374 return priv->canceled;
377 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
379 GapAgentPrivate *priv = agent;
381 /* Fix : NULL_RETURNS */
385 priv->canceled = value;
388 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
390 GapAgentPrivate *priv = agent;
391 GDBusProxy *agent_manager;
392 GError *error = NULL;
395 if (priv == NULL || priv->path == NULL || connection == NULL)
398 if (priv->agent_manager == NULL) {
399 agent_manager = g_dbus_proxy_new_sync(connection,
400 G_DBUS_PROXY_FLAGS_NONE, NULL,
401 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
402 BT_HAL_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, "UnregisterAgent",
415 g_variant_new("o", priv->path),
416 G_DBUS_CALL_FLAGS_NONE, -1,
418 g_object_unref(agent_manager);
419 priv->agent_manager = NULL;
422 ERR("Agent unregistration failed");
424 ERR("Agent unregistration failed: errCode[%x], message[%s]",
425 error->code, error->message);
426 g_clear_error(&error);
430 g_variant_unref(reply);
435 static GDBusNodeInfo *__bt_service_create_method_node_info
436 (const gchar *introspection_data)
439 GDBusNodeInfo *node_info = NULL;
441 if (introspection_data == NULL)
444 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
447 ERR("Unable to create node: %s", err->message);
453 static void __bt_gap_agent_method(GDBusConnection *connection,
455 const gchar *object_path,
456 const gchar *interface_name,
457 const gchar *method_name,
458 GVariant *parameters,
459 GDBusMethodInvocation *invocation,
465 DBG("Method[%s] Object Path[%s] Interface Name[%s]",
466 method_name, object_path, interface_name);
469 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
470 GapAgentPrivate *agent = user_data;
471 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
475 GDBusConnection *conn;
480 g_variant_get(parameters, "(&o)", &path);
481 DBG("Request pin code, Device Path :%s", path);
484 if (g_strcmp0(sender, agent->busname) != 0)
488 if (!agent->cb.passkey_func)
490 conn = _bt_hal_get_system_gconn();
493 device = g_dbus_proxy_new_sync(conn,
494 G_DBUS_PROXY_FLAGS_NONE, NULL,
495 BT_HAL_BLUEZ_NAME, path,
496 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
498 ERR("Fail to make device proxy");
499 g_dbus_method_invocation_return_error(invocation,
500 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
501 "No proxy for device");
503 ERR("Unable to create proxy: %s", err->message);
509 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
510 agent->reply_context = invocation;
512 addr = strstr(path, "dev_");
516 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
518 while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
521 agent->cb.pincode_func(agent, device);
522 g_object_unref(device);
524 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
525 GapAgentPrivate *priv = user_data;
526 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
530 GDBusConnection *conn;
535 g_variant_get(parameters, "(&o)", &path);
536 DBG("Request passkey : sender %s priv->busname %s Device Path :%s",
537 sender, priv->busname, path);
539 if (g_strcmp0(sender, agent->busname) != 0)
542 if (!priv->cb.passkey_func)
544 conn = _bt_hal_get_system_gconn();
548 device = g_dbus_proxy_new_sync(conn,
549 G_DBUS_PROXY_FLAGS_NONE, NULL,
550 BT_HAL_BLUEZ_NAME, path,
551 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
554 ERR("Fail to make device proxy");
556 g_dbus_method_invocation_return_error(invocation,
557 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
558 "No proxy for device");
560 ERR("Unable to create proxy: %s", err->message);
565 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
566 priv->reply_context = invocation;
568 addr = strstr(path, "dev_");
572 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
574 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
577 priv->cb.passkey_func(priv, device);
578 g_object_unref(device);
580 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
581 GapAgentPrivate *priv = user_data;
582 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
587 GDBusConnection *conn;
591 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
592 DBG("Request passkey display :sender %s priv->busname %s"
593 " Device Path :%s, Passkey: %d, Entered: %d",
594 sender, priv->busname, path, passkey, entered);
595 /* Do not show popup for Key event while typing*/
599 if (g_strcmp0(sender, agent->busname) != 0)
602 if (!priv->cb.display_func)
605 conn = _bt_hal_get_system_gconn();
608 device = g_dbus_proxy_new_sync(conn,
609 G_DBUS_PROXY_FLAGS_NONE, NULL,
610 BT_HAL_BLUEZ_NAME, path,
611 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
613 ERR("Fail to make device proxy");
615 g_dbus_method_invocation_return_error(invocation,
616 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
617 "No proxy for device");
619 ERR("Unable to create proxy: %s", err->message);
624 g_dbus_method_invocation_return_value(invocation, NULL);
625 priv->cb.display_func(priv, device, passkey);
626 g_object_unref(device);
628 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
629 GapAgentPrivate *priv = user_data;
630 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
635 GDBusConnection *conn;
640 g_variant_get(parameters, "(&ou)", &path, &passkey);
641 DBG("Request passkey confirmation, Device Path :%s, Passkey: %d",
644 DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
646 if (g_strcmp0(sender, agent->busname) != 0)
649 DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
650 if (!priv->cb.confirm_func)
652 conn = _bt_hal_get_system_gconn();
655 device = g_dbus_proxy_new_sync(conn,
656 G_DBUS_PROXY_FLAGS_NONE, NULL,
657 BT_HAL_BLUEZ_NAME, path,
658 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
660 ERR("Fail to make device proxy");
661 g_dbus_method_invocation_return_error(invocation,
662 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
663 "No proxy for device");
665 ERR("Unable to create proxy: %s", err->message);
670 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
671 priv->reply_context = invocation;
672 addr = strstr(path, "dev_");
676 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
678 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
682 DBG("Pairing address [%s]", priv->pairing_addr);
683 priv->cb.confirm_func(priv, device, passkey);
684 g_object_unref(device);
686 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
687 GapAgentPrivate *priv = user_data;
688 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
690 GDBusConnection *conn;
698 g_variant_get(parameters, "(&o&s)", &path, &uuid);
699 DBG("Request authorization :sender %s priv->busname %s "
700 "Device Path :%s UUID: %s",
701 sender, priv->busname, path, uuid);
704 if (g_strcmp0(sender, agent->busname) != 0)
708 if (!priv->cb.authorize_func)
711 conn = _bt_hal_get_system_gconn();
715 device = g_dbus_proxy_new_sync(conn,
716 G_DBUS_PROXY_FLAGS_NONE, NULL,
717 BT_HAL_BLUEZ_NAME, path,
718 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
721 ERR("Fail to make device proxy");
723 g_dbus_method_invocation_return_error(invocation,
724 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
725 "No proxy for device");
728 ERR("Unable to create proxy: %s", err->message);
735 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
736 priv->reply_context = invocation;
738 addr = strstr(path, "dev_");
742 g_strlcpy(priv->authorize_addr, addr,
743 sizeof(priv->authorize_addr));
745 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
749 priv->cb.authorize_func(priv, device, uuid);
751 g_object_unref(device);
753 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
754 g_dbus_method_invocation_return_value(invocation, NULL);
755 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
756 g_dbus_method_invocation_return_value(invocation, NULL);
757 } else if (g_strcmp0(method_name, "Cancel") == 0) {
758 GapAgentPrivate *priv = user_data;
759 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
763 DBG("Cancelled : agent %p sender %s", sender);
765 if (g_strcmp0(sender, agent->busname) != 0)
768 if (priv->cb.authorization_cancel_func &&
769 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
770 DBG("Call GAP agent cancel Authorization method.");
771 priv->cb.authorization_cancel_func(priv,
772 priv->authorize_addr);
773 memset(priv->authorize_addr, 0x00,
774 sizeof(priv->authorize_addr));
775 } else if (priv->cb.pairing_cancel_func &&
776 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
777 DBG("Call GAP agent cancel Pairing method.");
778 priv->cb.pairing_cancel_func(priv,
780 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
782 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
783 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
784 priv->reply_context != NULL) {
786 g_dbus_method_invocation_return_error(priv->reply_context,
787 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
788 "Rejected by remote cancel");
791 /* Canceled flag is set when user cancels pairing request
792 * Since here bluez has cancelled pairing request, we set the flag to false
794 priv->canceled = FALSE;
795 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
796 priv->reply_context = NULL;
798 } else if (g_strcmp0(method_name, "Release") == 0) {
799 GapAgentPrivate *priv = user_data;
800 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
805 DBG("Released : sender %s\n", sender);
808 if (g_strcmp0(sender, agent->busname) != 0)
812 g_dbus_method_invocation_return_value(invocation, NULL);
815 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
816 priv->reply_context = NULL;
818 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
819 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
822 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
824 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
825 GapAgentPrivate *priv = user_data;
826 const char *pin_code;
829 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
830 DBG("Accept: %d PinCode: %s", accept, pin_code);
831 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
832 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
833 GapAgentPrivate *priv = user_data;
837 g_variant_get(parameters, "(u&s)", &accept, &passkey);
838 DBG("Accept: %d PinCode: %s", accept, passkey);
839 gap_agent_reply_passkey(priv, accept, passkey, invocation);
840 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
841 GapAgentPrivate *priv = user_data;
844 g_variant_get(parameters, "(u)", &accept);
845 DBG("Accept: %d", accept);
846 gap_agent_reply_confirmation(priv, accept, invocation);
847 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
848 GapAgentPrivate *priv = user_data;
851 g_variant_get(parameters, "(u)", &accept);
852 DBG("Accept: %d", accept);
853 gap_agent_reply_authorize(priv, accept, invocation);
858 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
859 GDBusMethodInvocation *context)
864 GapAgentPrivate *priv = agent;
866 /* Fix : NULL_RETURNS */
870 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
871 priv->reply_context != NULL) {
872 if (accept == GAP_AGENT_ACCEPT || accept == GAP_AGENT_ACCEPT_ALWAYS) {
873 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
874 priv->canceled = FALSE;
877 case GAP_AGENT_CANCEL:
878 g_dbus_method_invocation_return_error(priv->reply_context,
879 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
881 priv->canceled = TRUE;
883 case GAP_AGENT_TIMEOUT:
884 case GAP_AGENT_REJECT:
886 g_dbus_method_invocation_return_error(priv->reply_context,
887 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
888 "Confirmation request rejected");
889 priv->canceled = FALSE;
895 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
896 priv->reply_context = NULL;
897 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
903 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
904 const char *pin_code,
905 GDBusMethodInvocation *context)
908 GapAgentPrivate *priv = agent;
910 /* Fix : NULL_RETURNS */
914 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
915 priv->reply_context != NULL) {
916 if (accept == GAP_AGENT_ACCEPT) {
917 g_dbus_method_invocation_return_value(priv->reply_context,
918 g_variant_new("(s)", pin_code));
919 priv->canceled = FALSE;
922 case GAP_AGENT_CANCEL:
923 g_dbus_method_invocation_return_error(priv->reply_context,
924 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
926 priv->canceled = TRUE;
928 case GAP_AGENT_TIMEOUT:
929 case GAP_AGENT_REJECT:
931 g_dbus_method_invocation_return_error(priv->reply_context,
932 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
933 "Pairing request rejected");
934 priv->canceled = FALSE;
939 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
940 priv->reply_context = NULL;
941 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
947 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
949 GDBusMethodInvocation *context)
952 GapAgentPrivate *priv = agent;
954 /* Fix : NULL_RETURNS */
958 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
959 priv->reply_context != NULL) {
960 if (accept == GAP_AGENT_ACCEPT) {
961 guint pass_key = atoi(passkey);
962 g_dbus_method_invocation_return_value(priv->reply_context,
963 g_variant_new("(u)", pass_key));
964 priv->canceled = FALSE;
967 case GAP_AGENT_CANCEL:
968 g_dbus_method_invocation_return_error(priv->reply_context,
969 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
971 priv->canceled = TRUE;
973 case GAP_AGENT_TIMEOUT:
974 case GAP_AGENT_REJECT:
976 g_dbus_method_invocation_return_error(priv->reply_context,
977 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
978 "Passkey request rejected");
979 priv->canceled = FALSE;
985 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
986 priv->reply_context = NULL;
987 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
993 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
994 GDBusMethodInvocation *context)
997 GapAgentPrivate *priv = agent;
1000 /* Fix : NULL_RETURNS */
1004 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
1005 priv->reply_context != NULL) {
1006 if (accept == GAP_AGENT_ACCEPT) {
1007 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1008 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
1009 /* TODO: Enable below logic after set authorization API implementation */
1010 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1013 case GAP_AGENT_CANCEL:
1014 g_dbus_method_invocation_return_error(priv->reply_context,
1015 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
1018 case GAP_AGENT_TIMEOUT:
1019 case GAP_AGENT_REJECT:
1021 g_dbus_method_invocation_return_error(priv->reply_context,
1022 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1023 "Authorization request rejected");
1029 g_dbus_method_invocation_return_value(context, NULL);
1033 g_dbus_method_invocation_return_error(context,
1034 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1039 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1040 priv->reply_context = NULL;
1041 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1048 bt_hal_agent_osp_server_t *_bt_hal_gap_agent_find_osp_server_by_type(GSList *servers, unsigned int type)
1051 bt_hal_agent_osp_server_t *server;
1053 for (l = servers; l != NULL; l = g_slist_next(l)) {
1059 if (type == server->type)
1066 gboolean _bt_hal_gap_agent_register_osp_server(GapAgentPrivate *agent, unsigned int type)
1068 bt_hal_agent_osp_server_t *server;
1072 GapAgentPrivate *priv = agent;
1076 if (type >= BT_OSP_SERVER_MAX)
1079 server = g_malloc0(sizeof(bt_hal_agent_osp_server_t));
1080 server->type = type;
1081 priv->osp_servers = g_slist_append(priv->osp_servers, server);
1087 gboolean _bt_hal_gap_agent_unregister_osp_server(GapAgentPrivate *agent, unsigned int type)
1089 bt_hal_agent_osp_server_t *server;
1091 GapAgentPrivate *priv = agent;
1097 if (type >= BT_OSP_SERVER_MAX)
1100 server = _bt_hal_gap_agent_find_osp_server_by_type(priv->osp_servers, type);
1104 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
1105 __bt_hal_free_osp_server(server);