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"
37 #include "bt-internal-types.h"
43 #include "bt-hal-adapter-dbus-handler.h"
44 #include "bt-hal-device-dbus-handler.h"
45 #include "bt-hal-dbus-common-utils.h"
47 static GDBusConnection *connection = NULL;
50 GAP_AGENT_ERROR_REJECT,
51 GAP_AGENT_ERROR_CANCEL,
52 GAP_AGENT_ERROR_TIMEOUT,
55 #define AGENT_ALREADY_EXIST 0x24
57 #define GAP_UUID "00001800-0000-1000-8000-00805f9b34fb"
58 #define GAP_AGENT_ERROR (gap_agent_error_quark())
60 static GQuark gap_agent_error_quark(void)
62 static GQuark quark = 0;
64 quark = g_quark_from_static_string("agent");
70 /* Forward declaration */
71 static gboolean __gap_agent_unregister(GapAgentPrivate *agent);
72 static GDBusNodeInfo *__bt_service_create_method_node_info
73 (const gchar *introspection_data);
74 static void __bt_gap_agent_method(GDBusConnection *connection,
76 const gchar *object_path,
77 const gchar *interface_name,
78 const gchar *method_name,
80 GDBusMethodInvocation *invocation,
82 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
84 static gint gap_agent_id = -1;
87 static void __bt_hal_free_osp_server(gpointer data)
89 bt_hal_agent_osp_server_t *server = data;
99 static void __bt_hal_gap_agent_remove_osp_servers(GSList *osp_servers)
102 ERR("osp_servers is NULL");
107 g_slist_free_full(osp_servers, __bt_hal_free_osp_server);
111 gboolean _gap_agent_register(GapAgentPrivate *agent)
113 GapAgentPrivate *priv = agent;
114 GDBusProxy *agent_manager;
115 GError *error = NULL;
123 if (priv->agent_manager == NULL) {
124 agent_manager = g_dbus_proxy_new_sync(connection,
125 G_DBUS_PROXY_FLAGS_NONE, NULL,
126 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
127 BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
128 if (!agent_manager) {
130 ERR("Unable to create proxy: %s", error->message);
131 g_clear_error(&error);
136 agent_manager = priv->agent_manager;
139 reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
140 #ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
141 g_variant_new("(os)", priv->path, "NoInputNoOutput"),
143 g_variant_new("(os)", priv->path, "DisplayYesNo"),
145 G_DBUS_CALL_FLAGS_NONE, -1,
148 ERR("Agent registration failed");
150 ERR("Agent registration failed: errCode[%x], message[%s]",
151 error->code, error->message);
153 if (error->code == AGENT_ALREADY_EXIST) {
154 DBG("Agent is already registered");
155 g_clear_error(&error);
157 g_clear_error(&error);
158 g_object_unref(agent_manager);
159 priv->agent_manager = NULL;
164 g_variant_unref(reply);
167 /* Set the defalut agent */
168 DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
169 reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
170 g_variant_new("(o)", priv->path),
171 G_DBUS_CALL_FLAGS_NONE, -1,
174 ERR("Request Default Agent failed");
176 ERR("Request Default Agent failed: errCode[%x], message[%s]",
177 error->code, error->message);
178 g_clear_error(&error);
180 g_object_unref(agent_manager);
181 priv->agent_manager = NULL;
184 g_variant_unref(reply);
186 priv->agent_manager = agent_manager;
191 static const gchar gap_agent_bluez_introspection_xml[] =
193 " <interface name='org.bluez.Agent1'>"
194 " <method name='RequestPinCode'>"
195 " <arg type='o' name='device' direction='in'/>"
196 " <arg type='s' name='pincode' direction='out'/>"
198 " <method name='RequestPasskey'>"
199 " <arg type='o' name='device' direction='in'/>"
200 " <arg type='u' name='passkey' direction='out'/>"
202 " <method name='DisplayPasskey'>"
203 " <arg type='o' name='device' direction='in'/>"
204 " <arg type='u' name='passkey' direction='in'/>"
205 " <arg type='q' name='entered' direction='in'/>"
207 " <method name='RequestConfirmation'>"
208 " <arg type='o' name='device' direction='in'/>"
209 " <arg type='u' name='passkey' direction='in'/>"
211 " <method name='RequestAuthorization'>"
212 " <arg type='o' name='device' direction='in'/>"
214 " <method name='AuthorizeService'>"
215 " <arg type='o' name='device' direction='in'/>"
216 " <arg type='s' name='uuid' direction='in'/>"
218 " <method name='Cancel'>"
220 " <method name='Release'>"
222 " <method name='ReplyPinCode'>"
223 " <arg type='u' name='accept' direction='in'/>"
224 " <arg type='s' name='pincode' direction='in'/>"
226 " <method name='ReplyPasskey'>"
227 " <arg type='u' name='accept' direction='in'/>"
228 " <arg type='s' name='passkey' direction='in'/>"
230 " <method name='ReplyConfirmation'>"
231 " <arg type='u' name='accept' direction='in'/>"
233 " <method name='ReplyAuthorize'>"
234 " <arg type='u' name='accept' direction='in'/>"
236 " <method name='ConfirmModeChange'>"
237 " <arg type='s' name='mode' direction='in'/>"
239 " <method name='GetDiscoverableTimeout'>"
240 " <arg type='u' name='timeout' direction='out'/>"
246 static const GDBusInterfaceVTable method_table = {
247 __bt_gap_agent_method,
252 void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
256 GapAgentPrivate *priv = agent;
258 GDBusNodeInfo *node_info;
259 GError *error = NULL;
261 priv->path = g_strdup(path);
263 node_info = __bt_service_create_method_node_info(
264 gap_agent_bluez_introspection_xml);
265 if (node_info == NULL)
268 DBG("path is [%s]", path);
270 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
273 ERR("Unable to connect to gdbus: %s", error->message);
274 g_clear_error(&error);
279 if (gap_agent_id == -1) {
280 gap_agent_id = g_dbus_connection_register_object(connection, path,
281 node_info->interfaces[0],
286 g_dbus_node_info_unref(node_info);
288 if (gap_agent_id == 0) {
289 ERR("Failed to register for Path: %s", path);
291 ERR("Failed to register: %s", error->message);
292 g_clear_error(&error);
297 memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
299 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
300 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
301 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
302 priv->reply_context = NULL;
304 DBG("path: %s", path);
306 proxy = g_dbus_proxy_new_sync(connection,
307 G_DBUS_PROXY_FLAGS_NONE, NULL,
308 BT_HAL_BLUEZ_NAME, path,
309 BT_HAL_AGENT_INTERFACE, NULL, &error);
312 ERR("Unable to create proxy");
314 ERR("Error: %s", error->message);
315 g_clear_error(&error);
317 priv->busname = NULL;
319 priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
320 g_object_unref(proxy);
321 DBG("Busname: %s", priv->busname);
325 void _gap_agent_reset_dbus(GapAgentPrivate *agent)
327 GapAgentPrivate *priv = agent;
329 /* Fix : NULL_RETURNS */
333 __gap_agent_unregister(agent);
335 if (gap_agent_id > 0) {
338 g_dbus_connection_unregister_object(connection,
344 if (priv->osp_servers)
345 __bt_hal_gap_agent_remove_osp_servers(priv->osp_servers);
348 g_object_ref(priv->adapter);
349 priv->adapter = NULL;
354 g_free(priv->busname);
355 priv->busname = NULL;
358 gchar* _gap_agent_get_path(GapAgentPrivate *agent)
360 GapAgentPrivate *priv = agent;
362 /* Fix : NULL_RETURNS */
369 gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
371 GapAgentPrivate *priv = agent;
373 /* Fix : NULL_RETURNS */
377 return priv->canceled;
380 void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
382 GapAgentPrivate *priv = agent;
384 /* Fix : NULL_RETURNS */
388 priv->canceled = value;
391 static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
393 GapAgentPrivate *priv = agent;
394 GDBusProxy *agent_manager;
395 GError *error = NULL;
398 if (priv == NULL || priv->path == NULL || connection == NULL)
401 if (priv->agent_manager == NULL) {
402 agent_manager = g_dbus_proxy_new_sync(connection,
403 G_DBUS_PROXY_FLAGS_NONE, NULL,
404 BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
405 BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
406 if (!agent_manager) {
408 ERR("Unable to create proxy: %s", error->message);
409 g_clear_error(&error);
414 agent_manager = priv->agent_manager;
417 reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
418 g_variant_new("(o)", priv->path),
419 G_DBUS_CALL_FLAGS_NONE, -1,
421 g_object_unref(agent_manager);
422 priv->agent_manager = NULL;
425 ERR("Agent unregistration failed");
427 ERR("Agent unregistration failed: errCode[%x], message[%s]",
428 error->code, error->message);
429 g_clear_error(&error);
433 g_variant_unref(reply);
438 static GDBusNodeInfo *__bt_service_create_method_node_info
439 (const gchar *introspection_data)
442 GDBusNodeInfo *node_info = NULL;
444 if (introspection_data == NULL)
447 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
450 ERR("Unable to create node: %s", err->message);
456 static void __bt_gap_agent_method(GDBusConnection *connection,
458 const gchar *object_path,
459 const gchar *interface_name,
460 const gchar *method_name,
461 GVariant *parameters,
462 GDBusMethodInvocation *invocation,
468 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
469 GapAgentPrivate *agent = user_data;
473 GDBusConnection *conn;
478 g_variant_get(parameters, "(&o)", &path);
479 INFO("Request pin code, Device Path :%s", path);
482 if (g_strcmp0(sender, agent->busname) != 0)
486 if (!agent->cb.passkey_func)
488 conn = _bt_hal_get_system_gconn();
491 device = g_dbus_proxy_new_sync(conn,
492 G_DBUS_PROXY_FLAGS_NONE, NULL,
493 BT_HAL_BLUEZ_NAME, path,
494 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
496 ERR("Fail to make device proxy");
497 g_dbus_method_invocation_return_error(invocation,
498 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
499 "No proxy for device");
501 ERR("Unable to create proxy: %s", err->message);
507 agent->exec_type = GAP_AGENT_EXEC_PAIRING;
508 agent->reply_context = invocation;
510 addr = strstr(path, "dev_");
514 g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
516 while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
519 agent->cb.pincode_func(agent, device);
520 g_object_unref(device);
522 } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
523 GapAgentPrivate *priv = user_data;
527 GDBusConnection *conn;
532 g_variant_get(parameters, "(&o)", &path);
533 INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
534 sender, priv->busname, path);
536 if (g_strcmp0(sender, agent->busname) != 0)
539 if (!priv->cb.passkey_func)
541 conn = _bt_hal_get_system_gconn();
545 device = g_dbus_proxy_new_sync(conn,
546 G_DBUS_PROXY_FLAGS_NONE, NULL,
547 BT_HAL_BLUEZ_NAME, path,
548 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
551 ERR("Fail to make device proxy");
553 g_dbus_method_invocation_return_error(invocation,
554 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
555 "No proxy for device");
557 ERR("Unable to create proxy: %s", err->message);
562 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
563 priv->reply_context = invocation;
565 addr = strstr(path, "dev_");
569 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
571 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
574 priv->cb.passkey_func(priv, device);
575 g_object_unref(device);
577 } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
578 GapAgentPrivate *priv = user_data;
583 GDBusConnection *conn;
587 g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
588 INFO("Request passkey display :sender %s priv->busname %s"
589 " Device Path :%s, Passkey: %d, Entered: %d",
590 sender, priv->busname, path, passkey, entered);
591 /* Do not show popup for Key event while typing*/
595 if (g_strcmp0(sender, agent->busname) != 0)
598 if (!priv->cb.display_func)
601 conn = _bt_hal_get_system_gconn();
604 device = g_dbus_proxy_new_sync(conn,
605 G_DBUS_PROXY_FLAGS_NONE, NULL,
606 BT_HAL_BLUEZ_NAME, path,
607 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
609 ERR("Fail to make device proxy");
611 g_dbus_method_invocation_return_error(invocation,
612 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
613 "No proxy for device");
615 ERR("Unable to create proxy: %s", err->message);
620 g_dbus_method_invocation_return_value(invocation, NULL);
621 priv->cb.display_func(priv, device, passkey);
622 g_object_unref(device);
624 } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
625 GapAgentPrivate *priv = user_data;
630 GDBusConnection *conn;
635 g_variant_get(parameters, "(&ou)", &path, &passkey);
636 INFO("Request passkey confirmation, Device Path :%s, Passkey: %d",
639 DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
641 if (g_strcmp0(sender, agent->busname) != 0)
644 DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
645 if (!priv->cb.confirm_func)
647 conn = _bt_hal_get_system_gconn();
650 device = g_dbus_proxy_new_sync(conn,
651 G_DBUS_PROXY_FLAGS_NONE, NULL,
652 BT_HAL_BLUEZ_NAME, path,
653 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
655 ERR("Fail to make device proxy");
656 g_dbus_method_invocation_return_error(invocation,
657 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
658 "No proxy for device");
660 ERR("Unable to create proxy: %s", err->message);
665 priv->exec_type = GAP_AGENT_EXEC_PAIRING;
666 priv->reply_context = invocation;
667 addr = strstr(path, "dev_");
671 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
673 while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
677 DBG("Pairing address [%s]", priv->pairing_addr);
678 priv->cb.confirm_func(priv, device, passkey);
679 g_object_unref(device);
681 } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
682 GapAgentPrivate *priv = user_data;
684 GDBusConnection *conn;
692 g_variant_get(parameters, "(&o&s)", &path, &uuid);
693 INFO("Request authorization :sender %s priv->busname %s "
694 "Device Path :%s UUID: %s",
695 sender, priv->busname, path, uuid);
698 if (g_strcmp0(sender, agent->busname) != 0)
702 if (!priv->cb.authorize_func)
705 conn = _bt_hal_get_system_gconn();
709 device = g_dbus_proxy_new_sync(conn,
710 G_DBUS_PROXY_FLAGS_NONE, NULL,
711 BT_HAL_BLUEZ_NAME, path,
712 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
715 ERR("Fail to make device proxy");
717 g_dbus_method_invocation_return_error(invocation,
718 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
719 "No proxy for device");
722 ERR("Unable to create proxy: %s", err->message);
729 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
730 priv->reply_context = invocation;
731 priv->uuid = g_strdup(uuid);
733 addr = strstr(path, "dev_");
737 g_strlcpy(priv->authorize_addr, addr,
738 sizeof(priv->authorize_addr));
740 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
744 priv->cb.authorize_func(priv, device, uuid);
746 g_object_unref(device);
748 } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
749 if (!TIZEN_PROFILE_WEARABLE) {
751 g_dbus_method_invocation_return_value(invocation, NULL);
753 /* TODO: This security feature is applicable for Mobile. */
754 GapAgentPrivate *priv = user_data;
755 char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
757 GDBusConnection *conn;
764 g_variant_get(parameters, "(&o)", &path);
765 DBG("Request authorization :sender %s priv->busname %s"
767 sender, priv->busname, path);
769 if (!priv->cb.authorize_func)
772 conn = _bt_hal_get_system_gconn();
776 device = g_dbus_proxy_new_sync(conn,
777 G_DBUS_PROXY_FLAGS_NONE, NULL,
778 BT_HAL_BLUEZ_NAME, path,
779 BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
782 ERR("Fail to make device proxy");
784 g_dbus_method_invocation_return_error(invocation,
785 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
786 "No proxy for device");
789 ERR("Unable to create proxy: %s", err->message);
796 priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
797 priv->reply_context = invocation;
799 addr = strstr(path, "dev_");
803 g_strlcpy(priv->authorize_addr, addr,
804 sizeof(priv->authorize_addr));
806 while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
810 priv->cb.authorize_func(priv, device, GAP_UUID);
812 g_object_unref(device);
815 } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
816 g_dbus_method_invocation_return_value(invocation, NULL);
817 } else if (g_strcmp0(method_name, "Cancel") == 0) {
818 GapAgentPrivate *priv = user_data;
822 INFO("Cancelled : agent %p sender %p", priv, sender);
824 if (g_strcmp0(sender, agent->busname) != 0)
827 if (priv->cb.authorization_cancel_func &&
828 priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
829 DBG("Call GAP agent cancel Authorization method.");
830 priv->cb.authorization_cancel_func(priv,
831 priv->authorize_addr);
832 memset(priv->authorize_addr, 0x00,
833 sizeof(priv->authorize_addr));
834 } else if (priv->cb.pairing_cancel_func &&
835 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
836 DBG("Call GAP agent cancel Pairing method.");
837 priv->cb.pairing_cancel_func(priv,
839 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
841 if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
842 priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
843 priv->reply_context != NULL) {
845 g_dbus_method_invocation_return_error(priv->reply_context,
846 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
847 "Rejected by remote cancel");
850 /* Canceled flag is set when user cancels pairing request
851 * Since here bluez has cancelled pairing request, we set the flag to false
853 priv->canceled = FALSE;
854 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
855 priv->reply_context = NULL;
857 } else if (g_strcmp0(method_name, "Release") == 0) {
858 GapAgentPrivate *priv = user_data;
863 INFO("Released : sender %s\n", sender);
866 if (g_strcmp0(sender, agent->busname) != 0)
870 g_dbus_method_invocation_return_value(invocation, NULL);
873 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
874 priv->reply_context = NULL;
876 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
877 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
880 } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
882 } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
883 GapAgentPrivate *priv = user_data;
884 const char *pin_code;
887 g_variant_get(parameters, "(u&s)", &accept, &pin_code);
888 INFO("Accept: %d PinCode: %s", accept, pin_code);
889 gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
890 } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
891 GapAgentPrivate *priv = user_data;
895 g_variant_get(parameters, "(u&s)", &accept, &passkey);
896 INFO("Accept: %d PinCode: %s", accept, passkey);
897 gap_agent_reply_passkey(priv, accept, passkey, invocation);
898 } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
899 GapAgentPrivate *priv = user_data;
902 g_variant_get(parameters, "(u)", &accept);
903 INFO("Accept: %d", accept);
904 gap_agent_reply_confirmation(priv, accept, invocation);
905 } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
906 GapAgentPrivate *priv = user_data;
909 g_variant_get(parameters, "(u)", &accept);
910 INFO("Accept: %d", accept);
911 gap_agent_reply_authorize(priv, accept, invocation);
913 ERR("Invalid method[%s] Object Path[%s] Interface Name[%s]",
914 method_name, object_path, interface_name);
918 gboolean gap_agent_reply_confirmation(GapAgentPrivate *agent, const guint accept,
919 GDBusMethodInvocation *context)
921 GapAgentPrivate *priv = agent;
923 /* Fix : NULL_RETURNS */
927 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
928 priv->reply_context != NULL) {
929 if (accept == GAP_AGENT_ACCEPT || accept == GAP_AGENT_ACCEPT_ALWAYS) {
930 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
931 priv->canceled = FALSE;
934 case GAP_AGENT_CANCEL:
935 g_dbus_method_invocation_return_error(priv->reply_context,
936 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
938 priv->canceled = TRUE;
940 case GAP_AGENT_TIMEOUT:
941 case GAP_AGENT_REJECT:
943 g_dbus_method_invocation_return_error(priv->reply_context,
944 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
945 "Confirmation request rejected");
946 priv->canceled = FALSE;
952 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
953 priv->reply_context = NULL;
954 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
959 gboolean gap_agent_reply_pin_code(GapAgentPrivate *agent, const guint accept,
960 const char *pin_code,
961 GDBusMethodInvocation *context)
963 GapAgentPrivate *priv = agent;
965 /* Fix : NULL_RETURNS */
969 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
970 priv->reply_context != NULL) {
971 if (accept == GAP_AGENT_ACCEPT) {
972 g_dbus_method_invocation_return_value(priv->reply_context,
973 g_variant_new("(s)", pin_code));
974 priv->canceled = FALSE;
977 case GAP_AGENT_CANCEL:
978 g_dbus_method_invocation_return_error(priv->reply_context,
979 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
981 priv->canceled = TRUE;
983 case GAP_AGENT_TIMEOUT:
984 case GAP_AGENT_REJECT:
986 g_dbus_method_invocation_return_error(priv->reply_context,
987 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
988 "Pairing request rejected");
989 priv->canceled = FALSE;
994 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
995 priv->reply_context = NULL;
996 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1001 gboolean gap_agent_reply_passkey(GapAgentPrivate *agent, const guint accept,
1002 const char *passkey,
1003 GDBusMethodInvocation *context)
1005 GapAgentPrivate *priv = agent;
1007 /* Fix : NULL_RETURNS */
1011 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
1012 priv->reply_context != NULL) {
1013 if (accept == GAP_AGENT_ACCEPT) {
1014 guint pass_key = atoi(passkey);
1015 g_dbus_method_invocation_return_value(priv->reply_context,
1016 g_variant_new("(u)", pass_key));
1017 priv->canceled = FALSE;
1020 case GAP_AGENT_CANCEL:
1021 g_dbus_method_invocation_return_error(priv->reply_context,
1022 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
1024 priv->canceled = TRUE;
1026 case GAP_AGENT_TIMEOUT:
1027 case GAP_AGENT_REJECT:
1029 g_dbus_method_invocation_return_error(priv->reply_context,
1030 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1031 "Passkey request rejected");
1032 priv->canceled = FALSE;
1038 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1039 priv->reply_context = NULL;
1040 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1045 gboolean gap_agent_reply_authorize(GapAgentPrivate *agent, const guint accept,
1046 GDBusMethodInvocation *context)
1048 gboolean ret = TRUE;
1049 GapAgentPrivate *priv = agent;
1051 /* Fix : NULL_RETURNS */
1055 if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
1056 priv->reply_context != NULL) {
1057 if (accept == GAP_AGENT_ACCEPT) {
1058 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1059 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
1060 bluetooth_device_address_t addr = { { 0, } };
1062 bt_trusted_profile_t profile;
1064 _bt_hal_convert_addr_string_to_type(addr.addr,
1065 priv->authorize_addr);
1067 profile = _bt_hal_get_trusted_profile_enum(priv->uuid);
1070 result = _bt_hal_device_set_trusted_profile((bt_bdaddr_t *)(&addr), profile, TRUE);
1072 result = _bt_hal_device_set_trust((bt_bdaddr_t *)(&addr), TRUE);
1074 if (result == BT_STATUS_SUCCESS) {
1075 INFO("[%s] Profile added as trusted for Device[%s]",
1076 priv->uuid, priv->authorize_addr);
1079 g_dbus_method_invocation_return_value(priv->reply_context, NULL);
1082 case GAP_AGENT_CANCEL:
1083 g_dbus_method_invocation_return_error(priv->reply_context,
1084 GAP_AGENT_ERROR, GAP_AGENT_ERROR_CANCEL,
1087 case GAP_AGENT_TIMEOUT:
1088 case GAP_AGENT_REJECT:
1090 g_dbus_method_invocation_return_error(priv->reply_context,
1091 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1092 "Authorization request rejected");
1098 g_dbus_method_invocation_return_value(context, NULL);
1102 g_dbus_method_invocation_return_error(context,
1103 GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
1108 priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1109 priv->reply_context = NULL;
1110 memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1120 bt_hal_agent_osp_server_t *_bt_hal_gap_agent_find_osp_server_by_type(GSList *servers, unsigned int type, const char *uuid)
1123 bt_hal_agent_osp_server_t *server;
1125 for (l = servers; l != NULL; l = g_slist_next(l)) {
1131 /* No uuid in obex server */
1132 if (type == BT_OSP_SERVER_OBEX
1133 && server->type == BT_OSP_SERVER_OBEX)
1136 if (g_strcmp0(server->uuid, uuid) == 0)
1143 gboolean _bt_hal_gap_agent_register_osp_server(GapAgentPrivate *agent, unsigned int type, char *uuid, char *path, int fd)
1145 bt_hal_agent_osp_server_t *server;
1147 GapAgentPrivate *priv = agent;
1151 if (type >= BT_OSP_SERVER_MAX)
1154 server = g_malloc0(sizeof(bt_hal_agent_osp_server_t));
1155 server->type = type;
1156 if (type == BT_OSP_SERVER_RFCOMM && uuid && path) {
1157 server->uuid = g_strdup(uuid);
1158 server->path = g_strdup(path);
1161 priv->osp_servers = g_slist_append(priv->osp_servers, server);
1166 gboolean _bt_hal_gap_agent_unregister_osp_server(GapAgentPrivate *agent, unsigned int type, char *uuid)
1168 bt_hal_agent_osp_server_t *server;
1170 GapAgentPrivate *priv = agent;
1175 if (type >= BT_OSP_SERVER_MAX)
1178 server = _bt_hal_gap_agent_find_osp_server_by_type(priv->osp_servers, type, uuid);
1182 priv->osp_servers = g_slist_remove(priv->osp_servers, server);
1183 __bt_hal_free_osp_server(server);