CAPI for hid host init and deinit 93/22793/1
authorGu Chaojie <chao.jie.gu@intel.com>
Thu, 12 Jun 2014 06:26:11 +0000 (14:26 +0800)
committerGu Chaojie <chao.jie.gu@intel.com>
Thu, 12 Jun 2014 06:26:44 +0000 (14:26 +0800)
Change-Id: I9871b5da7390ecdcca6f610febe2addef35c7b8c
Signed-off-by: Gu Chaojie <chao.jie.gu@intel.com>
capi/bluetooth.c
include/bluez.h
lib/bluez.c
test/bluez-capi-test.c

index d3555fb..b4aeabb 100644 (file)
@@ -178,6 +178,11 @@ struct socket_connection_state_changed_cb_node {
        void *user_data;
 };
 
+struct hid_host_connection_state_changed_cb_node {
+       bt_hid_host_connection_state_changed_cb cb;
+       void *user_data;
+};
+
 static struct device_connect_cb_node *device_connect_node;
 static struct device_disconnect_cb_node *device_disconnect_node;
 static struct avrcp_repeat_mode_changed_node *avrcp_repeat_node;
@@ -208,6 +213,7 @@ static struct socket_connection_requested_cb_node
                                        *socket_connection_requested_node;
 static struct socket_connection_state_changed_cb_node
                                        *socket_connection_state_node;
+static struct hid_host_connection_state_changed_cb_node *hid_host_state_node;
 
 static gboolean generic_device_removed_set;
 
@@ -606,6 +612,21 @@ static void device_panu_connected_changed(bluez_device_t *device,
        g_free(device_address);
 }
 
+static void device_hid_connected_changed(bluez_device_t *device,
+                                       int connected, void *user_data)
+{
+       struct hid_host_connection_state_changed_cb_node *node = user_data;
+       char *device_address;
+
+       DBG("");
+
+       device_address = bluez_device_get_property_address(device);
+
+       node->cb(BT_SUCCESS, connected, device_address, node->user_data);
+
+       g_free(device_address);
+}
+
 static unsigned int dev_property_callback_flags;
 
 enum bluez_device_property_callback_flag {
@@ -614,7 +635,8 @@ enum bluez_device_property_callback_flag {
        DEV_PROP_FLAG_AUTH = 0x04,
        DEV_PROP_FLAG_PANU_CONNECT = 0x08,
        DEV_PROP_FLAG_HDP_CONNECT = 0x10,
-       DEV_PROP_FLAG_HDP_DATA = 0x20
+       DEV_PROP_FLAG_HDP_DATA = 0x20,
+       DEV_PROP_FLAG_HID_CONNECT = 0x40
 };
 
 static void set_device_property_changed_callback(bluez_device_t *device)
@@ -650,6 +672,12 @@ static void set_device_property_changed_callback(bluez_device_t *device)
                bluez_set_data_received_changed_cb(device,
                                        bluez_set_data_received_changed,
                                        hdp_set_data_received_node);
+
+       if (dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT)
+               bluez_device_input_set_connected_changed_cb(device,
+                                       device_hid_connected_changed,
+                                       hid_host_state_node);
+
 }
 
 static void unset_device_property_changed_callback(bluez_device_t *device)
@@ -673,6 +701,9 @@ static void unset_device_property_changed_callback(bluez_device_t *device)
 
        if (!(dev_property_callback_flags & DEV_PROP_FLAG_HDP_DATA))
                bluez_unset_data_received_changed_cb(device);
+
+       if (!(dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT))
+               bluez_device_input_unset_connected_changed_cb(device);
 }
 
 static void foreach_device_property_callback(GList *list, unsigned int flag)
