[Adapt: Bluez HAL] Add GAP agent in Bluez HAL 91/78491/1
authorAnupam Roy <anupam.r@samsung.com>
Tue, 5 Jul 2016 15:40:37 +0000 (11:40 -0400)
committerAnupam Roy <anupam.r@samsung.com>
Tue, 5 Jul 2016 16:37:39 +0000 (12:37 -0400)
Change-Id: Iaffa998d8531781eac6c9e613ad2e05aed693ba8
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-oal/bluez_hal/CMakeLists.txt
bt-oal/bluez_hal/src/bt-hal-agent.c [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-agent.h [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h
bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c
bt-oal/bluez_hal/src/bt-hal-event-receiver.c
bt-oal/bluez_hal/src/bt-hal-gap-agent1.c [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-gap-agent1.h [new file with mode: 0644]

index eb2a75d..016ed83 100644 (file)
@@ -8,6 +8,8 @@ SET(SRCS
 ./src/bt-hal-dbus-common-utils.c
 ./src/bt-hal-event-receiver.c
 ./src/bt-hal-utils.c
+./src/bt-hal-gap-agent1.c
+./src/bt-hal-agent.c
 )
 
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
diff --git a/bt-oal/bluez_hal/src/bt-hal-agent.c b/bt-oal/bluez_hal/src/bt-hal-agent.c
new file mode 100644 (file)
index 0000000..535c951
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <malloc.h>
+#include <syspopup_caller.h>
+#include <vconf.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <eventsystem.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+
+/* BT HAL Headers */
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-internal.h"
+#include "bt-hal-event-receiver.h"
+#include "bt-hal-dbus-common-utils.h"
+
+#include "bt-hal-adapter-dbus-handler.h"
+#include "bt-hal-event-receiver.h"
+
+#include <bt-hal-agent.h>
+#include <bt-hal-gap-agent1.h>
+#include <bt-hal-dbus-common-utils.h>
+
+static void *adapter_agent = NULL;
+
+void* _bt_hal_create_agent(const char *path, gboolean adapter)
+{
+       GAP_AGENT_FUNC_CB func_cb;
+       GDBusProxy *adapter_proxy;
+       GapAgentPrivate *agent;
+
+       DBG("+");
+       adapter_proxy = _bt_get_adapter_proxy();
+       if (!adapter_proxy)
+               return NULL;
+
+       func_cb.pincode_func = NULL;
+       func_cb.display_func = NULL;
+       func_cb.passkey_func = NULL;
+       func_cb.confirm_func = NULL;
+       func_cb.authorize_func = NULL;
+       func_cb.pairing_cancel_func = NULL;
+       func_cb.authorization_cancel_func = NULL;
+
+       /* Allocate memory*/
+       agent = g_new0(GapAgentPrivate, 1);
+
+       _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
+
+       if (adapter) {
+               if (!_gap_agent_register(agent)) {
+                       ERR("gap agent registration failed!");
+                       _bt_hal_destroy_agent(agent);
+                       agent = NULL;
+               }
+       }
+       DBG("-");
+       return agent;
+}
+
+void _bt_hal_destroy_agent(void *agent)
+{
+       DBG("+");
+       if (!agent)
+               return;
+
+       _gap_agent_reset_dbus((GapAgentPrivate *)agent);
+
+       g_free(agent);
+       DBG("-");
+}
+
+gboolean _bt_hal_agent_is_canceled(void)
+{
+       void *agent = _bt_hal_get_adapter_agent();
+       if (!agent)
+               return FALSE;
+
+       return _gap_agent_is_canceled(agent);
+}
+
+int _bt_hal_agent_reply_cancellation(void)
+{
+       void *agent = _bt_hal_get_adapter_agent();
+       if (!agent)
+               return BT_STATUS_FAIL;
+       /* TODO Handle GAP Agent Cancel */
+       return BT_STATUS_SUCCESS;
+}
+
+void _bt_hal_agent_set_canceled(gboolean value)
+{
+       void *agent = _bt_hal_get_adapter_agent();
+       if (!agent)
+               return;
+
+       return _gap_agent_set_canceled(agent, value);
+}
+
+void _bt_hal_initialize_adapter_agent(void)
+{
+       adapter_agent = _bt_hal_create_agent(BT_HAL_ADAPTER_AGENT_PATH, TRUE);
+       if (!adapter_agent) {
+               ERR("Fail to register agent");
+               return;
+       }
+}
+
+void _bt_hal_destroy_adapter_agent(void)
+{
+       if (adapter_agent)
+               _bt_hal_destroy_agent(adapter_agent);
+       adapter_agent = NULL;
+}
+
+void* _bt_hal_get_adapter_agent(void)
+{
+       return adapter_agent;
+}
diff --git a/bt-oal/bluez_hal/src/bt-hal-agent.h b/bt-oal/bluez_hal/src/bt-hal-agent.h
new file mode 100644 (file)
index 0000000..f54dbd4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __BT_HAL_AGENT_H__
+#define __BT_HAL_AGENT_H__
+
+#include <stdint.h>
+#include <glib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+void* _bt_hal_create_agent(const char *path, gboolean adapter);
+
+void _bt_hal_destroy_agent(void *agent);
+
+gboolean _bt_hal_agent_is_canceled(void);
+
+void _bt_hal_agent_set_canceled(gboolean value);
+
+int _bt_hal_agent_reply_cancellation(void);
+
+void* _bt_hal_get_adapter_agent(void);
+
+void _bt_hal_initialize_adapter_agent(void);
+
+void _bt_hal_destroy_adapter_agent(void);
+
+#endif //__BT_HAL_AGENT__
index f6527f0..9ca55a9 100644 (file)
@@ -71,6 +71,9 @@ extern "C" {
 #define BT_HAL_MANAGER_PATH "/"
 #define BT_HAL_BLUEZ_HCI_PATH "/org/bluez/hci0"
 
+#define BT_HAL_DEVICE_AGENT_PATH "/org/tizen/device_agent"
+#define BT_HAL_ADAPTER_AGENT_PATH "/org/tizen/adapter_agent"
+
 #define BT_HAL_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
 #define BT_HAL_ADAPTER_INTERFACE "org.bluez.Adapter1"
 #define BT_HAL_DEVICE_INTERFACE "org.bluez.Device1"
index 859ccd4..dc81b70 100644 (file)
 #include "bt-hal-adapter-dbus-handler.h"
 #include "bt-hal-device-dbus-handler.h"
 #include "bt-hal-event-receiver.h"
+#include "bt-hal-agent.h"
 
 static handle_stack_msg event_cb = NULL;
 
 /* Forward Delcaration */
-static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data);
+static void __bt_hal_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data);
 
-static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
+static void __bt_hal_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
                                         gpointer user_data);
 
 int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr)
