When it wakes from sleep mode, the "known" wireless networks isn't always up to date, and sometimes doesn't update for up to 10 to 20 seconds, which means NetworkManager only reconnects to the wireless network when it does do such a scan.
I have, however, noticed that forcing a scan by running "iwlist scan" as root causes NetworkManager to immediately pick up the network and initiate the connection.
So I conjured up a script to help with this.
ACPI allows one to plug into some of it's events, one of which is the "lid" event. Though, once my laptop went into sleep mode, opening the lid doesn't automatically wake it up. I have to explicitly press the power button for this. The result is that the lid OPEN event is never triggered, as the machine is in standby when it physically happens.
I had a look at the ACPI docs, and there doesn't seem to be an event for "wake". Using acpi_listen, I did notice some events being triggered with the wake up. These are the ac_adapter, battery and 2 processor events (one for each core). They didn't carry any information which could reliably indicate a wake event, so I was forced to do my own.
So whenever I close my lid, I have an event that creates a file under /tmp. When the processor event is handled, it would check for this file, which if it exists indicates a fairly descent probability of "wake up".
If I were to close the lid and open it up before sleep mode has entered, ACPI does trigger an open event, which is the reason for the check on line 15 of "sleeplid.sh".
So to set this up I edited /etc/acpi/events/lidbtn, and added a 2nd action to trigger my event script. This results in the file reading:
event=button[ /]lid action=/etc/acpi/lid.sh action=/etc/acpi/sleeplid.sh lid
I also created a new event configuration, called /etc/acpi/events/processor, which reads:
event=processor action=/etc/acpi/sleeplid.sh processor
And finally, just to make the actual event handler /etc/acpi/sleeplist.sh:
#!/bin/bash LOG=/tmp/.sleeplig.log SLEEPING=/tmp/.sleeplid.sleeping DEV=wlan0 exec 2>&1 >> "$LOG" echo "Event triggered: "`date` DOSCAN=0 if [ "$1" = "lid" ] then if grep -q closed /proc/acpi/button/lid/*/state then echo "LID closed" touch "$SLEEPING" else echo "LID opened" fi elif [ "$1" = "processor" ] then echo "Processor event" if [ -f "$SLEEPING" ] then rm -f "$SLEEPING" DOSCAN=1 fi else echo "WARN: Unknown event '$1'" fi if [ $DOSCAN -eq 1 ] then echo "Initiating scan." iwlist $DEV scan fi
So this basically triggers the script to run with an argument "lid" whenever the lid event occurs, and argument "processor" when the processor event occurs.
If you intend on using this you might need to update the DEV variable to whatever your wireless device is named. Since ACPI events are very device specific, you might also need to customize other aspects. Though the general idea would probably not change much.
And people wonder why I only use Linux...
No comments:
Post a Comment