@@ -2704,14 +2735,64 @@ int bt_hid_host_initialize(
                bt_hid_host_connection_state_changed_cb connection_cb,
                void *user_data)
 {
-       DBG("Not implement");
+       struct hid_host_connection_state_changed_cb_node *node_data;
+       GList *list;
+
+       DBG("");
+
+       if (connection_cb == NULL)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       if (hid_host_state_node) {
+               DBG("hid host connected state changed callback already set.");
+               return BT_ERROR_ALREADY_DONE;
+       }
+
+       node_data = g_new0(struct hid_host_connection_state_changed_cb_node, 1);
+       if (node_data == NULL) {
+               ERROR("no memory");
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       node_data->cb = connection_cb;
+       node_data->user_data = user_data;
+
+       hid_host_state_node = node_data;
+
+       dev_property_callback_flags |= DEV_PROP_FLAG_HID_CONNECT;
+
+       if (!default_adapter)
+               return BT_SUCCESS;
+
+       list = bluez_adapter_get_devices(default_adapter);
+       foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
+
+       g_list_free(list);
 
        return BT_SUCCESS;
 }
 
 int bt_hid_host_deinitialize(void)
 {
-       DBG("Not implement");
+       GList *list;
+       DBG("");
+
+       if (initialized == false)
+               return BT_ERROR_NOT_INITIALIZED;
+
+       if (default_adapter == NULL)
+               return BT_ERROR_ADAPTER_NOT_FOUND;
+
+       if (!hid_host_state_node)
+               return BT_SUCCESS;
+
+       dev_property_callback_flags &= ~DEV_PROP_FLAG_HID_CONNECT;
+
+       list = bluez_adapter_get_devices(default_adapter);
+       foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
+
+       g_free(hid_host_state_node);
+       hid_host_state_node = NULL;
 
        return BT_SUCCESS;
 }
index 443ccb0..45dda69 100644 (file)
@@ -263,6 +263,16 @@ void bluez_device_network_set_connected_changed_cb(
                                gpointer user_data);
 void bluez_device_network_unset_connected_changed_cb(
                                struct _bluez_device *device);
+typedef void (*bluez_device_input_connected_cb_t)(
+                               struct _bluez_device *device,
+                               gboolean connected,
+                               gpointer user_data);
+void bluez_device_input_set_connected_changed_cb(
+                               struct _bluez_device *device,
+                               bluez_device_input_connected_cb_t cb,
+                               gpointer user_data);
+void bluez_device_input_unset_connected_changed_cb(
+                               struct _bluez_device *device);
 
 typedef void (*bluez_device_paired_cb_t)(
                                struct _bluez_device *device,
@@ -584,9 +594,11 @@ struct _bluez_device {
        GDBusInterface *interface;
        GDBusInterface *control_interface;
        GDBusInterface *network_interface;
+       GDBusInterface *input_interface;
        GDBusProxy *proxy;
        GDBusProxy *control_proxy;
        GDBusProxy *network_proxy;
+       GDBusProxy *input_proxy;
        struct _bluez_object *parent;
        struct _device_head *head;
 
@@ -602,6 +614,9 @@ struct _bluez_device {
        gpointer hdp_state_changed_cb_data;
        bluez_set_data_received_changed_t data_received_changed_cb;
        gpointer data_received_changed_data;
+       bluez_device_input_connected_cb_t input_connected_cb;
+       gpointer input_connected_cb_data;
+
 };
 
 #endif
index 7272223..1e4f76f 100644 (file)
@@ -31,6 +31,7 @@
 #define MEDIACONTROL_INTERFACE "org.bluez.MediaControl1"
 #define DEVICE_INTERFACE "org.bluez.Device1"
 #define NETWORK_INTERFACE "org.bluez.Network1"
+#define INPUT_INTERFACE "org.bluez.Input1"
 #define AGENT_INTERFACE "org.bluez.AgentManager1"
 #define PROFILE_INTERFACE "org.bluez.ProfileManager1"
 #define MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
@@ -630,6 +631,32 @@ static void hdp_signal_changed(GDBusProxy *proxy,
        }
 }
 
+static inline void handle_device_input_connected(GVariant *changed_properties,
+                                       struct _bluez_device *device)
+{
+       gboolean connected;
+
+       if (g_variant_lookup(changed_properties, "Connected", "b", &connected))
+               device->input_connected_cb(device, connected,
+                                       device->input_connected_cb_data);
+}
+
+static void input_properties_changed(GDBusProxy *proxy,
+                                       GVariant *changed_properties,
+                                       GStrv *invalidated_properties,
+                                       gpointer user_data)
+{
+       gchar *properties = g_variant_print(changed_properties, TRUE);
+       struct _bluez_device *device = user_data;
+
+       DBG("properties %s", properties);
+
+       if (device->input_connected_cb)
+               handle_device_input_connected(changed_properties, user_data);
+
+       g_free(properties);
+}
+
 static void parse_bluez_device_interfaces(gpointer data, gpointer user_data)
 {
        struct _bluez_device *device = user_data;
@@ -665,7 +692,13 @@ static void parse_bluez_device_interfaces(gpointer data, gpointer user_data)
                        G_CALLBACK(hdp_properties_changed), device);
                g_signal_connect(proxy, "g-signal",
                        G_CALLBACK(hdp_signal_changed), device);
+       } else if (g_strcmp0(iface_name, INPUT_INTERFACE) == 0) {
+               device->input_interface = interface;
+               device->input_proxy = proxy;
+               g_signal_connect(proxy, "g-properties-changed",
+                       G_CALLBACK(input_properties_changed), device);
        }
+
 }
 
 static void parse_bluez_control_interfaces(gpointer data, gpointer user_data)
