#!/bin/sh

# led 12.0.1 (Raspberry Pi)
# Copyright (c)2017-2026 John Lawson & Sons
# All Rights Reserved

# Color  State     Meaning
# -----  -----     -------
#
# Green  ON        Ethernet
#        FLASHING  WiFi
# Red    OFF       NORMAL
#        FLASHING  NO NETWORK
#        ON        NO MONITOR/TV (WAITING)

PWR_BRIGHTNESS="/sys/class/leds/PWR/brightness"
PWR_TRIGGER="/sys/class/leds/PWR/trigger"
ACT_BRIGHTNESS="/sys/class/leds/ACT/brightness"
ACT_TRIGGER="/sys/class/leds/ACT/trigger"
DISPLAY_STANDBY_MARKER="/run/signage-display-standby"

contains() {
    case "$1" in
        *"$2"*) return 0 ;;
        *)       return 1 ;;
    esac
}

write_if_exists() {
    file="$1"
    value="$2"

    [ -e "$file" ] || return 0

    printf '%s\n' "$value" >"$file" 2>/dev/null || true
}

read_file() {
    file="$1"

    [ -r "$file" ] || return 1

    value="$(cat "$file" 2>/dev/null)" || return 1
    printf '%s\n' "$value"
}

interface_is_up() {
    interface_path="$1"

    if [ -r "$interface_path/carrier" ]; then
        carrier="$(read_file "$interface_path/carrier" 2>/dev/null || true)"
        [ "$carrier" = "1" ]
        return
    fi

    operstate="$(read_file "$interface_path/operstate" 2>/dev/null || true)"
    [ "$operstate" = "up" ]
}

get_network_state() {
    wifi_up=0

    for interface_path in /sys/class/net/*; do
        [ -e "$interface_path" ] || continue

        interface_name="${interface_path##*/}"

        case "$interface_name" in
            lo)
                continue
                ;;

            eth*|en*)
                if interface_is_up "$interface_path"; then
                    printf '%s\n' "ethernet"
                    return 0
                fi
                ;;

            wlan*|wl*)
                if interface_is_up "$interface_path"; then
                    wifi_up=1
                fi
                ;;
        esac
    done

    if [ "$wifi_up" -eq 1 ]; then
        printf '%s\n' "wifi"
    else
        printf '%s\n' "offline"
    fi
}

monitor_connected() {
    found_connector=0

    for status_file in /sys/class/drm/card*-*/status; do
        [ -r "$status_file" ] || continue
        found_connector=1
        [ "$(read_file "$status_file" 2>/dev/null || true)" = "connected" ] && return 0
    done

    # Do not report a missing monitor when this kernel exposes no DRM status.
    [ "$found_connector" -eq 0 ] && return 0
    return 1
}

set_ethernet_led() {
    write_if_exists "$ACT_TRIGGER" "$act_on"
    write_if_exists "$ACT_BRIGHTNESS" "$act_light"
}

set_red_flashing() {
    write_if_exists "$ACT_TRIGGER" "none"
    write_if_exists "$ACT_BRIGHTNESS" "$act_dark"

    write_if_exists "$PWR_TRIGGER" "timer"
    write_if_exists "$PWR_BRIGHTNESS" "1"
}

set_red_on() {
    # Keep ACT under manual control while display status owns the LEDs.
    # In particular, Pi 5's inverted default-on trigger can emit a brief
    # green pulse even when its dark brightness value is subsequently set.
    write_if_exists "$ACT_TRIGGER" "none"
    write_if_exists "$ACT_BRIGHTNESS" "$act_dark"

    write_if_exists "$PWR_TRIGGER" "default-on"
    write_if_exists "$PWR_BRIGHTNESS" "1"
}

set_red_off() {
    write_if_exists "$PWR_TRIGGER" "none"
    write_if_exists "$PWR_BRIGHTNESS" "0"
}

set_wifi_led_on() {
    write_if_exists "$ACT_TRIGGER" "none"
    write_if_exists "$ACT_BRIGHTNESS" "$act_light"
}

set_wifi_led_off() {
    write_if_exists "$ACT_TRIGGER" "none"
    write_if_exists "$ACT_BRIGHTNESS" "$act_dark"
}

restore_led_control() {
    write_if_exists "$ACT_TRIGGER" "mmc0"
    write_if_exists "$PWR_TRIGGER" "default-on"
}

trap 'restore_led_control; exit 0' INT TERM HUP

# Default Raspberry Pi LED behaviour.
act_on="default-on"
act_light=1
act_dark=0

cpuinfo="$(cat /proc/cpuinfo 2>/dev/null || true)"

# Raspberry Pi 3 Model B has inverted ACT LED behaviour.
if contains "$cpuinfo" "Raspberry Pi 3 Model B" &&
   ! contains "$cpuinfo" "Raspberry Pi 3 Model B Plus"; then
    act_on="none"
fi

# Raspberry Pi 5 has inverted ACT LED trigger and brightness behaviour.
if contains "$cpuinfo" "Raspberry Pi 5 Model B"; then
    act_on="none"
    act_light=0
    act_dark=1
fi

# Disable kernel and firmware LED control before managing the LEDs.
write_if_exists "$PWR_TRIGGER" "none"
write_if_exists "$ACT_TRIGGER" "none"

last_state=""
last_red_state=""
wifi_flash=0

while :; do
    state="$(get_network_state 2>/dev/null || printf '%s\n' "offline")"
    if [ ! -e "$DISPLAY_STANDBY_MARKER" ] && monitor_connected; then
        monitor_up=1
    else
        monitor_up=0
    fi

    if [ "$monitor_up" -eq 0 ]; then
        red_state="on"
    elif [ "$state" = "offline" ]; then
        red_state="flashing"
    else
        red_state="off"
    fi

    if [ "$red_state" != "$last_red_state" ]; then
        case "$red_state" in
            on) set_red_on ;;
            flashing) set_red_flashing ;;
            off) set_red_off ;;
        esac
        last_red_state="$red_state"
    fi

    if [ "$monitor_up" -eq 0 ]; then
        last_state="display-wait"
        wifi_flash=0
        sleep 1
        continue
    fi

    case "$state" in
        wifi)
            if [ "$last_state" != "wifi" ]; then
                wifi_flash=0
                last_state="wifi"
            fi

            if [ "$wifi_flash" -eq 0 ]; then
                set_wifi_led_on
                wifi_flash=1
            else
                set_wifi_led_off
                wifi_flash=0
            fi

            sleep 1
            ;;

        ethernet)
            if [ "$last_state" != "ethernet" ]; then
                set_ethernet_led
                last_state="ethernet"
            fi

            wifi_flash=0
            sleep 1
            ;;

        *)
            last_state="offline"
            wifi_flash=0
            sleep 1
            ;;
    esac
done
