+ FN_START;
+
+ BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]",
+ method_name, object_path, interface_name);
+
+ GError *err = NULL;
+
+ if (g_strcmp0(method_name, "RequestPinCode") == 0) {
+ GapAgentPrivate *agent = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ char *addr;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o)", &path);
+ BT_INFO("Request pin code, Device Path :%s", path);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!agent->cb.passkey_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ agent->exec_type = GAP_AGENT_EXEC_PAIRING;
+ agent->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(agent->pairing_addr, addr, sizeof(agent->pairing_addr));
+
+ while ((pos = strchr(agent->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ agent->cb.pincode_func(agent, device);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ char *addr;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o)", &path);
+ BT_INFO("Request passkey : sender %s priv->busname %s Device Path :%s",
+ sender, priv->busname, path);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.passkey_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_PAIRING;
+ priv->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
+
+ while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.passkey_func(priv, device);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ guint passkey;
+ guint16 entered;
+ char *path;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&ouq)", &path, &passkey, &entered);
+ BT_INFO("Request passkey display :sender %s priv->busname %s"
+ " Device Path :%s, Passkey: %06d, Entered: %d",
+ sender, priv->busname, path, passkey, entered);
+
+ /* Do not show popup for Key event while typing*/
+ if (entered)
+ return;
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.display_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+
+ priv->cb.display_func(priv, device, passkey);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ guint passkey;
+ char *path;
+ char *addr;
+ GDBusConnection *conn;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&ou)", &path, &passkey);
+ BT_INFO_C("### Request passkey confirmation");
+ INFO_SECURE("Device Path :%s, Passkey: %d", path, passkey);
+
+ BT_DBG("Sender: [%s] priv->busname: [%s]", sender, priv->busname);
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ BT_DBG("priv->cb.confirm_func [%p]", priv->cb.confirm_func);
+ if (!priv->cb.confirm_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_PAIRING;
+ priv->reply_context = invocation;
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
+
+ while ((pos = strchr(priv->pairing_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.confirm_func(priv, device, passkey);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+ GDBusProxy *device;
+ GDBusConnection *conn;
+ char *addr;
+ char *path;
+ char *uuid;
+
+ if (sender == NULL)
+ return;
+
+ g_variant_get(parameters, "(&o&s)", &path, &uuid);
+ BT_DBG("Request authorization :sender %s priv->busname %s "
+ "Device Path :%s UUID: %s",
+ sender, priv->busname, path, uuid);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (!priv->cb.authorize_func)
+ return;
+
+ conn = _bt_gdbus_get_system_gconn();
+ if (conn == NULL)
+ return;
+
+ device = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, path,
+ BT_PROPERTIES_INTERFACE, NULL, &err);
+
+ if (!device) {
+ BT_ERR("Fail to make device proxy");
+
+ g_dbus_method_invocation_return_error(invocation,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "No proxy for device");
+
+ if (err) {
+ ERR("Unable to create proxy: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ return;
+ }
+
+ priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
+ priv->reply_context = invocation;
+ priv->uuid = g_strdup(uuid);
+
+ addr = strstr(path, "dev_");
+ if (addr != NULL) {
+ char *pos = NULL;
+ addr += 4;
+ g_strlcpy(priv->authorize_addr, addr,
+ sizeof(priv->authorize_addr));
+
+ while ((pos = strchr(priv->authorize_addr, '_')) != NULL)
+ *pos = ':';
+ }
+
+ priv->cb.authorize_func(priv, device, uuid);
+
+ g_object_unref(device);
+ return;
+
+ } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ } else if (g_strcmp0(method_name, "Cancel") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (sender == NULL)
+ return;
+
+ BT_DBG("Cancelled : agent %p sender %s", sender);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ if (priv->cb.authorization_cancel_func &&
+ priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
+ priv->cb.authorization_cancel_func(priv,
+ priv->authorize_addr);
+ memset(priv->authorize_addr, 0x00,
+ sizeof(priv->authorize_addr));
+ } else if (priv->cb.pairing_cancel_func &&
+ priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
+ priv->cb.pairing_cancel_func(priv,
+ priv->pairing_addr);
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+ }
+
+ if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
+ priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
+ priv->reply_context != NULL) {
+
+ g_dbus_method_invocation_return_error(priv->reply_context,
+ GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+ "Rejected by remote cancel");
+ }
+
+ /* Canceled flag is set when user cancels pairing request
+ * Since here bluez has cancelled pairing request, we set the flag to false
+ */
+ priv->canceled = FALSE;
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+
+ return;
+ } else if (g_strcmp0(method_name, "Release") == 0) {
+ GapAgentPrivate *priv = user_data;
+ char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+
+ if (sender == NULL)
+ return;
+
+ BT_DBG("Released : sender %s\n", sender);
+
+ /* Need to check
+ if (g_strcmp0(sender, agent->busname) != 0)
+ return;
+ */
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+
+ priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+ priv->reply_context = NULL;
+
+ memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+ memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
+
+ return;
+ } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
+ BT_DBG("+");
+
+ int timeout;
+
+ _bt_get_timeout_value(&timeout);
+
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(i)", timeout));
+
+ BT_DBG("-");
+
+ return;
+ } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const char *pin_code;
+ const guint accept;
+
+ g_variant_get(parameters, "(u&s)", &accept, &pin_code);
+ BT_DBG("Accept: %d PinCode: %s", accept, pin_code);
+ gap_agent_reply_pin_code(priv, accept, pin_code, invocation);
+ } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const char *passkey;
+ const guint accept;
+
+ g_variant_get(parameters, "(u&s)", &accept, &passkey);
+ BT_DBG("Accept: %d PinCode: %s", accept, passkey);
+ gap_agent_reply_passkey(priv, accept, passkey, invocation);
+ } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const guint accept;
+
+ g_variant_get(parameters, "(u)", &accept);
+ BT_DBG("Accept: %d", accept);
+ gap_agent_reply_confirmation(priv, accept, invocation);
+ } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
+ GapAgentPrivate *priv = user_data;
+ const guint accept;
+
+ g_variant_get(parameters, "(u)", &accept);
+ BT_DBG("Accept: %d", accept);
+ gap_agent_reply_authorize(priv, accept, invocation);
+ }
+}
+
+static const GDBusInterfaceVTable method_table = {
+ __bt_gap_agent_method,
+ NULL,
+ NULL,
+};
+
+void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
+ const char *path,
+ GDBusProxy *adapter)
+{
+ GapAgentPrivate *priv = agent;
+ GDBusProxy *proxy;
+ GDBusNodeInfo *node_info;
+ GError *error = NULL;