@@ -127,7 +128,7 @@ int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr)
                        G_DBUS_CALL_FLAGS_NONE,
                        BT_HAL_MAX_DBUS_TIMEOUT,
                        NULL,
-                       (GAsyncReadyCallback)__bt_bond_device_cb,
+                       (GAsyncReadyCallback)__bt_hal_bond_device_cb,
                        NULL);
 
        /* Prepare to send Bonding event event to HAL bluetooth */
@@ -219,14 +220,14 @@ int _bt_hal_device_remove_bond(const bt_bdaddr_t *bd_addr)
                        G_DBUS_CALL_FLAGS_NONE,
                        BT_HAL_MAX_DBUS_TIMEOUT,
                        NULL,
-                       (GAsyncReadyCallback)__bt_unbond_device_cb,
+                       (GAsyncReadyCallback)__bt_hal_unbond_device_cb,
                        (gpointer)device_path);
 
        DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
-static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
+static void __bt_hal_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
                                         gpointer user_data)
 {
        GError *err = NULL;
@@ -252,21 +253,37 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
                g_dbus_error_strip_remote_error(err);
                ERR("@@@Error occured in CreateBonding [%s]", err->message);
                if (g_strrstr(err->message, "Already Exists")) {
-                       DBG("Existing Bond, remove and retry");
+                       ERR("Still bond existing even after remove");
+                       result = BT_STATUS_AUTH_FAILURE;
                } else if (g_strrstr(err->message, "Authentication Rejected")) {
-                       DBG("REJECTED");
+                       INFO("REJECTED");
+                       result = BT_STATUS_AUTH_REJECTED;
+               } else if (_bt_hal_agent_is_canceled() ||
+                               g_strrstr(err->message, "Authentication Canceled")) {
+                       INFO("Cancelled by USER");
+                       result = BT_STATUS_AUTH_FAILURE;
                } else if (g_strrstr(err->message, "In Progress")) {
-                       DBG("Bond in progress, cancel and retry");
+                       INFO("Bond in progress, cancel and retry");
                } else if (g_strrstr(err->message, "Authentication Failed")) {
-                       DBG("Authentication Failed");
+                       INFO("Authentication Failed");
                        result = BT_STATUS_AUTH_FAILURE;
                } else if (g_strrstr(err->message, "Page Timeout")) {
-                       DBG("Page Timeout");
+                       INFO("Page Timeout");
+                       /* This is the special case
+                          As soon as call bluetooth_bond_device, try to cancel bonding.
+                          In this case, before completing to call 'CreatePairedDevice' method
+                          the procedure is stopped. So 'Cancle' error is not return.
+                        */
                        result = BT_STATUS_RMT_DEV_DOWN;
                } else if (g_strrstr(err->message, BT_HAL_TIMEOUT_MESSAGE)) {
-                       DBG("Timeout");
+                       INFO("Timeout");
+                       result = BT_STATUS_FAIL;
                } else if (g_strrstr(err->message, "Connection Timeout")) {
+                       /* Pairing request timeout */
+                       result = BT_STATUS_RMT_DEV_DOWN;
                } else if (g_strrstr(err->message, "Authentication Timeout")) {
+                       /* Pairing request timeout */
+                       result = BT_STATUS_AUTH_FAILURE;
                } else {
                        DBG("Default case: Pairing failed");
                        result = BT_STATUS_AUTH_FAILURE;
@@ -274,7 +291,9 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
        }
 
        if (result == BT_STATUS_AUTH_FAILURE ||
-                       result == BT_STATUS_RMT_DEV_DOWN) {
+                       result == BT_STATUS_RMT_DEV_DOWN ||
+                       result == BT_STATUS_AUTH_REJECTED ||
+                       result == BT_STATUS_FAIL) {
                DBG("Bonding Failed!!");
        } else {
                DBG("Bonding Success!!");
@@ -298,7 +317,7 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
        DBG("-");
 }
 
-static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
+static void __bt_hal_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
                                         gpointer user_data)
 {
        GError *err = NULL;
index cd56b24..3ae7c81 100644 (file)
@@ -37,6 +37,7 @@
 #include "bt-hal-internal.h"
 #include "bt-hal-event-receiver.h"
 #include "bt-hal-dbus-common-utils.h"
+#include "bt-hal-agent.h"
 
 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
                + sizeof(struct hal_property))