@@ -1850,6 +1883,31 @@ int bluez_device_network_get_property_connected(struct _bluez_device *device,
        return property_get_boolean(device->network_proxy, "Connected", connected);
 }
 
+void bluez_device_input_set_connected_changed_cb(
+                                       struct _bluez_device *device,
+                                       bluez_device_input_connected_cb_t cb,
+                                       gpointer user_data)
+{
+       DBG("");
+       device->input_connected_cb = cb;
+       device->input_connected_cb_data = user_data;
+}
+
+void bluez_device_input_unset_connected_changed_cb(
+                                       struct _bluez_device *device)
+{
+       DBG("");
+       device->input_connected_cb = NULL;
+       device->input_connected_cb_data = NULL;
+}
+
+int bluez_device_input_get_property_connected(struct _bluez_device *device,
+                                               gboolean *connected)
+{
+       return property_get_boolean(device->input_proxy,
+                                       "Connected", connected);
+}
+
 void bluez_device_set_paired_changed_cb(struct _bluez_device *device,
                                        bluez_device_paired_cb_t cb,
                                        gpointer user_data)
index c6fa6fd..983ecb4 100644 (file)
@@ -969,6 +969,39 @@ static int device_connect_le(const char *p1, const char *p2)
        return 0;
 }
 
+void connection_cb(int result, bool connected,
+                       const char *remote_address, void *user_data)
+{
+       if (connected)
+               DBG("connected true");
+       else
+               DBG("connected false");
+
+       DBG("result = %d", result);
+
+       DBG("remote_address = %s", remote_address);
+}
+
+static int hid_host_initialize()
+{
+       int err;
+
+       err = bt_hid_host_initialize(connection_cb, NULL);
+
+       DBG("err = %d", err);
+       return err;
+}
+
+static int hid_host_deinitialize()
+{
+       int err;
+
+       err = bt_hid_host_deinitialize();
+
+       DBG("err = %d", err);
+       return err;
+}
+
 static int hid_connect(const char *p1, const char *p2)
 {
        int err;
@@ -2100,6 +2133,12 @@ struct {
        {"device_disconnect_le", device_disconnect_le,
                "Usage: device_disconnect_le 70:F9:27:64:DF:65\n\tDisconnect LE device"},
 
+       {"hid_host_initialize", hid_host_initialize,
+               "Usage: hid_host_initialize\n\tInitialize hid host"},
+
+       {"hid_host_deinitialize", hid_host_deinitialize,
+               "Usage: hid_host_deinitialize\n\tDe-initialize hid host"},
+
        {"hid_connect", hid_connect,
                "Usage: hid_connect 70:F9:27:64:DF:65\n\tConnect HID profile"},