diff --git a/profiles/input/device.c b/profiles/input/device.c
index 1b28cdc..b622ee8 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
unsigned int report_req_timer;
uint32_t report_rsp_id;
bool virtual_cable_unplug;
+ unsigned int idle_timer;
};
static int idle_timeout = 0;
g_free(idev->req);
}
+ if (idev->idle_timer)
+ timeout_remove(idev->idle_timer);
+
if (idev->reconnect_timer > 0)
timeout_remove(idev->reconnect_timer);
idev->virtual_cable_unplug = false;
}
-static bool hidp_send_message(GIOChannel *chan, uint8_t hdr,
- const uint8_t *data, size_t size)
+static int uhid_disconnect(struct input_device *idev, bool force)
+{
+ int err;
+
+ if (!bt_uhid_created(idev->uhid))
+ return 0;
+
+ /* Only destroy the node if virtual cable unplug flag has been set */
+ if (!idev->virtual_cable_unplug && !force)
+ return 0;
+
+ bt_uhid_unregister_all(idev->uhid);
+
+ err = bt_uhid_destroy(idev->uhid);
+ if (err < 0) {
+ error("bt_uhid_destroy: %s", strerror(-err));
+ return err;
+ }
+
+ return err;
+}
+
+static bool input_device_idle_timeout(gpointer user_data)
+{
+ struct input_device *idev = user_data;
+
+ idev->idle_timer = 0;
+
+ DBG("path=%s", idev->path);
+
+ uhid_disconnect(idev, true);
+ connection_disconnect(idev, 0);
+
+ return false;
+}
+
+static void input_device_idle_reset(struct input_device *idev)
+{
+ timeout_remove(idev->idle_timer);
+
+ if (idle_timeout)
+ idev->idle_timer = timeout_add_seconds(idle_timeout,
+ input_device_idle_timeout, idev,
+ NULL);
+}
+
+static bool hidp_send_message(struct input_device *idev, GIOChannel *chan,
+ uint8_t hdr, const uint8_t *data, size_t size)
{
int fd;
ssize_t len;
return false;
}
+ input_device_idle_reset(idev);
+
return true;
}
if (hdr == (HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG))
idev->virtual_cable_unplug = true;
- return hidp_send_message(idev->ctrl_io, hdr, data, size);
+ return hidp_send_message(idev, idev->ctrl_io, hdr, data, size);
}
static bool hidp_send_intr_message(struct input_device *idev, uint8_t hdr,
const uint8_t *data, size_t size)
{
- return hidp_send_message(idev->intr_io, hdr, data, size);
+ return hidp_send_message(idev, idev->intr_io, hdr, data, size);
}
static bool uhid_send_get_report_reply(struct input_device *idev,
return true;
}
+ input_device_idle_reset(idev);
+
hdr = data[0];
if (hdr != (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
DBG("unsupported HIDP protocol header 0x%02x", hdr);
return true;
}
-static int uhid_disconnect(struct input_device *idev, bool force)
-{
- int err;
-
- if (!bt_uhid_created(idev->uhid))
- return 0;
-
- /* Only destroy the node if virtual cable unplug flag has been set */
- if (!idev->virtual_cable_unplug && !force)
- return 0;
-
- bt_uhid_unregister_all(idev->uhid);
-
- err = bt_uhid_destroy(idev->uhid);
- if (err < 0) {
- error("bt_uhid_destroy: %s", strerror(-err));
- return err;
- }
-
- return err;
-}
-
static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
struct input_device *idev = data;
return true;
}
+ input_device_idle_reset(idev);
+
hdr = data[0];
type = hdr & HIDP_HEADER_TRANS_MASK;
param = hdr & HIDP_HEADER_PARAM_MASK;
diff --git a/profiles/input/input.conf b/profiles/input/input.conf
index 00a34eb..fc20c58 100644
--- a/profiles/input/input.conf
+++ b/profiles/input/input.conf
# Set idle timeout (in minutes) before the connection will
# be disconnect (defaults to 0 for no timeout)
-#IdleTimeout=30
+#IdleTimeout=0
# Enable HID protocol handling in userspace input profile
# Defaults to true (Use UHID instead of kernel HIDP)