base-files: add a hardware detection layer
authorJohn Crispin <john@openwrt.org>
Mon, 18 Aug 2014 13:09:17 +0000 (13:09 +0000)
committerJohn Crispin <john@openwrt.org>
Mon, 18 Aug 2014 13:09:17 +0000 (13:09 +0000)
this allows targets to use the new uci-default helper which will generate
a file called /etc/board.json. a tool called /bin/config_generate can then
be used to generate the default uci settings.

Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 42185

package/base-files/files/bin/board_detect [new file with mode: 0755]
package/base-files/files/bin/config_generate [new file with mode: 0755]
package/base-files/files/etc/init.d/boot
package/base-files/files/lib/functions/uci-defaults-new.sh [new file with mode: 0755]

diff --git a/package/base-files/files/bin/board_detect b/package/base-files/files/bin/board_detect
new file mode 100755 (executable)
index 0000000..ddd17a1
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+[ -d "/etc/board.d/" -a ! -f "/etc/board.json" ] || {
+       for a in `ls /etc/board.d/*`; do
+               [ -x $a ] || continue;
+               $(. $a)
+       done
+}
+
+[ -f "/etc/board.json" ] || return 1
+[ -f "/etc/config/network" ] || {
+       touch /etc/config/network
+       /bin/config_generate
+}
diff --git a/package/base-files/files/bin/config_generate b/package/base-files/files/bin/config_generate
new file mode 100755 (executable)
index 0000000..c435e7b
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/sh
+
+CFG=/etc/board.json
+
+. /usr/share/libubox/jshn.sh
+
+[ -f $CFG ] || exit 1
+
+generate_static_network() {
+       uci -q batch <<EOF
+delete network.loopback
+set network.loopback='interface'
+set network.loopback.ifname='lo'
+set network.loopback.proto='static'
+set network.loopback.ipaddr='127.0.0.1'
+set network.loopback.netmask='255.0.0.0'
+delete network.globals
+set network.globals='globals'
+set network.globals.ula_prefix='fdb1:a57f:2544::/48'
+EOF
+}
+
+next_vlan=3
+generate_network() {
+       local vlan
+
+       json_select network
+       json_select $1
+       json_get_vars ifname create_vlan macaddr
+       json_select ..
+       json_select ..
+
+       [ -n "$ifname" ] || return
+       [ "$create_vlan" -eq 1 ] && case $1 in
+       lan) vlan=1;;
+       wan) vlan=2;;
+       *)
+               vlan=$next_vlan
+               next_vlan=$((next_vlan + 1))
+               ;;
+       esac
+       [ -n "$vlan" ] && ifname=${ifname}.${vlan}
+       uci -q batch <<EOF
+delete network.$1
+set network.$1='interface'
+set network.$1.ifname='$ifname'
+set network.$1.force_link=1
+set network.$1.proto='none'
+set network.$1.macaddr='$macaddr'
+EOF
+
+       case $1 in
+       lan) uci -q batch <<EOF
+set network.$1.type='bridge'
+set network.$1.proto='static'
+set network.$1.ipaddr='192.168.1.1'
+set network.$1.netmask='255.255.255.0'
+set network.$1.ip6assign='60'
+EOF
+               ;;
+       wan) uci -q batch <<EOF
+set network.$1.proto='dhcp'
+delete network.wan6
+set network.wan6='interface'
+set network.wan6.ifname='@wan6'
+set network.wan6.proto='dhcpv6'
+EOF
+               ;;
+       esac
+}
+
+generate_switch_vlan() {
+       local device=$1
+       local vlan=$2
+       local cpu_port=$3
+
+       case $vlan in
+       lan)    vlan=1;;
+       wan)    vlan=2;;
+       *)      vlan=${vlan##vlan};;
+       esac
+
+       json_select vlans
+       json_select $2
+       json_get_values ports
+       json_select ..
+       json_select ..
+
+       uci -q batch <<EOF
+add network switch_vlan
+set network.@switch_vlan[-1].device='$device'
+set network.@switch_vlan[-1].vlan='$vlan'
+set network.@switch_vlan[-1].ports='$ports ${cpu_port}t'
+EOF
+}
+
+generate_switch() {
+       local key=$1
+       local vlans
+
+       json_select switch
+       json_select $key
+       json_get_vars enable reset blinkrate cpu_port
+
+       [ -n "$cpu_port" ] || return
+
+       uci -q batch <<EOF
+add network switch
+set network.@switch[-1].name='$key'
+set network.@switch[-1].reset='$reset'
+set network.@switch[-1].enable_vlan='$enable'
+set network.@switch[-1].blinkrate='$blinkrate'
+EOF
+
+       json_get_keys vlans vlans
+       for vlan in $vlans; do generate_switch_vlan $1 $vlan $cpu_port; done
+       json_select ..
+       json_select ..
+}
+
+generate_led() {
+       local key=$1
+       local cfg="led_$key"
+
+       json_select led
+       json_select $key
+       json_get_vars name sysfs type trigger device interface default
+       json_select ..
+       json_select ..
+
+       uci -q batch <<EOF
+delete system.$cfg
+set system.$cfg='led'
+set system.$cfg.name='$name'
+set system.$cfg.sysfs='$sysfs'
+set system.$cfg.dev='$device'
+set system.$cfg.trigger='$trigger'
+set system.$cfg.port_mask='$port_mask'
+set system.$cfg.default='$default'
+EOF
+       case $type in
+       netdev)
+               uci -q batch <<EOF
+set system.$cfg.trigger='netdev'
+set system.$cfg.mode='link tx rx'
+EOF
+       ;;
+
+       usb)
+               uci -q batch <<EOF
+set system.$cfg.trigger='usbdev'
+set system.$cfg.interval='50'
+EOF
+       ;;
+
+       esac
+}
+
+json_init
+json_load "$(cat ${CFG})"
+
+generate_static_network
+
+json_get_keys keys network
+for key in $keys; do generate_network $key; done
+
+json_get_keys keys switch
+for key in $keys; do generate_switch $key; done
+
+json_get_keys keys led
+for key in $keys; do generate_led $key; done
+
+uci commit
index b1272f401c6c33004c308a489d75b5231a5ad04e..f10db1344f69dc9e08dd28dc68df6e85f054e187 100755 (executable)
@@ -46,6 +46,7 @@ boot() {
        }
        rm -f /tmp/wireless.tmp
 
