Wednesday, March 9, 2011

XBMC, /proc/acpi/wakeup, and instant resume

I got one of these guys http://www.ipazzport.com/show_10A.html to control my Fedora XBMC HTPC without wires and without having a large keyboard on the coffee table.

There was one nagging issue though. To be completely lazy I needed a remote power switch. Specifically I needed a way to wakeup the box from suspend.

/proc/acpi/wakeup to the rescue! I quickly found that USB2 was the bus (terminology?) that my wireless keyboards dongle was attached to. Great! But do to the way /proc/acpi/wakeup and the wireless dongle work I was left with a problem... as soon as the computer suspended it resumed. No amount of acpi conflict resolution seemed to work for me (as discussed here http://wiki.xbmc.org/?title=Enable_Wake-On-Device).

Whats a hacker to do? Hack of course :-D

I patched the XBMC code a few times to provide a delay when the suspend function was called (I figured the remote needed to be fully powered off). No good. So I patched XBMC again to not use its built in suspend functionality, but instead call out to an external shell script. No more compiling/test/compiling/etc. Yay!

--- xbmc-10.0-Dharma/xbmc/utils/Builtins.cpp 2010-12-17 01:17:41.000000000 -0500
+++ xbmc-10.0-Dharma-delay/xbmc/utils/Builtins.cpp 2011-03-06 14:05:57.747094861 -0500
@@ -84,6 +84,10 @@
#endif

#include
+#include
+#include
+#include
+#include

using namespace std;
using namespace XFILE;
@@ -254,7 +258,16 @@
}
else if (execute.Equals("suspend"))
{
- g_application.getApplicationMessenger().Suspend();
+ pid_t child_pid = fork();
+ if (child_pid == 0) {
+ char *args[] = {"/usr/bin/xbmc-delay", (char *) 0};
+ execvp (args[0], args);
+ return(0);
+ } else {
+ wait(NULL);
+ }
+ kill(child_pid, SIGKILL);
+ //g_application.getApplicationMessenger().Suspend();
}
else if (execute.Equals("quit"))
{


Now I could edit the shell script and test rather quickly (no need to rebuild and install). I found that with one suspend the dongle was still active enough to wake the box. Even large delays (so I could turn the remote off before the box was going down) did not help.

What works? Two back to back suspends. Why? I think it has to do with the way that usb subsystems come back online after a suspend. The dongle needs to stop mucking around on the usb bus to stop waking the machine up. While suspended the dongle certainly quits doing stuff. Thus when the second suspend occurs the dongle has settled down, and it does not wake the box up until I power the remote on.

The bash script is stupid simple
#!/bin/bash
sleep 1
sudo pm-suspend
sudo pm-suspend

Fun stuff...

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home