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) {
522 agent->cb.pincode_func(agent, device);
523 g_object_unref(device);
525 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
526 GapAgentPrivate *priv = user_data;
527 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
531 GDBusConnection *conn;
536 g_variant_get(parameters, "(&o)", &path);
537 DBG("Request passkey : sender %s priv->busname %s Device Path :%s",
538 sender, priv->busname, path);
540 if (g_strcmp0(sender, agent->busname) != 0)
543 if (!priv->cb.passkey_func)
545 conn = _bt_hal_get_system_gconn();
549 device = g_dbus_proxy_new_sync(conn,
550 G_DBUS_PROXY_FLAGS_NONE, NULL,
551 BT_HAL_BLUEZ_NAME, path,
552 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
555 ERR("Fail to make device proxy");
557 g_dbus_method_invocation_return_error(invocation,
558 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
559 "No proxy for device");
561 ERR("Unable to create proxy: %s", err->message);
566 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
567 priv->reply_context = invocation;
569 addr = strstr(path, "dev_");
573 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
575 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
579 priv->cb.passkey_func(priv, device);
580 g_object_unref(device);
582 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
583 GapAgentPrivate *priv = user_data;
584 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
589 GDBusConnection *conn;
593 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
594 DBG("Request passkey display :sender %s priv->busname %s"
595 " Device Path :%s, Passkey: %d, Entered: %d",
596 sender, priv->busname, path, passkey, entered);
597 /* Do not show popup for Key event while typing*/
601 if (g_strcmp0(sender, agent->busname) != 0)
604 if (!priv->cb.display_func)
607 conn = _bt_hal_get_system_gconn();
610 device = g_dbus_proxy_new_sync(conn,
611 G_DBUS_PROXY_FLAGS_NONE, NULL,
612 BT_HAL_BLUEZ_NAME, path,
613 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
615 ERR("Fail to make device proxy");
617 g_dbus_method_invocation_return_error(invocation,
618 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
619 "No proxy for device");
621 ERR("Unable to create proxy: %s", err->message);
626 g_dbus_method_invocation_return_value(invocation, NULL);
627 priv->cb.display_func(priv, device, passkey);
628 g_object_unref(device);
630 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
631 GapAgentPrivate *priv = user_data;
632 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
637 GDBusConnection *conn;
642 g_variant_get(parameters, "(&ou)", &path, &passkey);
643 DBG("Request passkey confirmation, Device Path :%s, Passkey: %d",
646 DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
648 if (g_strcmp0(sender, agent->busname) != 0)
651 DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
652 if (!priv->cb.confirm_func)
654 conn = _bt_hal_get_system_gconn();
657 device = g_dbus_proxy_new_sync(conn,
658 G_DBUS_PROXY_FLAGS_NONE, NULL,
659 BT_HAL_BLUEZ_NAME, path,
660 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
662 ERR("Fail to make device proxy");
663 g_dbus_method_invocation_return_error(invocation,
664 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
665 "No proxy for device");
667 ERR("Unable to create proxy: %s", err->message);
672 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
673 priv->reply_context = invocation;
674 addr = strstr(path, "dev_");
678 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
680 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
685 DBG("Pairing address [%s]", priv->pairing_addr);
686 priv->cb.confirm_func(priv, device, passkey);
687 g_object_unref(device);
689 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
690 GapAgentPrivate *priv = user_data;
691 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
693 GDBusConnection *conn;
701 g_variant_get(parameters, "(&o&s)", &path, &uuid);
702 DBG("Request authorization :sender %s priv->busname %s "
703 "Device Path :%s UUID: %s",
704 sender, priv->busname, path, uuid);
707 if (g_strcmp0(sender, agent->busname) != 0)
711 if (!priv->cb.authorize_func)
714 conn = _bt_hal_get_system_gconn();
718 device = g_dbus_proxy_new_sync(conn,
719 G_DBUS_PROXY_FLAGS_NONE, NULL,
720 BT_HAL_BLUEZ_NAME, path,
721 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
724 ERR("Fail to make device proxy");
726 g_dbus_method_invocation_return_error(invocation,
727 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
728 "No proxy for device");
731 ERR("Unable to create proxy: %s", err->message);
738 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
739 priv->reply_context = invocation;
741 addr = strstr(path, "dev_");
745 g_strlcpy(priv->authorize_addr, addr,
746 sizeof(priv->authorize_addr));
748 while ((pos = strchr(priv->authorize_addr, '_')) != NULL) {
753 priv->cb.authorize_func(priv, device, uuid);
755 g_object_unref(device);
757 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
758 g_dbus_method_invocation_return_value(invocation, NULL);
759 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
760 g_dbus_method_invocation_return_value(invocation, NULL);
761 } else if (g_strcmp0(method_name, "Cancel") == 0) {
762 GapAgentPrivate *priv = user_data;
763 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
767 DBG("Cancelled : agent %p sender %s", sender);
769 if (g_strcmp0(sender, agent->busname) != 0)
772 if (priv->cb.authorization_cancel_func &&
773 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
774 DBG("Call GAP agent cancel Authorization method.");
775 priv->cb.authorization_cancel_func(priv,
776 priv->authorize_addr);
777 memset(priv->authorize_addr, 0x00,
778 sizeof(priv->authorize_addr));
779 } else if (priv->cb.pairing_cancel_func &&
780 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
781 DBG("Call GAP agent cancel Pairing method.");
782 priv->cb.pairing_cancel_func(priv,
784 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
786 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
787 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
788 priv->reply_context != NULL) {
790 g_dbus_method_invocation_return_error(priv->reply_context,
791 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
792 "Rejected by remote cancel");
795 /* Canceled flag is set when user cancels pairing request
796 * Since here bluez has cancelled pairing request, we set the flag to false
798 priv->canceled = FALSE;
799 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
800 priv->reply_context = NULL;
802 } else if (g_strcmp0(method_name, "Release") == 0) {
803 GapAgentPrivate *priv = user_data;
804 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
809 DBG("Released : sender %s\n", sender);
812 if (g_strcmp0(sender, agent->busname) != 0)
816 g_dbus_method_invocation_return_value(invocation, NULL);
819 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
820 priv->reply_context = NULL;
822 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
823 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
826 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
828 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
829 GapAgentPrivate *priv = user_data;
830 const char *pin_code;
833 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
834 DBG("Accept: %d PinCode: %s", accept, pin_code);
835 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
836 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
837 GapAgentPrivate *priv = user_data;
841 g_variant_get(parameters, "(u&s)", &accept, &passkey);
842 DBG("Accept: %d PinCode: %s", accept, passkey);
843 gap_agent_reply_passkey(priv, accept, passkey, invocation);
844 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
845 GapAgentPrivate *priv = user_data;
848 g_variant_get(parameters, "(u)", &accept);
849 DBG("Accept: %d", accept);
850 gap_agent_reply_confirmation(priv, accept, invocation);
851 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
852 GapAgentPrivate *priv = user_data;
855 g_variant_get(parameters, "(u)", &accept);
856 DBG("Accept: %d", accept);
857 gap_agent_reply_authorize(priv, accept, invocation);
862 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
863 GDBusMethodInvocation *context)
868 GapAgentPrivate *priv = agent;
870 /* Fix : NULL_RETURNS */
874 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
875 priv->reply_context != NULL) {
876 if (accept == GAP_AGENT_ACCEPT || accept == GAP_AGENT_ACCEPT_ALWAYS) {
877 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
878 priv->canceled = FALSE;
881 case GAP_AGENT_CANCEL:
882 g_dbus_method_invocation_return_error(priv->reply_context,
883 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
885 priv->canceled = TRUE;
887 case GAP_AGENT_TIMEOUT:
888 case GAP_AGENT_REJECT:
890 g_dbus_method_invocation_return_error(priv->reply_context,
891 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
892 "Confirmation request rejected");
893 priv->canceled = FALSE;
899 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
900 priv->reply_context = NULL;
901 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
907 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
908 const char *pin_code,
909 GDBusMethodInvocation *context)
912 GapAgentPrivate *priv = agent;
914 /* Fix : NULL_RETURNS */
918 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
919 priv->reply_context != NULL) {
920 if (accept == GAP_AGENT_ACCEPT) {
921 g_dbus_method_invocation_return_value(priv->reply_context,
922 g_variant_new("(s)", pin_code));
923 priv->canceled = FALSE;
926 case GAP_AGENT_CANCEL:
927 g_dbus_method_invocation_return_error(priv->reply_context,
928 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
930 priv->canceled = TRUE;
932 case GAP_AGENT_TIMEOUT:
933 case GAP_AGENT_REJECT:
935 g_dbus_method_invocation_return_error(priv->reply_context,
936 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
937 "Pairing request rejected");
938 priv->canceled = FALSE;
943 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
944 priv->reply_context = NULL;
945 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
951 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
953 GDBusMethodInvocation *context)
956 GapAgentPrivate *priv = agent;
958 /* Fix : NULL_RETURNS */
962 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
963 priv->reply_context != NULL) {
964 if (accept == GAP_AGENT_ACCEPT) {
965 guint pass_key = atoi(passkey);
966 g_dbus_method_invocation_return_value(priv->reply_context,
967 g_variant_new("(u)", pass_key));
968 priv->canceled = FALSE;
971 case GAP_AGENT_CANCEL:
972 g_dbus_method_invocation_return_error(priv->reply_context,
973 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
975 priv->canceled = TRUE;
977 case GAP_AGENT_TIMEOUT:
978 case GAP_AGENT_REJECT:
980 g_dbus_method_invocation_return_error(priv->reply_context,
981 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
982 "Passkey request rejected");
983 priv->canceled = FALSE;
989 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
990 priv->reply_context = NULL;
991 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
997 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
998 GDBusMethodInvocation *context)
1000 gboolean ret = TRUE;
1001 GapAgentPrivate *priv = agent;
1004 /* Fix : NULL_RETURNS */
1008 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
1009 priv->reply_context != NULL) {
1010 if (accept == GAP_AGENT_ACCEPT) {
1011 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1012 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
1013 /* TODO: Enable below logic after set authorization API implementation */
1014 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1017 case GAP_AGENT_CANCEL:
1018 g_dbus_method_invocation_return_error(priv->reply_context,
1019 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
1022 case GAP_AGENT_TIMEOUT:
1023 case GAP_AGENT_REJECT:
1025 g_dbus_method_invocation_return_error(priv->reply_context,
1026 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1027 "Authorization request rejected");
1033 g_dbus_method_invocation_return_value(context, NULL);
1037 g_dbus_method_invocation_return_error(context,
1038 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1043 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1044 priv->reply_context = NULL;
1045 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1052 bt_hal_agent_osp_server_t *_bt_hal_gap_agent_find_osp_server_by_type(GSList *servers, unsigned int type)
1055 bt_hal_agent_osp_server_t *server;
1057 for (l = servers; l != NULL; l = g_slist_next(l)) {
1063 if (type == server->type)
1070 gboolean _bt_hal_gap_agent_register_osp_server(GapAgentPrivate *agent, unsigned int type)
1072 bt_hal_agent_osp_server_t *server;
1076 GapAgentPrivate *priv = agent;
1080 if (type >= BT_OSP_SERVER_MAX)
1083 server = g_malloc0(sizeof(bt_hal_agent_osp_server_t));
1084 server->type = type;
1085 priv->osp_servers = g_slist_append(priv->osp_servers, server);
1091 gboolean _bt_hal_gap_agent_unregister_osp_server(GapAgentPrivate *agent, unsigned int type)
1093 bt_hal_agent_osp_server_t *server;
1095 GapAgentPrivate *priv = agent;
1101 if (type >= BT_OSP_SERVER_MAX)
1104 server = _bt_hal_gap_agent_find_osp_server_by_type(priv->osp_servers, type);
1108 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
1109 __bt_hal_free_osp_server(server);