@@ -243,12 +244,14 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                                ev.state = HAL_POWER_OFF;
                                event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
                                /* Destroy Agent */
+                               _bt_hal_destroy_adapter_agent();
                        } else {
                                DBG("###### Adapter Powered Up ######");
                                struct hal_ev_adapter_state_changed ev;
                                ev.state = HAL_POWER_ON;
                                event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
                                /* Create Agent */
+                               _bt_hal_initialize_adapter_agent();
                        }
 
                } else if (!g_strcmp0(key, "Pairable")) {
diff --git a/bt-oal/bluez_hal/src/bt-hal-gap-agent1.c b/bt-oal/bluez_hal/src/bt-hal-gap-agent1.c
new file mode 100644 (file)
index 0000000..9c10eec
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include  <bt-hal-gap-agent1.h>
+#include  <bt-hal-agent.h>
+#include  <bt-hal-internal.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-utils.h"
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+
+#include "bt-hal-adapter-dbus-handler.h"
+#include "bt-hal-dbus-common-utils.h"
+
+static GDBusConnection *connection = NULL;
+
+typedef enum {
+       GAP_AGENT_ERROR_REJECT,
+       GAP_AGENT_ERROR_CANCEL,
+       GAP_AGENT_ERROR_TIMEOUT,
+} GapAgentError;
+
+
+/* Forward declaration */
+static gboolean __gap_agent_unregister(GapAgentPrivate *agent);
+static GDBusNodeInfo *__bt_service_create_method_node_info
+(const gchar *introspection_data);
+static void __bt_gap_agent_method(GDBusConnection *connection,
+               const gchar *sender,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *method_name,
+               GVariant *parameters,
+               GDBusMethodInvocation *invocation,
+               gpointer user_data);
+void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
+
+
+
+static gint gap_agent_id = -1;
+
+gboolean _gap_agent_register(GapAgentPrivate *agent)
+{
+       GapAgentPrivate *priv = agent;
+       GDBusProxy *agent_manager;
+       GError *error = NULL;
+       GVariant *reply;
+
+       if (!priv)
+               return FALSE;
+       if (!connection)
+               return FALSE;
+
+       if (priv->agent_manager == NULL) {
+               agent_manager = g_dbus_proxy_new_sync(connection,
+                               G_DBUS_PROXY_FLAGS_NONE, NULL,
+                               BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
+                               BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
+               if (!agent_manager) {
+                       if (error) {
+                               ERR("Unable to create proxy: %s", error->message);
+                               g_clear_error(&error);
+                       }
+                       return FALSE;
+               }
+       } else {
+               agent_manager = priv->agent_manager;
+       }
+
+       reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent",
+#ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT
+                       g_variant_new("(os)", priv->path, "NoInputNoOutput"),
+#else
+                       g_variant_new("(os)", priv->path, "DisplayYesNo"),
+#endif
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &error);
+       if (reply == NULL) {
+               ERR("Agent registration failed");
+               if (error) {
+                       ERR("Agent registration failed: errCode[%x], message[%s]",
+                                       error->code, error->message);
+                       g_clear_error(&error);
+               }
+               g_object_unref(agent_manager);
+               priv->agent_manager = NULL;
+               return FALSE;
+       }
+       g_variant_unref(reply);
+       reply = NULL;
+
+       /* Set the defalut agent */
+       DBG("agent_manager[%p] priv->path[%s]", agent_manager, priv->path);
+       reply = g_dbus_proxy_call_sync(agent_manager, "RequestDefaultAgent",
+                       g_variant_new("(o)", priv->path),
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &error);
+       if (reply == NULL) {
+               ERR("Request Default Agent failed");
+               if (error) {
+                       ERR("Request Default Agent failed: errCode[%x], message[%s]",
+                                       error->code, error->message);
+                       g_clear_error(&error);
+               }
+               g_object_unref(agent_manager);
+               priv->agent_manager = NULL;
+               return FALSE;
+       }
+       g_variant_unref(reply);
+
+       priv->agent_manager = agent_manager;
+
+       return TRUE;
+}
+
+
+static const gchar gap_agent_bluez_introspection_xml[] =
+"<node name='/'>"
+"  <interface name='org.bluez.Agent1'>"
+"    <method name='RequestPinCode'>"
+"      <arg type='o' name='device' direction='in'/>"
+"      <arg type='s' name='pincode' direction='out'/>"
+"    </method>"
+"    <method name='RequestPasskey'>"
+"      <arg type='o' name='device' direction='in'/>"
+"      <arg type='u' name='passkey' direction='out'/>"
+"    </method>"
+"    <method name='DisplayPasskey'>"
+"      <arg type='o' name='device' direction='in'/>"
+"      <arg type='u' name='passkey' direction='in'/>"
+"      <arg type='q' name='entered' direction='in'/>"
+"    </method>"
+"    <method name='RequestConfirmation'>"
+"      <arg type='o' name='device' direction='in'/>"
+"      <arg type='u' name='passkey' direction='in'/>"
+"    </method>"
+"    <method name='RequestAuthorization'>"
+"      <arg type='o' name='device' direction='in'/>"
+"    </method>"
+"    <method name='AuthorizeService'>"
+"      <arg type='o' name='device' direction='in'/>"
+"      <arg type='s' name='uuid' direction='in'/>"
+"    </method>"
+"    <method name='Cancel'>"
+"    </method>"
+"    <method name='Release'>"
+"    </method>"
+"    <method name='ReplyPinCode'>"
+"      <arg type='u' name='accept' direction='in'/>"
+"      <arg type='s' name='pincode' direction='in'/>"
+"    </method>"
+"    <method name='ReplyPasskey'>"
+"      <arg type='u' name='accept' direction='in'/>"
+"      <arg type='s' name='passkey' direction='in'/>"
+"    </method>"
+"    <method name='ReplyConfirmation'>"
+"      <arg type='u' name='accept' direction='in'/>"
+"    </method>"
+"    <method name='ReplyAuthorize'>"
+"      <arg type='u' name='accept' direction='in'/>"
+"    </method>"
+"    <method name='ConfirmModeChange'>"
+"      <arg type='s' name='mode' direction='in'/>"
+"    </method>"
+"    <method name='GetDiscoverableTimeout'>"
+"      <arg type='u' name='timeout' direction='out'/>"
+"    </method>"
+"  </interface>"
+"</node>";
+
+
+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;
+       DBG("+");
+
+       priv->path = g_strdup(path);
+
+       node_info = __bt_service_create_method_node_info(
+                       gap_agent_bluez_introspection_xml);
+       if (node_info == NULL)
+               return;
+
+       DBG("path is [%s]", path);
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (!connection) {
+               if (error) {
+                       ERR("Unable to connect to gdbus: %s", error->message);
+                       g_clear_error(&error);
+               }
+               return;
+       }
+
+       if (gap_agent_id == -1) {
+               gap_agent_id = g_dbus_connection_register_object(connection, path,
+                               node_info->interfaces[0],
+                               &method_table, priv,
+                               NULL, &error);
+       }
+
+       g_dbus_node_info_unref(node_info);
+
+       if (gap_agent_id == 0) {
+               ERR("Failed to register for Path: %s", path);
+               if (error) {
+                       ERR("Failed to register: %s", error->message);
+                       g_clear_error(&error);
+               }
+               return;
+       }
+
+       memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
+
+       priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
+       memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
+       memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
+       priv->reply_context = NULL;
+
+       DBG("path: %s", path);
+
+       proxy =  g_dbus_proxy_new_sync(connection,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       BT_HAL_BLUEZ_NAME, path,
+                       BT_HAL_AGENT_INTERFACE, NULL, &error);
+
+       if (!proxy) {
+               ERR("Unable to create proxy");
+               if (error) {
+                       ERR("Error: %s", error->message);
+                       g_clear_error(&error);
+               }
+               priv->busname = NULL;
+       } else {
+               priv->busname = g_strdup(g_dbus_proxy_get_name(proxy));
+               g_object_unref(proxy);
+               DBG("Busname: %s", priv->busname);
+       }
+       DBG("-");
+}
+
+
+void _gap_agent_reset_dbus(GapAgentPrivate *agent)
+{
+       GapAgentPrivate *priv = agent;
+
+       /* Fix : NULL_RETURNS */
+       if (priv == NULL)
+               return ;
+
+       __gap_agent_unregister(agent);
+
+       if (gap_agent_id > 0) {
+
+               if (connection)
+                       g_dbus_connection_unregister_object(connection,
+                                       gap_agent_id);
+               gap_agent_id = -1;
+       }
+       /*TODO*/
+#if 0
+       if (priv->osp_servers) {
+               __gap_agent_remove_osp_servers(priv->osp_servers);
+               g_slist_free(priv->osp_servers);
+               priv->osp_servers = NULL;
+       }
+#endif
+       g_object_ref(priv->adapter);
+       priv->adapter = NULL;
+
+       g_free(priv->path);
+       priv->path = NULL;
+
+       g_free(priv->busname);
+       priv->busname = NULL;
+}
+
+gchar* _gap_agent_get_path(GapAgentPrivate *agent)
+{
+       GapAgentPrivate *priv = agent;
+
+       /* Fix : NULL_RETURNS */
+       if (priv == NULL)
+               return NULL;
+
+       return priv->path;
+}
+
+gboolean _gap_agent_is_canceled(GapAgentPrivate *agent)
+{
+       GapAgentPrivate *priv = agent;
+
+       /* Fix : NULL_RETURNS */
+       if (priv == NULL)
+               return  FALSE;
+
+       return priv->canceled;
+}
+
+void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value)
+{
+       GapAgentPrivate *priv = agent;
+
+       /* Fix : NULL_RETURNS */
+       if (priv == NULL)
+               return;
+
+       priv->canceled = value;
+}
+
+static gboolean __gap_agent_unregister(GapAgentPrivate *agent)
+{
+       GapAgentPrivate *priv = agent;
+       GDBusProxy *agent_manager;
+       GError *error = NULL;
+       GVariant *reply;
+
+       if (priv == NULL || priv->path == NULL|| connection == NULL )
+               return  FALSE;
+
+       if (priv->agent_manager == NULL) {
+               agent_manager = g_dbus_proxy_new_sync(connection,
+                               G_DBUS_PROXY_FLAGS_NONE, NULL,
+                               BT_HAL_BLUEZ_NAME, BT_HAL_BLUEZ_PATH,
+                               BT_HAL_AGENT_MANAGER_INTERFACE, NULL, &error);
+               if (!agent_manager) {
+                       if (error) {
+                               ERR("Unable to create proxy: %s", error->message);
+                               g_clear_error(&error);
+                       }
+                       return FALSE;
+               }
+       } else {
+               agent_manager = priv->agent_manager;
+       }
+
+       reply = g_dbus_proxy_call_sync(agent_manager, "UnregisterAgent",
+                       g_variant_new("o", priv->path),
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &error);
+       g_object_unref(agent_manager);
+       priv->agent_manager = NULL;
+
+       if (reply == NULL) {
+               ERR("Agent unregistration failed");
+               if (error) {
+                       ERR("Agent unregistration failed: errCode[%x], message[%s]",
+                                       error->code, error->message);
+                       g_clear_error(&error);
+               }
+               return FALSE;
+       }
+       g_variant_unref(reply);
+
+       return TRUE;
+}
+
+       static GDBusNodeInfo *__bt_service_create_method_node_info
+(const gchar *introspection_data)
+{
+       GError *err = NULL;
+       GDBusNodeInfo *node_info = NULL;
+
+       if (introspection_data == NULL)
+               return NULL;
+
+       node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
+
+       if (err) {
+               ERR("Unable to create node: %s", err->message);
+               g_clear_error(&err);
+       }
+       return node_info;
+}
+
+static void __bt_gap_agent_method(GDBusConnection *connection,
+               const gchar *sender,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *method_name,
+               GVariant *parameters,
+               GDBusMethodInvocation *invocation,
+               gpointer user_data)
+{
+       DBG("+");
+       FN_START;
+
+       DBG("Method[%s] Object Path[%s] Interface Name[%s]",
+                       method_name, object_path, interface_name);
+       /* TODO Fill handlers */
+       if (g_strcmp0(method_name, "RequestPinCode") == 0) {
+       } else if (g_strcmp0(method_name, "RequestPasskey") == 0) {
+       } else if (g_strcmp0(method_name, "DisplayPasskey") == 0) {
+       } else if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
+       } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
+       } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
+       } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
+       } else if (g_strcmp0(method_name, "Cancel") == 0) {
+       } else if (g_strcmp0(method_name, "Release") == 0) {
+       } else if (g_strcmp0(method_name, "GetDiscoverableTimeout") == 0) {
+       } else if (g_strcmp0(method_name, "ReplyPinCode") == 0) {
+       } else if (g_strcmp0(method_name, "ReplyPasskey") == 0) {
+       } else if (g_strcmp0(method_name, "ReplyConfirmation") == 0) {
+       } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
+       }
+       DBG("-");
+}
diff --git a/bt-oal/bluez_hal/src/bt-hal-gap-agent1.h b/bt-oal/bluez_hal/src/bt-hal-gap-agent1.h
new file mode 100644 (file)
index 0000000..0ee2145
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __BT_HAL_GAP_AGENT_1_H__
+#define _BT_HAL_GAP_AGENT_1_H__
+
+#include <stdint.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+typedef enum {
+       GAP_AGENT_EXEC_NO_OPERATION,
+       GAP_AGENT_EXEC_PAIRING,
+       GAP_AGENT_EXEC_AUTHORZATION,
+       GAP_AGENT_EXEC_CONFIRM_MODE,
+} GapAgentExecType;
+
+typedef struct _GapAgentPrivate GapAgentPrivate;
+
+typedef gboolean(*GapAgentPasskeyFunc) (GapAgentPrivate *agent,
+               GDBusProxy *device);
+typedef gboolean(*GapAgentDisplayFunc) (GapAgentPrivate *agent, GDBusProxy *device,
+               guint passkey);
+typedef gboolean(*GapAgentConfirmFunc) (GapAgentPrivate *agent, GDBusProxy *device,
+               guint passkey);
+typedef gboolean(*GapAgentAuthorizeFunc) (GapAgentPrivate *agent,
+               GDBusProxy *device, const char *uuid);
+typedef gboolean(*GapAgentConfirmModeFunc) (GapAgentPrivate *agent,
+               const char *mode, const char *sender,
+               gboolean need_popup, void *data);
+typedef gboolean(*GapAgentCancelFunc) (GapAgentPrivate *agent,
+               const char *address);
+
+typedef uint8_t bool_t;
+
+typedef struct {
+       GapAgentPasskeyFunc pincode_func;
+       GapAgentDisplayFunc display_func;
+       GapAgentPasskeyFunc passkey_func;
+       GapAgentConfirmFunc confirm_func;
+       GapAgentAuthorizeFunc authorize_func;
+       GapAgentCancelFunc pairing_cancel_func;
+       GapAgentCancelFunc authorization_cancel_func;
+} GAP_AGENT_FUNC_CB;
+
+typedef enum {
+       GAP_AGENT_ACCEPT,
+       GAP_AGENT_REJECT,
+       GAP_AGENT_CANCEL,
+       GAP_AGENT_TIMEOUT,
+       GAP_AGENT_ACCEPT_ALWAYS,
+} GAP_AGENT_ACCEPT_TYPE_T;
+
+struct _GapAgentPrivate {
+       gchar *busname;
+       gchar *path;
+       GDBusProxy *adapter;
+       GDBusProxy *agent_manager;
+       GDBusProxy *dbus_proxy;
+       GapAgentExecType exec_type;
+       GDBusMethodInvocation *reply_context;
+
+       char pairing_addr[18];
+       char authorize_addr[18];
+
+       GSList *osp_servers;
+       GAP_AGENT_FUNC_CB cb;
+       gboolean canceled;
+};
+
+void _gap_agent_setup_dbus(GapAgentPrivate *agent, GAP_AGENT_FUNC_CB *func_cb,
+               const char *path, GDBusProxy *adapter);
+
+gboolean _gap_agent_register(GapAgentPrivate *agent);
+
+void _gap_agent_reset_dbus(GapAgentPrivate *agent);
+
+gchar* _gap_agent_get_path(GapAgentPrivate *agent);
+
+gboolean _gap_agent_is_canceled(GapAgentPrivate *agent);
+
+void _gap_agent_set_canceled(GapAgentPrivate *agent, gboolean value);
+
+#endif //_BT_HAL_GAP_AGENT_1_H__