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 AGENT_ALREADY_EXIST 0x24
54 #define GAP_AGENT_ERROR (gap_agent_error_quark())
56 static GQuark gap_agent_error_quark(void)
58 static GQuark quark = 0;
60 quark = g_quark_from_static_string("agent");
66 /* Forward declaration */
67 static gboolean __gap_agent_unregister(GapAgentPrivate *agent);
68 static GDBusNodeInfo *__bt_service_create_method_node_info
69 (const gchar *introspection_data);
70 static void __bt_gap_agent_method(GDBusConnection *connection,
72 const gchar *object_path,
73 const gchar *interface_name,
74 const gchar *method_name,
76 GDBusMethodInvocation *invocation,
78 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
80 static gint gap_agent_id = -1;
83 static void __bt_hal_free_osp_server(gpointer data)
85 bt_hal_agent_osp_server_t *server = data;
95 static void __bt_hal_gap_agent_remove_osp_servers(GSList *osp_servers)
98 ERR("osp_servers is NULL");
103 g_slist_free_full(osp_servers, __bt_hal_free_osp_server);
107 gboolean _gap_agent_register(GapAgentPrivate *agent)
109 GapAgentPrivate *priv = agent;
110 GDBusProxy *agent_manager;
111 GError *error = NULL;
119 if (priv->agent_manager == NULL) {
120 agent_manager = g_dbus_proxy_new_sync(connection,
121 G_DBUS_PROXY_FLAGS_NONE, NULL,
122 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
123 BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
124 if (!agent_manager) {
126 ERR("Unable to create proxy: %s", error->message);
127 g_clear_error(&error);
132 agent_manager = priv->agent_manager;
135 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
136 #ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
137 g_variant_new("(os)", priv->path, "NoInputNoOutput"),
139 g_variant_new("(os)", priv->path, "DisplayYesNo"),
141 G_DBUS_CALL_FLAGS_NONE, -1,
144 ERR("Agent registration failed");
146 ERR("Agent registration failed: errCode[%x], message[%s]",
147 error->code, error->message);
149 if (error->code == AGENT_ALREADY_EXIST) {
150 DBG("Agent is already registered");
151 g_clear_error(&error);
153 g_clear_error(&error);
154 g_object_unref(agent_manager);
155 priv->agent_manager = NULL;
160 g_variant_unref(reply);
163 /* Set the defalut agent */
164 DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
165 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
166 g_variant_new("(o)", priv->path),
167 G_DBUS_CALL_FLAGS_NONE, -1,
170 ERR("Request Default Agent failed");
172 ERR("Request Default Agent failed: errCode[%x], message[%s]",
173 error->code, error->message);
174 g_clear_error(&error);
176 g_object_unref(agent_manager);
177 priv->agent_manager = NULL;
180 g_variant_unref(reply);
182 priv->agent_manager = agent_manager;
187 static const gchar gap_agent_bluez_introspection_xml[] =
189 " <interface name='org.bluez.Agent1'>"
190 " <method name='RequestPinCode'>"
191 " <arg type='o' name='device' direction='in'/>"
192 " <arg type='s' name='pincode' direction='out'/>"
194 " <method name='RequestPasskey'>"
195 " <arg type='o' name='device' direction='in'/>"
196 " <arg type='u' name='passkey' direction='out'/>"
198 " <method name='DisplayPasskey'>"
199 " <arg type='o' name='device' direction='in'/>"
200 " <arg type='u' name='passkey' direction='in'/>"
201 " <arg type='q' name='entered' direction='in'/>"
203 " <method name='RequestConfirmation'>"
204 " <arg type='o' name='device' direction='in'/>"
205 " <arg type='u' name='passkey' direction='in'/>"
207 " <method name='RequestAuthorization'>"
208 " <arg type='o' name='device' direction='in'/>"
210 " <method name='AuthorizeService'>"
211 " <arg type='o' name='device' direction='in'/>"
212 " <arg type='s' name='uuid' direction='in'/>"
214 " <method name='Cancel'>"
216 " <method name='Release'>"
218 " <method name='ReplyPinCode'>"
219 " <arg type='u' name='accept' direction='in'/>"
220 " <arg type='s' name='pincode' direction='in'/>"
222 " <method name='ReplyPasskey'>"
223 " <arg type='u' name='accept' direction='in'/>"
224 " <arg type='s' name='passkey' direction='in'/>"
226 " <method name='ReplyConfirmation'>"
227 " <arg type='u' name='accept' direction='in'/>"
229 " <method name='ReplyAuthorize'>"
230 " <arg type='u' name='accept' direction='in'/>"
232 " <method name='ConfirmModeChange'>"
233 " <arg type='s' name='mode' direction='in'/>"
235 " <method name='GetDiscoverableTimeout'>"
236 " <arg type='u' name='timeout' direction='out'/>"
242 static const GDBusInterfaceVTable method_table = {
243 __bt_gap_agent_method,
248 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
252 GapAgentPrivate *priv = agent;
254 GDBusNodeInfo *node_info;
255 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);
321 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
323 GapAgentPrivate *priv = agent;
325 /* Fix : NULL_RETURNS */
329 __gap_agent_unregister(agent);
331 if (gap_agent_id > 0) {
334 g_dbus_connection_unregister_object(connection,
340 if (priv->osp_servers)
341 __bt_hal_gap_agent_remove_osp_servers(priv->osp_servers);
344 g_object_ref(priv->adapter);
345 priv->adapter = NULL;
350 g_free(priv->busname);
351 priv->busname = NULL;
354 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
356 GapAgentPrivate *priv = agent;
358 /* Fix : NULL_RETURNS */
365 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
367 GapAgentPrivate *priv = agent;
369 /* Fix : NULL_RETURNS */
373 return priv->canceled;
376 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
378 GapAgentPrivate *priv = agent;
380 /* Fix : NULL_RETURNS */
384 priv->canceled = value;
387 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
389 GapAgentPrivate *priv = agent;
390 GDBusProxy *agent_manager;
391 GError *error = NULL;
394 if (priv == NULL || priv->path == NULL || connection == NULL)
397 if (priv->agent_manager == NULL) {
398 agent_manager = g_dbus_proxy_new_sync(connection,
399 G_DBUS_PROXY_FLAGS_NONE, NULL,
400 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
401 BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
402 if (!agent_manager) {
404 ERR("Unable to create proxy: %s", error->message);
405 g_clear_error(&error);
410 agent_manager = priv->agent_manager;
413 reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
414 g_variant_new("o", priv->path),
415 G_DBUS_CALL_FLAGS_NONE, -1,
417 g_object_unref(agent_manager);
418 priv->agent_manager = NULL;
421 ERR("Agent unregistration failed");
423 ERR("Agent unregistration failed: errCode[%x], message[%s]",
424 error->code, error->message);
425 g_clear_error(&error);
429 g_variant_unref(reply);
434 static GDBusNodeInfo *__bt_service_create_method_node_info
435 (const gchar *introspection_data)
438 GDBusNodeInfo *node_info = NULL;
440 if (introspection_data == NULL)
443 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
446 ERR("Unable to create node: %s", err->message);
452 static void __bt_gap_agent_method(GDBusConnection *connection,
454 const gchar *object_path,
455 const gchar *interface_name,
456 const gchar *method_name,
457 GVariant *parameters,
458 GDBusMethodInvocation *invocation,
464 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
465 GapAgentPrivate *agent = user_data;
469 GDBusConnection *conn;
474 g_variant_get(parameters, "(&o)", &path);
475 INFO("Request pin code, Device Path :%s", path);
478 if (g_strcmp0(sender, agent->busname) != 0)
482 if (!agent->cb.passkey_func)
484 conn = _bt_hal_get_system_gconn();
487 device = g_dbus_proxy_new_sync(conn,
488 G_DBUS_PROXY_FLAGS_NONE, NULL,
489 BT_HAL_BLUEZ_NAME, path,
490 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
492 ERR("Fail to make device proxy");
493 g_dbus_method_invocation_return_error(invocation,
494 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
495 "No proxy for device");
497 ERR("Unable to create proxy: %s", err->message);
503 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
504 agent->reply_context = invocation;
506 addr = strstr(path, "dev_");
510 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
512 while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
515 agent->cb.pincode_func(agent, device);
516 g_object_unref(device);
518 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
519 GapAgentPrivate *priv = user_data;
523 GDBusConnection *conn;
528 g_variant_get(parameters, "(&o)", &path);
529 INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
530 sender, priv->busname, path);
532 if (g_strcmp0(sender, agent->busname) != 0)
535 if (!priv->cb.passkey_func)
537 conn = _bt_hal_get_system_gconn();
541 device = g_dbus_proxy_new_sync(conn,
542 G_DBUS_PROXY_FLAGS_NONE, NULL,
543 BT_HAL_BLUEZ_NAME, path,
544 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
547 ERR("Fail to make device proxy");
549 g_dbus_method_invocation_return_error(invocation,
550 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
551 "No proxy for device");
553 ERR("Unable to create proxy: %s", err->message);
558 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
559 priv->reply_context = invocation;
561 addr = strstr(path, "dev_");
565 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
567 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
570 priv->cb.passkey_func(priv, device);
571 g_object_unref(device);
573 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
574 GapAgentPrivate *priv = user_data;
579 GDBusConnection *conn;
583 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
584 INFO("Request passkey display :sender %s priv->busname %s"
585 " Device Path :%s, Passkey: %d, Entered: %d",
586 sender, priv->busname, path, passkey, entered);
587 /* Do not show popup for Key event while typing*/
591 if (g_strcmp0(sender, agent->busname) != 0)
594 if (!priv->cb.display_func)
597 conn = _bt_hal_get_system_gconn();
600 device = g_dbus_proxy_new_sync(conn,
601 G_DBUS_PROXY_FLAGS_NONE, NULL,
602 BT_HAL_BLUEZ_NAME, path,
603 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
605 ERR("Fail to make device proxy");
607 g_dbus_method_invocation_return_error(invocation,
608 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
609 "No proxy for device");
611 ERR("Unable to create proxy: %s", err->message);
616 g_dbus_method_invocation_return_value(invocation, NULL);
617 priv->cb.display_func(priv, device, passkey);
618 g_object_unref(device);
620 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
621 GapAgentPrivate *priv = user_data;
626 GDBusConnection *conn;
631 g_variant_get(parameters, "(&ou)", &path, &passkey);
632 INFO("Request passkey confirmation, Device Path :%s, Passkey: %d",
635 DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
637 if (g_strcmp0(sender, agent->busname) != 0)
640 DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
641 if (!priv->cb.confirm_func)
643 conn = _bt_hal_get_system_gconn();
646 device = g_dbus_proxy_new_sync(conn,
647 G_DBUS_PROXY_FLAGS_NONE, NULL,
648 BT_HAL_BLUEZ_NAME, path,
649 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
651 ERR("Fail to make device proxy");
652 g_dbus_method_invocation_return_error(invocation,
653 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
654 "No proxy for device");
656 ERR("Unable to create proxy: %s", err->message);
661 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
662 priv->reply_context = invocation;
663 addr = strstr(path, "dev_");
667 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
669 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
673 DBG("Pairing address [%s]", priv->pairing_addr);
674 priv->cb.confirm_func(priv, device, passkey);
675 g_object_unref(device);
677 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
678 GapAgentPrivate *priv = user_data;
680 GDBusConnection *conn;
688 g_variant_get(parameters, "(&o&s)", &path, &uuid);
689 INFO("Request authorization :sender %s priv->busname %s "
690 "Device Path :%s UUID: %s",
691 sender, priv->busname, path, uuid);
694 if (g_strcmp0(sender, agent->busname) != 0)
698 if (!priv->cb.authorize_func)
701 conn = _bt_hal_get_system_gconn();
705 device = g_dbus_proxy_new_sync(conn,
706 G_DBUS_PROXY_FLAGS_NONE, NULL,
707 BT_HAL_BLUEZ_NAME, path,
708 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
711 ERR("Fail to make device proxy");
713 g_dbus_method_invocation_return_error(invocation,
714 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
715 "No proxy for device");
718 ERR("Unable to create proxy: %s", err->message);
725 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
726 priv->reply_context = invocation;
728 addr = strstr(path, "dev_");
732 g_strlcpy(priv->authorize_addr, addr,
733 sizeof(priv->authorize_addr));
735 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
739 priv->cb.authorize_func(priv, device, uuid);
741 g_object_unref(device);
743 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
744 g_dbus_method_invocation_return_value(invocation, NULL);
745 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
746 g_dbus_method_invocation_return_value(invocation, NULL);
747 } else if (g_strcmp0(method_name, "Cancel") == 0) {
748 GapAgentPrivate *priv = user_data;
752 INFO("Cancelled : agent %p sender %p", priv, sender);
754 if (g_strcmp0(sender, agent->busname) != 0)
757 if (priv->cb.authorization_cancel_func &&
758 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
759 DBG("Call GAP agent cancel Authorization method.");
760 priv->cb.authorization_cancel_func(priv,
761 priv->authorize_addr);
762 memset(priv->authorize_addr, 0x00,
763 sizeof(priv->authorize_addr));
764 } else if (priv->cb.pairing_cancel_func &&
765 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
766 DBG("Call GAP agent cancel Pairing method.");
767 priv->cb.pairing_cancel_func(priv,
769 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
771 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
772 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
773 priv->reply_context != NULL) {
775 g_dbus_method_invocation_return_error(priv->reply_context,
776 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
777 "Rejected by remote cancel");
780 /* Canceled flag is set when user cancels pairing request
781 * Since here bluez has cancelled pairing request, we set the flag to false
783 priv->canceled = FALSE;
784 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
785 priv->reply_context = NULL;
787 } else if (g_strcmp0(method_name, "Release") == 0) {
788 GapAgentPrivate *priv = user_data;
793 INFO("Released : sender %s\n", sender);
796 if (g_strcmp0(sender, agent->busname) != 0)
800 g_dbus_method_invocation_return_value(invocation, NULL);
803 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
804 priv->reply_context = NULL;
806 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
807 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
810 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
812 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
813 GapAgentPrivate *priv = user_data;
814 const char *pin_code;
817 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
818 INFO("Accept: %d PinCode: %s", accept, pin_code);
819 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
820 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
821 GapAgentPrivate *priv = user_data;
825 g_variant_get(parameters, "(u&s)", &accept, &passkey);
826 INFO("Accept: %d PinCode: %s", accept, passkey);
827 gap_agent_reply_passkey(priv, accept, passkey, invocation);
828 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
829 GapAgentPrivate *priv = user_data;
832 g_variant_get(parameters, "(u)", &accept);
833 INFO("Accept: %d", accept);
834 gap_agent_reply_confirmation(priv, accept, invocation);
835 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
836 GapAgentPrivate *priv = user_data;
839 g_variant_get(parameters, "(u)", &accept);
840 INFO("Accept: %d", accept);
841 gap_agent_reply_authorize(priv, accept, invocation);
843 ERR("Invalid method[%s] Object Path[%s] Interface Name[%s]",
844 method_name, object_path, interface_name);
848 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
849 GDBusMethodInvocation *context)
851 GapAgentPrivate *priv = agent;
853 /* Fix : NULL_RETURNS */
857 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
858 priv->reply_context != NULL) {
859 if (accept == GAP_AGENT_ACCEPT || accept == GAP_AGENT_ACCEPT_ALWAYS) {
860 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
861 priv->canceled = FALSE;
864 case GAP_AGENT_CANCEL:
865 g_dbus_method_invocation_return_error(priv->reply_context,
866 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
868 priv->canceled = TRUE;
870 case GAP_AGENT_TIMEOUT:
871 case GAP_AGENT_REJECT:
873 g_dbus_method_invocation_return_error(priv->reply_context,
874 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
875 "Confirmation request rejected");
876 priv->canceled = FALSE;
882 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
883 priv->reply_context = NULL;
884 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
889 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
890 const char *pin_code,
891 GDBusMethodInvocation *context)
893 GapAgentPrivate *priv = agent;
895 /* Fix : NULL_RETURNS */
899 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
900 priv->reply_context != NULL) {
901 if (accept == GAP_AGENT_ACCEPT) {
902 g_dbus_method_invocation_return_value(priv->reply_context,
903 g_variant_new("(s)", pin_code));
904 priv->canceled = FALSE;
907 case GAP_AGENT_CANCEL:
908 g_dbus_method_invocation_return_error(priv->reply_context,
909 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
911 priv->canceled = TRUE;
913 case GAP_AGENT_TIMEOUT:
914 case GAP_AGENT_REJECT:
916 g_dbus_method_invocation_return_error(priv->reply_context,
917 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
918 "Pairing request rejected");
919 priv->canceled = FALSE;
924 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
925 priv->reply_context = NULL;
926 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
931 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
933 GDBusMethodInvocation *context)
935 GapAgentPrivate *priv = agent;
937 /* Fix : NULL_RETURNS */
941 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
942 priv->reply_context != NULL) {
943 if (accept == GAP_AGENT_ACCEPT) {
944 guint pass_key = atoi(passkey);
945 g_dbus_method_invocation_return_value(priv->reply_context,
946 g_variant_new("(u)", pass_key));
947 priv->canceled = FALSE;
950 case GAP_AGENT_CANCEL:
951 g_dbus_method_invocation_return_error(priv->reply_context,
952 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
954 priv->canceled = TRUE;
956 case GAP_AGENT_TIMEOUT:
957 case GAP_AGENT_REJECT:
959 g_dbus_method_invocation_return_error(priv->reply_context,
960 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
961 "Passkey request rejected");
962 priv->canceled = FALSE;
968 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
969 priv->reply_context = NULL;
970 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
975 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
976 GDBusMethodInvocation *context)
979 GapAgentPrivate *priv = agent;
981 /* Fix : NULL_RETURNS */
985 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
986 priv->reply_context != NULL) {
987 if (accept == GAP_AGENT_ACCEPT) {
988 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
989 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
990 /* TODO: Enable below logic after set authorization API implementation */
991 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
994 case GAP_AGENT_CANCEL:
995 g_dbus_method_invocation_return_error(priv->reply_context,
996 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
999 case GAP_AGENT_TIMEOUT:
1000 case GAP_AGENT_REJECT:
1002 g_dbus_method_invocation_return_error(priv->reply_context,
1003 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1004 "Authorization request rejected");
1010 g_dbus_method_invocation_return_value(context, NULL);
1014 g_dbus_method_invocation_return_error(context,
1015 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1020 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1021 priv->reply_context = NULL;
1022 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1028 bt_hal_agent_osp_server_t *_bt_hal_gap_agent_find_osp_server_by_type(GSList *servers, unsigned int type, const char *uuid)
1031 bt_hal_agent_osp_server_t *server;
1033 for (l = servers; l != NULL; l = g_slist_next(l)) {
1039 /* No uuid in obex server */
1040 if (type == BT_OSP_SERVER_OBEX
1041 && server->type == BT_OSP_SERVER_OBEX)
1044 if (g_strcmp0(server->uuid, uuid) == 0)
1051 gboolean _bt_hal_gap_agent_register_osp_server(GapAgentPrivate *agent, unsigned int type, char *uuid, char *path, int fd)
1053 bt_hal_agent_osp_server_t *server;
1055 GapAgentPrivate *priv = agent;
1059 if (type >= BT_OSP_SERVER_MAX)
1062 server = g_malloc0(sizeof(bt_hal_agent_osp_server_t));
1063 server->type = type;
1064 if (type == BT_OSP_SERVER_RFCOMM && uuid && path) {
1065 server->uuid = g_strdup(uuid);
1066 server->path = g_strdup(path);
1069 priv->osp_servers = g_slist_append(priv->osp_servers, server);
1074 gboolean _bt_hal_gap_agent_unregister_osp_server(GapAgentPrivate *agent, unsigned int type, char *uuid)
1076 bt_hal_agent_osp_server_t *server;
1078 GapAgentPrivate *priv = agent;
1083 if (type >= BT_OSP_SERVER_MAX)
1086 server = _bt_hal_gap_agent_find_osp_server_by_type(priv->osp_servers, type, uuid);
1090 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
1091 __bt_hal_free_osp_server(server);