+       /bin/board_detect
        uci_apply_defaults
        
        # temporary hack until configd exists
diff --git a/package/base-files/files/lib/functions/uci-defaults-new.sh b/package/base-files/files/lib/functions/uci-defaults-new.sh
new file mode 100755 (executable)
index 0000000..528835b
--- /dev/null
@@ -0,0 +1,302 @@
+#!/bin/ash
+
+CFG=/etc/board.json
+
+. /usr/share/libubox/jshn.sh
+
+json_select_array() {
+       local _json_no_warning=1
+
+       json_select "$1"
+       [ $? = 0 ] && return
+
+       json_add_array $1
+       json_close_array
+
+        json_select "$1"
+}
+
+json_select_object() {
+       local _json_no_warning=1
+
+       json_select "$1"
+       [ $? = 0 ] && return
+
+       json_add_object $1
+       json_close_object
+
+        json_select "$1"
+}
+
+_ucidef_set_interface() {
+       local name=$1
+       local iface=$2
+
+       json_select_object $name
+       json_add_string ifname "${iface%%.*}"
+       [ "$iface" == "${iface%%.*}" ] || json_add_boolean create_vlan 1 
+       json_select ..
+}
+
+ucidef_set_interface_loopback()
+{
+       # stub
+       local a=$1
+}
+
+ucidef_set_interface_lan() {
+       local lan_if=$1
+
+       json_select_object network
+       _ucidef_set_interface lan $lan_if
+       json_select ..
+}
+
+ucidef_set_interfaces_lan_wan() {
+       local lan_if=$1
+       local wan_if=$2
+
+       json_select_object network
+       _ucidef_set_interface lan $lan_if
+       _ucidef_set_interface wan $wan_if
+       json_select ..
+}
+
+ucidef_add_switch() {
+       local name=$1
+       local reset=$2
+       local enable=$3
+
+       json_select_object switch
+
+        json_select_object $name
+       [ "$enable" -eq 1 ] && json_add_boolean enable 1
+       [ "$reset" -eq 1 ] && json_add_boolean reset 1
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_add_switch_attr() {
+       local name=$1
+       local key=$2
+       local val=$3
+
+       json_select_object switch
+
+        json_select_object $name
+       json_add_string $key $val
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_add_switch_vlan() {
+       local name=$1
+       local vlan=$2
+       local ports=$3
+       local cpu_port=''
+
+       case $vlan in
+       1)      vlan=lan;;
+       2)      vlan=wan;;
+       *)      vlan=vlan$vlan;;
+       esac
+
+       json_select_object switch
+       json_select_object $name
+       json_select_object vlans
+
+       json_add_array $vlan
+       for p in $ports; do
+               if [ ${p%t} != $p ]; then
+                       cpu_port=$p
+               else
+                       json_add_int "" $p
+               fi
+       done
+       json_close_array
+
+       json_select ..
+       [ -n "$cpu_port" ] && json_add_int cpu_port $cpu_port
+       json_select ..
+       json_select ..
+}
+
+ucidef_set_interface_macaddr() {
+       local network=$1
+       local macaddr=$2
+
+       json_select_object network
+
+       json_select $network
+       [ $? -eq 0 ] || {
+               json_select ..
+               return
+       }
+
+       json_add_string macaddr $macaddr
+       json_select ..
+       
+       json_select ..
+}
+
+ucidef_set_led_netdev() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local dev=$4
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name
+       json_add_string type netdev
+       json_add_string sysfs $sysfs
+       json_add_string device $dev
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_interface() {
+       local name=$1
+       local sysfs=$2
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name
+       json_add_string type interface
+       json_add_string sysfs $sysfs
+       json_add_string interface $name
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_usbdev() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local dev=$4
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name      
+       json_add_string type usb
+       json_add_string sysfs $sysfs
+       json_add_string device $dev
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_wlan() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local trigger=$4
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name
+       json_add_string type trigger
+       json_add_string sysfs $sysfs
+       json_add_string trigger $trigger
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_switch() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local trigger=$4
+       local port_mask=$5
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name
+       json_add_string type switch
+       json_add_string sysfs $sysfs
+       json_add_string trigger $trigger
+       json_add_string port_mask $port_mask
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_default() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local default=$4
+
+       json_select_object led
+       
+       json_select_object $1
+       json_add_string name $name
+       json_add_string sysfs $sysfs
+       json_add_string default $default
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_led_rssi() {
+       local cfg="led_$1"
+       local name=$2
+       local sysfs=$3
+       local iface=$4
+       local minq=$5
+       local maxq=$6
+       local offset=$7
+       local factor=$8
+
+       json_select_object led
+       
+       json_select_object rssi
+       json_select_object $1
+       json_add_string name $name
+       json_add_string sysfs $sysfs
+       json_add_string minq $minq
+       json_add_string maxq $maxq
+       json_add_string offset $offset
+       json_add_string factor $factor
+       json_select ..
+       json_select ..
+
+       json_select ..
+}
+
+ucidef_set_rssimon() {
+       local dev="$1"
+       local refresh="$2"
+       local threshold="$3"
+
+       json_select_object led
+       
+       json_select_object rssi
+       json_add_string type rssi
+       json_add_string dev $dev
+       json_add_string threshold $threshold
+       json_select ..
+
+       json_select ..
+       
+}
+
+board_config_update() {
+       json_init
+       [ -f ${CFG} ] && json_load "$(cat ${CFG})"
+}
+
+board_config_flush() {
+       json_dump -i > /tmp/.board.json
+       mv /tmp/.board.json ${CFG}
+}