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;
*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;
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 {
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)
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)
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)
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;
}
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,
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;
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
#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"
}
}
+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;
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)
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)
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;
{"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"},