Blob Blame History Raw
From cca11542bcd4d1748c850806c1599ed1b76ea19a Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Sun, 17 Jun 2012 01:26:18 +0200
Subject: [PATCH 2/3] fakehid: Disconnect from PS3 remote after 10 mins

After 10 minutes, disconnect the PS3 BD Remote to avoid draining its
battery. This is consistent with its behaviour on the PS3.

Original patch by Ruslan N. Marchenko <rufferson@gmail.com>
---
 input/device.h  |    1 +
 input/fakehid.c |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/input/device.h b/input/device.h
index ff52967..d8baa2c 100644
--- a/input/device.h
+++ b/input/device.h
@@ -33,6 +33,7 @@ struct fake_input {
 	int		uinput;		/* uinput socket */
 	int		rfcomm;		/* RFCOMM socket */
 	uint8_t		ch;		/* RFCOMM channel number */
+	guint           timeout_id;	/* Disconnect timeout ID */
 	gboolean	(*connect) (struct input_conn *iconn, GError **err);
 	int		(*disconnect) (struct input_conn *iconn);
 	void		*priv;
diff --git a/input/fakehid.c b/input/fakehid.c
index 3181538..a125356 100644
--- a/input/fakehid.c
+++ b/input/fakehid.c
@@ -44,6 +44,9 @@
 #include "fakehid.h"
 #include "uinput.h"
 
+/* Timeout to get the PS3 remote disconnected, in seconds */
+#define PS3_REMOTE_TIMEOUT 10 * 60
+
 enum ps3remote_special_keys {
 	PS3R_BIT_PS = 0,
 	PS3R_BIT_ENTER = 3,
@@ -141,6 +144,20 @@ static unsigned int ps3remote_keymap[] = {
 	[0xff] = KEY_MAX,
 };
 
+static gboolean ps3_remote_timeout_cb(gpointer user_data);
+
+static void ps3remote_set_timeout(struct fake_input *fake, gboolean enable)
+{
+	if (enable) {
+		fake->timeout_id = g_timeout_add_seconds(PS3_REMOTE_TIMEOUT, ps3_remote_timeout_cb, fake);
+	} else {
+		if (fake->timeout_id > 0) {
+			g_source_remove(fake->timeout_id);
+			fake->timeout_id = 0;
+		}
+	}
+}
+
 static int ps3remote_decode(char *buff, int size, unsigned int *value)
 {
 	static unsigned int lastkey = 0;
@@ -203,6 +220,16 @@ error:
 	return -1;
 }
 
+static gboolean
+ps3_remote_timeout_cb(gpointer user_data)
+{
+	struct fake_input *fake = (struct fake_input *) user_data;
+	input_device_request_disconnect(fake);
+	DBG("Disconnected PS3 BD Remote after timeout");
+	fake->timeout_id = 0;
+	return FALSE;
+}
+
 static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond,
 				gpointer data)
 {
@@ -221,6 +248,9 @@ static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 	}
 
+	/* Remove the old timeout */
+	ps3remote_set_timeout(fake, FALSE);
+
 	fd = g_io_channel_unix_get_fd(chan);
 
 	memset(buff, 0, sizeof(buff));
@@ -256,6 +286,8 @@ static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 	}
 
+	ps3remote_set_timeout(fake, TRUE);
+
 	return TRUE;
 
 failed:
@@ -318,6 +350,8 @@ static int ps3remote_setup_uinput(struct fake_input *fake,
 		goto err;
 	}
 
+	ps3remote_set_timeout(fake, TRUE);
+
 	return 0;
 
 err:
@@ -378,6 +412,8 @@ struct fake_input *fake_hid_connadd(struct fake_input *fake,
 	for (l = fake_hid->devices; l != NULL; l = l->next) {
 		old = l->data;
 		if (old->idev == fake->idev) {
+			if (fake->timeout_id > 0)
+				g_source_remove(fake->timeout_id);
 			g_free(fake);
 			fake = old;
 			fake_hid->connect(fake, NULL);
-- 
1.7.10