The buttons need to connected across +3.3V and gpio22,23,24,25,27
while the leds need to be connected between +3.3V and gpio4,7,8,17,18 like this 3.3V o---|>|---o GPIO so that the gpio sinks the current (and is inverted so that when value is 1 output is 0v).
To use it first execute it with "start" parameter, then execute it with "monitor &"
status,report and find were mainly used for debugging. but may still be handy.
When you press a button the corresponding led goes on as soon as the script catches the button press and remains on until the action has been taken.
If there's nothing in the port led stays on for 2 seconds to prevent bounce .... if there's something that is not a network I don't know what would happen for sure but I assume that it should do the same as if nothing is plugged in the port.
If you do not actually unplug the nic in the usb port you can press it again to reenable the device (restart AP for example) once the led goes back off.
Have fun.
Code:
#!/bin/bash
NAME=$(basename $0)
#This array maps the kernel gpio port, their direction, the pi's gpio pin and
#the inverter status
#GPIO04 is iset to output, is connected to pin 7 and is inverted
#hence "4:OUT:7:1"
GPIO_PINS=(4:out:7:1 7:out:26:1 8:out:24:1 17:out:11:1 18:out:12:1 22:in:15:0 23:in:16:0 24:in:18:0 25:in:22:0 27:in:13:0)
#Actions array for when input pin is detected high (same order as the input pins set in GPIO_PINS
#so button connected to gpio22 does shutdown and so on
ACTIONS=("do_shutdown" "usb_toggle 1 2" "usb_toggle 1 3" "usb_toggle 1 4" "usb_toggle 1 5")
do_start ()
{ for ((i=0;i<${#GPIO_PINS[*]};i++))
do
eval $(echo "GPIO_PIN_DATA=$(echo "(${GPIO_PINS[$i]})" |tr ":" " ")")
echo ${GPIO_PIN_DATA[0]} > /sys/class/gpio/export
echo ${GPIO_PIN_DATA[1]} > /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/direction
sleep 0.2
[ ${GPIO_PIN_DATA[3]} -ne 0 ] && echo ${GPIO_PIN_DATA[3]} > /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/active_low
[ "${GPIO_PIN_DATA[1]}" = "out" ] && echo 0 > /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/value
done
}
do_stop ()
{ MYPID=$$
PIDS=$(ps -eo pid,cmd |grep -wvE "grep|$MYPID" |grep -w "rc.gpio monitor" |awk '{print $1}')
[ "$PIDS" != "" ] && kill -9 $PIDS
for ((i=0;i<${#GPIO_PINS[*]};i++))
do
eval $(echo "GPIO_PIN_DATA=$(echo "(${GPIO_PINS[$i]})" |tr ":" " ")")
echo ${GPIO_PIN_DATA[0]} > /sys/class/gpio/unexport
done
}
show_status ()
{ for ((i=0;i<${#GPIO_PINS[*]};i++))
do
eval $(echo "GPIO_PIN_DATA=$(echo "(${GPIO_PINS[$i]})" |tr ":" " ")")
echo -n "/sys/class/gpio/gpio${GPIO_PIN_DATA[0]}: "
echo -n "direction: $(cat /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/direction) "
echo -n "pin#: ${GPIO_PIN_DATA[2]} "
echo -n "invert: $(cat /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/active_low) "
echo "value: $(cat /sys/class/gpio/gpio${GPIO_PIN_DATA[0]}/value)"
done
}
show_report ()
{ echo "Reporting all the gpio pinns status ... "
for PIN in $(find /sys/class/gpio -type l -maxdepth 1 -name "gpio[0-9]*")
do
echo "${PIN}: direction: $(cat $PIN/direction) value: $(cat $PIN/value)"
done
}
#takes as input bus number and port and outputs the NIC's name
find_nic ()
{ #/sys/bus/usb/devices/usb<bus number>/<bus number>-<root port>/<bus number>-<root port>.<port>
#/sys/bus/usb/devices/<bus number>-<root port>.<port>
SYSBP=/sys/bus/usb/devices
SYSNICDIR=$(find -H $SYSBP/${1}-1.${2}:* -type d -name net 2>/dev/null)
[ "$SYSNICDIR" != "" ] && NIC=$(ls --indicator-style=none $SYSNICDIR) || return
echo $NIC
}
usb_toggle ()
{ STIME=$(date +s)
GPIOPIN=$(echo ${GPIO_PINS[$(($2 - 1))]} |awk -F: '{print $1}')
echo 1 > /sys/class/gpio/gpio$GPIOPIN/value
NIC=$(find_nic $1 $2)
[ "$NIC" = "" -o ! -f /etc/rc.d/network/$NIC ] && return
if [ $(ifconfig $NIC |head -1 |grep -wc UP) -ge 1 ]
then
echo "stopping $NIC"
/etc/rc.d/network/$NIC stop >/dev/null 2>&1
else
echo "starting $NIC"
/etc/rc.d/network/$NIC start >/dev/null 2>&1
fi
sleep $(( 5 - $(date +%s) + $STIME )) >/dev/null 2>&1
echo 0 > /sys/class/gpio/gpio$GPIOPIN/value
}
do_shutdown ()
{ GPIOPIN=$(echo ${GPIO_PINS[0]} |awk -F: '{print $1}')
echo 1 > /sys/class/gpio/gpio$GPIOPIN/value
shutdown -h now
}
monitor ()
{ MYPID=$$
if ps -eo pid,cmd |grep -v grep |grep -wv "$MYPID" |grep -wq "rc.gpio monitor"
then
echo "$NAME monitor is already running "
exit 1
fi
j=0
for ((i=0;i<${#GPIO_PINS[*]};i++))
do
eval $(echo "GPIO_PIN_DATA=$(echo "(${GPIO_PINS[$i]})" |tr ":" " ")")
[ "${GPIO_PIN_DATA[1]}" != "in" ] && continue
MONITOR_PINS[$j]=${GPIO_PIN_DATA[0]}
((j++))
done
i=0
while ((i<=${#MONITOR_PINS[*]}))
do
grep -q 1 /sys/class/gpio/gpio${MONITOR_PINS[$i]}/value 2>/dev/null && ${ACTIONS[$i]}
i=$((++i % ${#MONITOR_PINS[*]}))
[ $i -eq 0 ] && sleep 0.2
done
}
case $1 in
start) do_start;;
stop) do_stop;;
status) show_status;;
report) show_report;;
monitor) monitor ;;
find) find_nic $2 $3;;
*) echo "$NAME <start|stop|report|status|monitor>" ; exit 1;;
esac
http://i246.photobucket.com/albums/g...pshwu4p9x9.jpg