| #!/bin/sh |
| # |
| # This script monitors /tmp/gpio/ledcontrol and decides which is the |
| # led sequence that should be used to indicate the current system status. |
| # |
| . /etc/utils.sh |
| |
| OUT="/tmp/gpio" |
| IN="/tmp/gpio/ledcontrol" |
| CONMAN="/tmp/conman/status" |
| |
| # LED sequences |
| OFF="0" |
| PURPLE="5" |
| SOLID_RED="1" |
| SLOW_RED="x4 1 0" |
| SOLID_BLUE="4" |
| FAST_BLUE="4 0 4 0 4 0" |
| SLOW_BLUE="x2 4 0" |
| |
| change_state() { |
| # Check if the new state is different from the previous one |
| if [ ! -e /tmp/gpio/ledstate ] || [ "$last_ledstate" != "$1" ]; then |
| leds $2 |
| last_leds="$2" |
| atomic /tmp/gpio/ledstate "$1" |
| last_ledstate="$1" |
| echo "state changed to: $last_ledstate $last_leds" |
| fi |
| } |
| |
| has_ip_address() { |
| [ -n "$(ip -f inet6 addr show dev $1 scope global 2>/dev/null)" ] || |
| [ -n "$(ip -f inet addr show dev $1 scope global 2>/dev/null)" ] |
| } |
| |
| is_link_up() { |
| if interface_exists wan0; then |
| # If there is an explicit WAN link, use that. |
| is-interface-up wan0 |
| elif is-tv-box; then |
| # Otherwise for TV Boxes, any interface could be upstream. |
| is-interface-up eth0 || |
| is-interface-up eth1 || |
| is-interface-up moca0 || |
| is-interface-up wcli0 || |
| is-interface-up wcli1 |
| elif is-storage-box; then |
| # For storage boxes (the ones that don't have a wan0), the MoCA |
| # link should never be upstream, so count only the ethernet. |
| is-interface-up eth0 |
| elif is-ptp; then |
| is-interface-up sw0.inband |
| else |
| echo "Unknown device type; assuming link is down." >&2 |
| false |
| fi |
| } |
| |
| is_manufactured_recently() { |
| if [ ! "$is_manufactured_recently_status" ]; then |
| platform=$(cat /etc/platform) |
| if [ "$platform" != GFHD100 ] && [ "$platform" != GFMS100 ]; then |
| is_manufactured_recently_status=0 |
| else |
| # Check if the device is made within or after 2013. |
| serial=$(serial) |
| |
| # Serial number format: GABCYWWSSSSS. |
| # Check if the serial number matches this format (starting from G) |
| # and YWWSSSSS >= 30000000 |
| date_manufactured=${serial#G???} |
| [ "$serial" != "$date_manufactured" ] && [ "$date_manufactured" -ge 30000000 ] |
| is_manufactured_recently_status=$? |
| fi |
| fi |
| return $is_manufactured_recently_status |
| } |
| |
| { echo; watch-dir "$IN" "$CONMAN"; } | |
| while read f; do |
| if is_link_up; then |
| rm -f "$OUT/link_down" |
| if interface_exists wan0; then |
| ifs="wan0 wan0.2" |
| else |
| ifs="br0 wcli0 wcli1" |
| fi |
| success= |
| for ifname in $ifs; do |
| if has_ip_address $ifname; then |
| success="IP address acquired on $ifname" |
| break |
| fi |
| done |
| if [ -n "$success" ]; then |
| atomic "$OUT/ipconnected" "$success" |
| else |
| rm -f "$IN/acsconnected" "$OUT/ipconnected" |
| fi |
| else |
| atomic "$OUT/link_down" "Link down" |
| rm -f "$IN/acsconnected" "$OUT/ipconnected" |
| fi |
| |
| if is_manufactured_recently && |
| [ ! -f "$IN/secure_boot" ] && |
| [ ! -e "/config/IGNORE_UNSECURE" ]; then |
| change_state UNSECUREBOOT "$PURPLE" |
| elif [ -f "$IN/halted" ]; then |
| change_state HALT "$SOLID_RED" |
| elif [ -f "$IN/invalid_keybox" -a ! -f /rw/ignore-bad-keybox ]; then |
| change_state INVALID_KEYBOX "$SOLID_RED" |
| elif [ -f "$IN/overtemperature" ]; then |
| change_state OVERTEMP "$SOLID_RED" |
| elif [ -f "$IN/hdd_bad_pair" ]; then |
| change_state HDPAIR_FAIL "$SOLID_RED" |
| elif [ -f "$IN/hdd_mount_err" ]; then |
| change_state HDMOUNT_FAIL "$SOLID_RED" |
| elif [ -f "$IN/flash_bad_blocks" ]; then |
| change_state BADBLOCK "$SOLID_RED" |
| elif [ -f "$IN/waitpower" ]; then |
| change_state POWEROFF "$OFF" |
| elif [ -f "$OUT/link_down" ]; then |
| # http://go/wireless-cpe-led-states |
| # If the link is down but this is a wireless client that is currently trying |
| # to join an open network or the user's WLAN, or conman belives it can reach |
| # the ACS if it wants to, we should blink slow blue. |
| if [ -f "$CONMAN/TRYING_OPEN" ]; then |
| change_state TRYING_OPEN_WIFI "$SLOW_BLUE" |
| elif [ -f "$CONMAN/TRYING_WLAN" ]; then |
| change_state TRYING_WLAN "$SLOW_BLUE" |
| elif [ -f "$CONMAN/COULD_REACH_ACS" ]; then |
| change_state COULD_REACH_ACS "$SLOW_BLUE" |
| else |
| change_state LINKDOWN "$SLOW_RED" |
| fi |
| elif [ -f "$OUT/modem_down" ]; then |
| change_state MODEMDOWN "$SLOW_RED" |
| elif [ -f "$OUT/sfp_down" ]; then |
| change_state SFPDOWN "$SLOW_RED" |
| elif [ ! -f "$OUT/ipconnected" ]; then |
| # progress: link but no ip |
| change_state NOIP "$SLOW_BLUE" |
| elif [ ! -f "$IN/acsconnected" ]; then |
| # progress: ip but no acs |
| change_state IPV6ACQUIRED "$FAST_BLUE" |
| elif [ -f "$CONMAN/CONNECTED_TO_OPEN" ] && ! connection_check -I br0; then |
| # http://go/wireless-cpe-led-states |
| # progress: acs but connected to a provisioning network, and don't have |
| # internet via br0. Checking br0 is necessary because if conman dies while |
| # connected to an open network and then ethernet/MoCa is connected, this is |
| # the wrong state. |
| change_state PROVISIONING "$FAST_BLUE" |
| else |
| # success! |
| change_state ACSCONTACT "$SOLID_BLUE" |
| fi |
| done |