diff --git a/6.1/target/linux/ipq40xx/base-files/bin/board_detect b/6.1/target/linux/ipq40xx/base-files/bin/board_detect new file mode 100755 index 00000000..840bd017 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/bin/board_detect @@ -0,0 +1,14 @@ +#!/bin/sh + +CFG=$1 + +[ -n "$CFG" ] || CFG=/etc/board.json + +[ -d "/etc/board.d/" -a ! -s "$CFG" ] && { + for a in $(ls /etc/board.d/*); do + [ -x $a ] || continue; + $(. $a) + done +} + +[ -s "$CFG" ] || return 1 diff --git a/6.1/target/linux/ipq40xx/base-files/bin/board_modem b/6.1/target/linux/ipq40xx/base-files/bin/board_modem new file mode 100755 index 00000000..7628fc86 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/bin/board_modem @@ -0,0 +1,307 @@ +#!/bin/sh +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# Copyright (c) 2011-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +CFG=/etc/board.json + +# do not run on preinit/early init +[ "$EARLY_INIT" ] && return + +strstr() { + [ "${1#*$2*}" = "$1" ] && return 1 + return 0 +} + +print_array() { + json_add_array $1 + case "$1" in + 4G) + for element in $2 + do + json_add_string "" "$(echo $element)" + done + ;; + 3G) + for element in $2 + do + json_add_string "" "wcdma_$(echo $element)" + done + ;; + 2G) + for element in $2 + do + json_add_string "" "$(echo $element)" + done + ;; + esac + json_close_array +} + +gather_band_capabilities() { + # Same logic as unhandler.c + ###################### EG06 ######################### + if strstr $revision_from_unhandler "EG06E"; then #EG06E + lte_bands="1 3 5 7 8 20 28 32 38 40 41" #B + trysg_bands="850 900 1800 2100" #MHz + dug_bands="" + elif strstr $revision_from_unhandler "EG06A"; then #EG06A + lte_bands="2 4 5 7 12 13 25 26 29 30 66" + trysg_bands="850 1700 1900" + dug_bands="" + ###################### EC25 ######################### + elif strstr $revision_from_unhandler "EC25EF"; then #EC25E + lte_bands="1 3 5 7 8 20 38 40 41" + trysg_bands="850 900 2100" + dug_bands="900 1800" #MHz + elif strstr $revision_from_unhandler "EC25EC"; then #EC25EC + lte_bands="1 3 7 8 20 28" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC25AUX"; then #EC25AUX + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="850 900 1700 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "EC25AFA"; then #EC25A + lte_bands="2 4 12" + trysg_bands="850 1700 1900" + dug_bands="" + elif strstr $revision_from_unhandler "EC25V"; then #EC25V + lte_bands="4 13" + trysg_bands="" + dug_bands="" + elif strstr $revision_from_unhandler "EC25AFX"; then #EC25AFX + lte_bands="2 4 5 12 13 14 66 71" + trysg_bands="850 1700 1900" + dug_bands="" + elif strstr $revision_from_unhandler "EC25AFF"; then #EC25AF + lte_bands="2 4 5 12 13 14 66 71" + trysg_bands="850 1700 1900" + dug_bands="" + elif strstr $revision_from_unhandler "EC25AUTF"; then #EC25AUT + lte_bands="1 3 5 7 28" + trysg_bands="850 2100" + dug_bands="" + elif strstr $revision_from_unhandler "EC25AUTL"; then #EC25AUTL + lte_bands="3 7 28" + trysg_bands="" + dug_bands="" + elif strstr $revision_from_unhandler "EC25AUF"; then #EC25AU + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="850 900 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "EC25J"; then #EC25J + lte_bands="1 3 8 18 19 26 41" + trysg_bands="800 900 2100" + dug_bands="" + elif strstr $revision_from_unhandler "EC25EUX"; then #EC25EUX + lte_bands="1 3 7 8 20 28 38 40 41" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC25EUF"; then #EC25EU + lte_bands="1 3 7 8 20 28 38 40 41" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC25EUG"; then #EC25EU + lte_bands="1 3 7 8 20 28 38 40 41" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC25MX"; then #EC25MX + lte_bands="2 4 5 7 28 66" + trysg_bands="850 1700 1900" + dug_bands="" + ###################### EC21 ######################### + elif strstr $revision_from_unhandler "EC21EUX"; then #EC21EUX + lte_bands="1 3 7 8 20 28" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC21EU"; then #EC21EU + lte_bands="1 3 7 8 20 28" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC21EC"; then #EC21EC + lte_bands="1 3 7 8 20 28" + trysg_bands="900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC21E"; then #EC21E + lte_bands="1 3 5 7 8 20" + trysg_bands="850 900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "EC21V"; then #EC21V + lte_bands="4 13" + trysg_bands="" + dug_bands="" + elif strstr $revision_from_unhandler "EC21KL"; then #EC21KL + lte_bands="1 3 5 7 8" + trysg_bands="" + dug_bands="" + elif strstr $revision_from_unhandler "EC21J"; then #EC21J + lte_bands="1 3 8 18 19 26" + trysg_bands="" + dug_bands="" + elif strstr $revision_from_unhandler "EC21AUX"; then #EC21AUX + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="850 900 1700 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "EC21AUT"; then #EC21AUT + lte_bands="1 3 5 7 28" + trysg_bands="850 2100" + dug_bands="" + elif strstr $revision_from_unhandler "EC21AU"; then #EC21AU + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="850 900 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "EC21A"; then #EC21A + lte_bands="2 4 12" + trysg_bands="850 1700 1900" + dug_bands="" + ###################### EG25 ######################### + elif strstr $revision_from_unhandler "EG25G"; then #EG25G + lte_bands="1 2 3 4 5 7 8 12 13 18 19 20 25 26 28 38 39 40 41" + trysg_bands="800 850 900 1700 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "EG12EA"; then #EG12EA + lte_bands="1 3 5 7 8 20 28 38 40 41" + trysg_bands="850 900 1800 2100" + dug_bands="" + elif strstr $revision_from_unhandler "EG12NA"; then #EG12NA + lte_bands="2 4 5 7 12 13 14 17 25 26 29 30 41 66 71" + trysg_bands="850 1700 1900" + dug_bands="" + elif strstr $revision_from_unhandler "BG96"; then #BG96M + lte_bands="1 2 3 4 5 8 12 13 18 19 20 26 28 39" + trysg_bands="" + dug_bands="850 900 1800 1900" + ##################### SLM750 ######################## + elif strstr $revision_from_unhandler "750VE"; then #SLM750VE + lte_bands="1 3 5 7 8 20 40" + trysg_bands="850 900 2100" + dug_bands="900 1800" + elif strstr $revision_from_unhandler "750VAU"; then #SLM750VAU + lte_bands="1 3 5 7 8 28 40" + trysg_bands="850 900 2100" + dug_bands="850 900 1800" + elif strstr $revision_from_unhandler "750VA"; then #SLM750VA + lte_bands="2 4 5 12 13 17 18 25 26 41" + trysg_bands="850 1700 1900" + dug_bands="850 1900" + elif strstr $revision_from_unhandler "750VJ"; then #SLM750VJ + lte_bands="1 3 8 18 19 26 41" + trysg_bands="800 900 2100" + dug_bands="" + elif strstr $revision_from_unhandler "750VSA"; then #SLM750VSA + lte_bands="2 4 5 7 8 28 40" + trysg_bands="850 900 1900" + dug_bands="850 900 1900" + ###################### UC20 ######################### + elif strstr $revision_from_unhandler "UC20E"; then #UC20E + lte_bands="" + trysg_bands="900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "UC20G"; then #UC20G + lte_bands="" + trysg_bands="800 850 900 1900 2100" + dug_bands="850 900 1800 1900" + elif strstr $revision_from_unhandler "UC20A"; then #UC20A + lte_bands="" + trysg_bands="850 1900" + dug_bands="" + else + lte_bands="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28" + trysg_bands="700 800 850 900 1500 1700 2600" + dug_bands="1700 1800 1900 2100" + fi +} + +validate_service_modes() { + json_get_keys service_modes service_modes + + found_modes="$(printf "$service_modes" | awk '!seen[$0]++'| wc -l)" + [ "$found_modes" -eq 0 ] && { + return 0 + } + + return 1 +} + +#~ Get model name for RUTX products +setup_modem() { + local key="$1" + local object_num="$2" + local id gps boudrate type desc control product vendor stop_bits + + json_select "$object_num" + json_get_vars id product + + if [ "$id" = "$id_from_unhandler" ]; then + + [ -z "$product" ] || \ + { + [ -f "/sys/bus/usb/devices/$id/idVendor" ] && [ -f "/sys/bus/usb/devices/$id/idProduct" ] || { + json_select .. + return 1 + } + + validate_service_modes && { + gather_band_capabilities + json_select_object service_modes + [ -z "$lte_bands" ] || print_array "4G" "$lte_bands" + [ -z "$trysg_bands" ] || print_array "3G" "$trysg_bands" + [ -z "$dug_bands" ] || print_array "2G" "$dug_bands" + json_select .. + } + json_select .. + return 1 + } + + vendor="$(cat "/sys/bus/usb/devices/$id/idVendor")" + product="$(cat "/sys/bus/usb/devices/$id/idProduct")" + + [ -f "/lib/network/wwan/$vendor:$product" ] && { + devicename="$id" + + gather_band_capabilities + + json_set_namespace defaults old_cb + json_load "$(cat /lib/network/wwan/$vendor:$product)" + json_get_vars gps boudrate type desc control stop_bits + json_set_namespace "$old_cb" + + [ "${devicename%%:*}" = "$devicename" ] && { + json_add_string vendor "$vendor" + json_add_string product "$product" + json_add_string gps "$gps" + json_add_string stop_bits "$stop_bits" + json_add_string boudrate "$boudrate" + json_add_string type "$type" + json_add_string desc "$desc" + json_add_string control "$control" + json_add_object service_modes + [ -z "$lte_bands" ] || print_array "4G" "$lte_bands" + [ -z "$trysg_bands" ] || print_array "3G" "$trysg_bands" + [ -z "$dug_bands" ] || print_array "2G" "$dug_bands" + json_close_object + } + } + fi + json_select .. +} + +[ -s "${CFG}" ] || exit 1 + +id_from_unhandler="$1" +revision_from_unhandler="$2" + +lock /var/run/board_modem.lock + +board_config_update +json_for_each_item setup_modem modems +board_config_flush + +lock -u /var/run/board_modem.lock + +exit 0 diff --git a/6.1/target/linux/ipq40xx/base-files/bin/board_track b/6.1/target/linux/ipq40xx/base-files/bin/board_track new file mode 100755 index 00000000..563b8768 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/bin/board_track @@ -0,0 +1,47 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh + +CFG=/etc/board.json +SLP=30 + +check_modem() { + json_select "$2" + json_get_vars id + + [ -z "$id" ] && { + json_select .. + return 0 + } + + #logger -t "board-track" "ls -d /sys/bus/usb/devices/$id/${id}*/tty?*" + ttys=$(ls -d /sys/bus/usb/devices/$id/${id}*/tty?*) + + [ -n "$ttys" ] || { #FAILED TO FIND MODEM + logger -t "board-track" "modem $id not detected" + for m in /sys/class/gpio/modem*_power; do + label="$(basename $m | awk -F_ '{print $1}')" + mctl -s -m ${label} + sleep 1 + mctl -p -m ${label} + done + sleep 5 + ip link set up dev wwan0 2>&1 >/dev/null + ip link set up dev wwan1 2>&1 >/dev/null + json_select .. + return 1 + } + + [ -n "$(ip link show dev wwan0 | grep DOWN)" ] && ip link set up dev wwan0 2>&1 >/dev/null + [ -n "$(ip link show dev wwan1 | grep DOWN)" ] && ip link set up dev wwan1 2>&1 >/dev/null + + #MODEM UP + json_select .. +} + +board_config_update +while true; do + json_for_each_item check_modem modems + sleep $SLP + [ $SLP -lt 300 ] && SLP=$((SLP+30)) +done diff --git a/6.1/target/linux/ipq40xx/base-files/bin/config_generate b/6.1/target/linux/ipq40xx/base-files/bin/config_generate new file mode 100755 index 00000000..b2542b14 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/bin/config_generate @@ -0,0 +1,665 @@ +#!/bin/sh + +CFG=/etc/board.json + +. /usr/share/libubox/jshn.sh + +[ -s $CFG ] || /bin/board_detect || exit 1 + +[ -s /etc/config/network ] && \ +[ -s /etc/config/system ] && \ +[ -s /etc/config/hwinfo ] && \ +[ -s /etc/config/blesem ] && \ +exit 0 + +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' + EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + delete network.globals + set network.globals='globals' + set network.globals.ula_prefix='auto' + EOF + } + + if json_is_a dsl object; then + json_select dsl + if json_is_a atmbridge object; then + json_select atmbridge + local vpi vci encaps payload nameprefix + json_get_vars vpi vci encaps payload nameprefix + uci -q batch <<-EOF + delete network.atm + set network.atm='atm-bridge' + set network.atm.vpi='$vpi' + set network.atm.vci='$vci' + set network.atm.encaps='$encaps' + set network.atm.payload='$payload' + set network.atm.nameprefix='$nameprefix' + EOF + json_select .. + fi + + if json_is_a modem object; then + json_select modem + local type annex firmware tone xfer_mode + json_get_vars type annex firmware tone xfer_mode + uci -q batch <<-EOF + delete network.dsl + set network.dsl='dsl' + set network.dsl.annex='$annex' + set network.dsl.firmware='$firmware' + set network.dsl.tone='$tone' + set network.dsl.xfer_mode='$xfer_mode' + EOF + json_select .. + fi + json_select .. + fi +} + +addr_offset=2 +generate_network() { + local keys var val ifname macaddr proto type ipaddr netmask + + uci -q batch <<-EOF + delete "network.$1" + set network.$1='interface' + EOF + + json_select network + json_select "$1" + json_get_keys keys + for var in $keys; do + json_get_var val "$var" + [ "${var#_*}" = "$var" ] && { + eval "$var=\"\$val\"" + uci -q set "network.$1.$var=$val" + } + done + json_select .. + json_select .. + + #~ [ -n "$ifname" ] || return + + # force bridge for multi-interface devices (and lan) + case "$1:$ifname" in + *\ * | lan:*) + type="bridge" + uci -q set "network.$1.type=$type" + ;; + esac + + if [ -n "$macaddr" ]; then + for name in $ifname; do + uci -q batch <<-EOF + delete network.$1_${name/./_}_dev + set network.$1_${name/./_}_dev='device' + set network.$1_${name/./_}_dev.name='$name' + set network.$1_${name/./_}_dev.macaddr='$macaddr' + EOF + done + fi + + case "$proto" in + static) + local ipad + case "$1" in + lan) + ipad=${ipaddr:-"192.168.100.1"} + ;; + *) ipad=${ipaddr:-"192.168.$((addr_offset++)).1"} ;; + esac + + netm=${netmask:-"255.255.255.0"} + + uci -q batch <<-EOF + set network.$1.proto='static' + set network.$1.ipaddr='$ipad' + set network.$1.netmask='$netm' + EOF + [ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60' + ;; + + dhcp) + # fixup IPv6 slave interface if parent is a bridge + [ "$type" = "bridge" ] && ifname="br-$1" + + uci set network.$1.proto='dhcp' + uci set network.$1.metric='1' + + #[ -e /proc/sys/net/ipv6 ] && { + # uci -q batch <<-EOF + # delete network.${1}6 + # set network.${1}6='interface' + # set network.${1}6.device='$ifname' + # set network.${1}6.proto='dhcpv6' + # set network.${1}6.metric='1' + # EOF + #} + ;; + + pppoe) + uci -q batch <<-EOF + set network.$1.proto='pppoe' + set network.$1.username='username' + set network.$1.password='password' + EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + set network.$1.ipv6='1' + delete network.${1}6 + set network.${1}6='interface' + set network.${1}6.ifname='@${1}' + set network.${1}6.proto='dhcpv6' + EOF + } + ;; + esac +} + +add_modem_section() { + local id="$1" + local num="$2" + local simcount="$3" + local builtin="$4" + + for count in $(seq "$simcount"); do + interface="mob${num}s${count}a1" + local proto="wwan" + + # just like this for now + # probably we should merge connm with wwan + [ -e /dev/smd9 ] && { + proto="connm" + } + + uci -q batch <<-EOF + delete network.$interface + set network.$interface='interface' + set network.$interface.proto='$proto' + set network.$interface.modem='$id' + set network.$interface.metric='$((num+1))' + set network.$interface.sim='${count}' + set network.$interface.pdp='1' + EOF + + # just like this for now + # probably we should merge connm with wwan + [ -e /dev/smd9 ] && { + uci set network.$interface.ifname='rmnet0' + } + + update_firewall_zone "wan" "$interface" + create_multiwan_iface "$interface" "$num" + add_simcard_config "$id" "${count}" "${count}" "$builtin" + add_sim_switch_config "$id" "${count}" + add_quota_limit_config "$interface" + done + add_sms_storage_config "$id" +} + +generate_dynamic_lte() { +[ -f /lib/functions/modem.sh ] || return +. /lib/functions/modem.sh + + local interface num id simcount builtin + + #creating simcard sections from board.json file + if json_is_a modems array; then + json_get_keys modems modems + json_select modems + + num=1 + + for modem in $modems; do + json_select "$modem" + json_get_vars id simcount builtin + json_select .. + add_modem_section "$id" "$num" "$simcount" "$builtin" + num=$(( num + 1 )) + done + + json_select .. + else + ## because of RUTX8 have no default modem + # after this script runs out simcard config + # must not be empty due to external modems could appear to config + echo " " >> /etc/config/simcard + fi + + #creating simcard sections from conneted via USB + for a in `ls /sys/bus/usb/devices`; do + local vendor product + [ -f "/sys/bus/usb/devices/$a/idVendor" ] && [ -f "/sys/bus/usb/devices/$a/idProduct" ] || continue + vendor=$(cat "/sys/bus/usb/devices/$a/idVendor") + product=$(cat "/sys/bus/usb/devices/$a/idProduct") + [ -f "/lib/network/wwan/${vendor}:${product}" ] && { + add_simcard_config "$a" "1" "0" "" + } + done +} + +generate_switch_vlans_ports() { + local switch="$1" + local port ports role roles num attr val + + # + # autogenerate vlans + # + + if json_is_a roles array; then + json_get_keys roles roles + json_select roles + + for role in $roles; do + json_select "$role" + json_get_vars ports + json_select .. + + uci -q batch <<-EOF + add network switch_vlan + set network.@switch_vlan[-1].device='$switch' + set network.@switch_vlan[-1].vlan='$role' + set network.@switch_vlan[-1].ports='$ports' + EOF + done + + json_select .. + fi + + + # + # write port specific settings + # + + if json_is_a ports array; then + json_get_keys ports ports + json_select ports + + for port in $ports; do + json_select "$port" + json_get_vars num + + if json_is_a attr object; then + json_get_keys attr attr + json_select attr + uci -q batch <<-EOF + add network switch_port + set network.@switch_port[-1].device='$switch' + set network.@switch_port[-1].port=$num + EOF + + for attr in $attr; do + json_get_var val "$attr" + uci -q set network.@switch_port[-1].$attr="$val" + done + json_select .. + fi + json_select .. + done + + json_select .. + fi +} + +generate_switch() { + local key="$1" + local vlans + + json_select switch + json_select "$key" + json_get_vars enable reset blinkrate cpu_port \ + ar8xxx_mib_type ar8xxx_mib_poll_interval + + 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' + set network.@switch[-1].ar8xxx_mib_type='$ar8xxx_mib_type' + set network.@switch[-1].ar8xxx_mib_poll_interval='$ar8xxx_mib_poll_interval' + EOF + + generate_switch_vlans_ports "$1" + + json_select .. + json_select .. +} + + +generate_static_system() { + param=$(/sbin/mnf_info "--name") + hostname=${param:0:6} + uci -q batch <<-EOF + delete system.@system[0] + set system.system='system' + set system.@system[-1].hostname='OpenMPTCProuter' + set system.@system[-1].timezone='UTC' + set system.@system[-1].ttylogin='0' + set system.@system[-1].log_size='128' + set system.@system[-1].urandom_seed='0' + + delete system.ntp + set system.ntp='timeserver' + set system.ntp.enabled='0' + set system.ntp.enable_server='0' + add_list system.ntp.server='0.pool.ntp.org' + add_list system.ntp.server='1.pool.ntp.org' + add_list system.ntp.server='2.pool.ntp.org' + add_list system.ntp.server='3.pool.ntp.org' + + delete system.debug + set system.debug='debug' + set system.debug.sms_utils_debug_level='4' + EOF + + if json_is_a system object; then + json_select system + local hostname + #if json_get_var hostname hostname; then + # uci -q set "system.@system[-1].hostname=$hostname" + #fi + + if json_is_a ntpserver array; then + local keys key + json_get_keys keys ntpserver + json_select ntpserver + uci -q delete "system.ntp.server" + + for key in $keys; do + local server + if json_get_var server "$key"; then + uci -q add_list "system.ntp.server=$server" + fi + done + json_select .. + fi + json_select .. + fi +} + +generate_rssimon() { + local key="$1" + local cfg="rssid_$key" + local refresh threshold + + json_select rssimon + json_select "$key" + json_get_vars refresh threshold + json_select .. + json_select .. + + uci -q batch <<-EOF + delete system.$cfg + set system.$cfg='rssid' + set system.$cfg.dev='$key' + set system.$cfg.refresh='$refresh' + set system.$cfg.threshold='$threshold' + EOF +} + +generate_led() { + local key="$1" + local cfg="led_$key" + + json_select led + json_select "$key" + json_get_vars name sysfs type trigger default + + uci -q batch <<-EOF + delete system.$cfg + set system.$cfg='led' + set system.$cfg.name='$name' + set system.$cfg.sysfs='$sysfs' + set system.$cfg.trigger='$trigger' + set system.$cfg.default='$default' + EOF + + case "$type" in + gpio) + local gpio inverted + json_get_vars gpio inverted + uci -q batch <<-EOF + set system.$cfg.trigger='gpio' + set system.$cfg.gpio='$gpio' + set system.$cfg.inverted='$inverted' + EOF + ;; + + netdev) + local device mode + json_get_vars device mode + uci -q batch <<-EOF + set system.$cfg.trigger='netdev' + set system.$cfg.mode='$mode' + set system.$cfg.dev='$device' + EOF + ;; + + usb) + local device + json_get_vars device + uci -q batch <<-EOF + set system.$cfg.trigger='usbdev' + set system.$cfg.interval='50' + set system.$cfg.dev='$device' + EOF + ;; + + usbport) + local ports port + json_get_values ports ports + uci set system.$cfg.trigger='usbport' + for port in $ports; do + uci add_list system.$cfg.port=$port + done + ;; + + rssi) + local iface minq maxq offset factor + json_get_vars iface minq maxq offset factor + uci -q batch <<-EOF + set system.$cfg.trigger='rssi' + set system.$cfg.iface='rssid_$iface' + set system.$cfg.minq='$minq' + set system.$cfg.maxq='$maxq' + set system.$cfg.offset='$offset' + set system.$cfg.factor='$factor' + EOF + ;; + + switch) + local port_mask speed_mask mode + json_get_vars port_mask speed_mask mode + uci -q batch <<-EOF + set system.$cfg.port_mask='$port_mask' + set system.$cfg.speed_mask='$speed_mask' + set system.$cfg.mode='$mode' + EOF + ;; + + portstate) + local port_state + json_get_vars port_state + uci -q batch <<-EOF + set system.$cfg.port_state='$port_state' + EOF + ;; + + timer|oneshot) + local delayon delayoff + json_get_vars delayon delayoff + uci -q batch <<-EOF + set system.$cfg.trigger='$type' + set system.$cfg.delayon='$delayon' + set system.$cfg.delayoff='$delayoff' + EOF + ;; + esac + + json_select .. + json_select .. +} + +generate_gpioswitch() { + local cfg="$1" + + json_select gpioswitch + json_select "$cfg" + local name pin default + json_get_vars name pin default + uci -q batch <<-EOF + delete system.$cfg + set system.$cfg='gpio_switch' + set system.$cfg.name='$name' + set system.$cfg.gpio_pin='$pin' + set system.$cfg.value='$default' + EOF + json_select .. + json_select .. +} + +generate_hwinfo() { + local parameter="$1" + local temp + + json_select hwinfo + json_get_var temp "$parameter" + json_select .. + + uci -q batch <<-EOF + set hwinfo.hwinfo='hwinfo' + set hwinfo.hwinfo.$parameter='$temp' + EOF +} + +generate_bluetooth() { + uci -q batch <<-EOF + set blesem.general='section' + set blesem.general.enabled='0' + set blesem.settings='app' + set blesem.settings.refresh_time='30000' + EOF +} + +add_firewall_zone() { + local ifname + + json_select network + json_select "$1" + json_get_vars ifname + json_select .. + json_select .. + + fw3 -q network "$1" || fw3 -q device "$ifname" && return + + uci -q batch <<-EOF + add firewall zone + set firewall.@zone[-1].name='$1' + set firewall.@zone[-1].network='$1' + set firewall.@zone[-1].input='REJECT' + set firewall.@zone[-1].output='ACCEPT' + set firewall.@zone[-1].forward='REJECT' + + add firewall forwarding + set firewall.@forwarding[-1].src='$1' + set firewall.@forwarding[-1].dest='wan' + + add firewall rule + set firewall.@rule[-1].name='Allow-DNS-$1' + set firewall.@rule[-1].src='$1' + set firewall.@rule[-1].dest_port='53' + set firewall.@rule[-1].proto='tcp udp' + set firewall.@rule[-1].target='ACCEPT' + + add firewall rule + set firewall.@rule[-1].name='Allow-DHCP-$1' + set firewall.@rule[-1].src='$1' + set firewall.@rule[-1].dest_port='67' + set firewall.@rule[-1].proto='udp' + set firewall.@rule[-1].family='ipv4' + set firewall.@rule[-1].target='ACCEPT' + EOF +} + +add_dhcp() { + + json_select network + json_select "$1" + json_get_vars _dhcp + json_select .. + json_select .. + + [ "$_dhcp" = "1" ] || return + uci -q batch <<-EOF + set dhcp.$1='dhcp' + set dhcp.$1.interface='$1' + set dhcp.$1.start='100' + set dhcp.$1.limit='150' + set dhcp.$1.leasetime='1h' + EOF +} + +json_init +json_load "$(cat ${CFG})" + +umask 077 + +if [ ! -s /etc/config/network ]; then + touch /etc/config/network + generate_static_network + + json_get_keys keys network + for key in $keys; do + generate_network $key + add_firewall_zone "$key" + add_dhcp "$key" + done + + json_get_keys keys switch + for key in $keys; do generate_switch $key; done + + generate_dynamic_lte +fi + +if [ ! -s /etc/config/system ]; then + touch /etc/config/system + generate_static_system + + json_get_keys keys rssimon + for key in $keys; do generate_rssimon $key; done + + json_get_keys keys gpioswitch + for key in $keys; do generate_gpioswitch $key; done + + json_get_keys keys led + for key in $keys; do generate_led $key; done +fi + +if [ ! -s /etc/config/hwinfo ]; then + touch /etc/config/hwinfo + json_get_keys keys hwinfo + for key in $keys; do generate_hwinfo $key; done +fi + +if [ ! -s /etc/config/blesem ]; then + bluetooth="" + json_select hwinfo + json_get_vars bluetooth + [ "$bluetooth" -eq 1 ] && { + touch /etc/config/blesem + touch /etc/config/ble_devices + generate_bluetooth + } +fi + +uci commit diff --git a/6.1/target/linux/ipq40xx/base-files/bin/ipcalc.sh b/6.1/target/linux/ipq40xx/base-files/bin/ipcalc.sh new file mode 100755 index 00000000..5d5eac3e --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/bin/ipcalc.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +awk -f - $* <limit) end=limit + + print "IP="int2ip(ipaddr) + print "NETMASK="int2ip(netmask) + print "BROADCAST="int2ip(broadcast) + print "NETWORK="int2ip(network) + print "PREFIX="32-bitcount(compl32(netmask)) + + # range calculations: + # ipcalc + + if (ARGC > 3) { + print "START="int2ip(start) + print "END="int2ip(end) + } +} +EOF diff --git a/6.1/target/linux/ipq40xx/base-files/etc/board.d/1-board_json b/6.1/target/linux/ipq40xx/base-files/etc/board.d/1-board_json new file mode 100755 index 00000000..c9c258b2 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/board.d/1-board_json @@ -0,0 +1,214 @@ +#!/bin/sh +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# Copyright (c) 2011-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/functions/teltonika-defaults.sh +. /lib/functions/system.sh + +setup_json() { + local model="$1" + + case "$model" in + RUTX08*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "0u@eth1" "5:wan" + ucidef_set_hwinfo usb ethernet ios + ;; + RUTX09*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "3-1" "2" "gps_out" + ucidef_set_hwinfo dual_sim usb gps mobile ethernet ios + ;; + RUTX10*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "0u@eth1" "5:wan" + ucidef_set_hwinfo bluetooth usb wifi dual_band_ssid ethernet ios + ;; + RUTX11*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "3-1" "2" "gps_out" + ucidef_set_hwinfo dual_sim usb gps mobile wifi dual_band_ssid bluetooth ethernet ios + ;; + RUTXR1*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "3-1" "2" + ucidef_set_hwinfo dual_sim usb mobile wifi dual_band_ssid ethernet sfp_port + ucidef_set_release_version "2.3.1" + ;; + RUTX12*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan" + # builtin and primary should be first modem + ucidef_add_static_modem_info "$model" "3-1" "1" "primary" "gps_out" + ucidef_add_static_modem_info "$model" "1-1.2" "1" + ucidef_set_hwinfo usb gps mobile wifi dual_band_ssid bluetooth ethernet ios + ucidef_set_release_version "2.3.1" + ;; + RUTX14*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "1-1" "2" "gps_out" + ucidef_set_hwinfo usb gps dual_sim mobile wifi dual_band_ssid bluetooth ethernet ios at_sim + ucidef_set_release_version "2.6.1" + ;; + RUTX18*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "2-1" "2" "gps_out" + ucidef_set_hwinfo usb gps dual_sim mobile wifi dual_band_ssid bluetooth ethernet ios + ;; + RUTX50*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "switch0" \ + "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "0u@eth1" "5:wan" + ucidef_add_static_modem_info "$model" "2-1" "2" "gps_out" + ucidef_set_hwinfo dual_sim usb gps mobile wifi dual_band_ssid ethernet ios at_sim + ;; + TRB2*) + ucidef_set_led_switch "lan" "LAN" "eth_led" "switch0" "0x04" + ucidef_set_interface_lan "eth0" + ucidef_add_static_modem_info "$model" "1-1.4" "2" "gps_out" + ucidef_add_serial_capabilities "rs232 rs485" \ + "300 600 1200 2400 4800 9600 14400 19200 38400 56000 57600 115200 \ + 230400 460800 921600 1000000 3000000" \ + "7 8" + ucidef_set_hwinfo dual_sim mobile gps ethernet ios + ;; + RUT200* |\ + RUT241*) + ucidef_set_led_switch "lan" "LAN" "eth1_led" "switch0" "0x2" + ucidef_set_led_switch "wan" "WAN" "eth2_led" "switch0" "0x1" + ucidef_add_switch "switch0" "1:lan" "0:wan" "6@eth0" + ucidef_set_interface_macaddr "lan" "$(mtd_get_mac_binary config 0x0)" + ucidef_set_interface_macaddr "wan" "$(macaddr_add "$(mtd_get_mac_binary config 0x0)" 1)" + ucidef_add_static_modem_info "$model" "1-1" "1" + [ "${model:7:1}" = "1" ] && ucidef_set_hwinfo mobile wifi \ + ethernet || ucidef_set_hwinfo mobile wifi ethernet ios + ;; + RUT2*) + ucidef_set_led_switch "lan" "LAN" "lan_led" "switch0" "0x04" + ucidef_set_led_netdev "wan" "WAN" "wan_led" "eth1" + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_static_modem_info "$model" "1-1" "1" + [ "${model:6:1}" = "1" ] && ucidef_set_hwinfo mobile wifi \ + ethernet || ucidef_set_hwinfo mobile wifi ethernet ios + ;; + RUT300*) + ucidef_set_led_switch "lan1" "LAN1" "eth1_led" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "eth2_led" "switch0" "0x10" + ucidef_set_led_switch "lan3" "LAN3" "eth3_led" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "eth4_led" "switch0" "0x04" + ucidef_set_led_netdev "wan" "WAN" "wan_led" "eth1" + ucidef_set_interface_wan "eth1" + ucidef_add_switch "switch0" \ + "0@eth0" "1:lan:1" "2:lan:4" "3:lan:3" "4:lan:2" + ucidef_set_hwinfo usb ethernet ios + ;; + RUT360*) + ucidef_set_led_switch "lan" "LAN" "eth1_led" "switch0" "0x10" + ucidef_set_led_netdev "wan" "WAN" "eth2_led" "eth1" + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_static_modem_info "$model" "1-1" "1" + ucidef_set_hwinfo mobile wifi dual_band_ssid ethernet ios + ;; + RUT950*) + ucidef_set_led_switch "lan1" "LAN1" "eth1_led" "switch0" "0x10" + ucidef_set_led_switch "lan2" "LAN2" "eth2_led" "switch0" "0x08" + ucidef_set_led_switch "lan3" "LAN3" "eth3_led" "switch0" "0x04" + ucidef_set_led_netdev "wan" "WAN" "wan_led" "eth1" + ucidef_set_interface_wan "eth1" + ucidef_add_switch "switch0" "0@eth0" "2:lan:3" "3:lan:2" "4:lan:1" + ucidef_add_static_modem_info "$model" "1-1" "2" + [ "${model:7:2}" = "06" ] && ucidef_set_hwinfo dual_sim mobile \ + wifi ethernet || ucidef_set_hwinfo dual_sim mobile wifi ethernet ios + ;; + RUT955*) + ucidef_set_led_switch "lan1" "LAN1" "eth1_led" "switch0" "0x10" + ucidef_set_led_switch "lan2" "LAN2" "eth2_led" "switch0" "0x08" + ucidef_set_led_switch "lan3" "LAN3" "eth3_led" "switch0" "0x04" + ucidef_set_led_netdev "wan" "WAN" "wan_led" "eth1" + ucidef_set_interface_wan "eth1" + ucidef_add_switch "switch0" "0@eth0" "2:lan:3" "3:lan:2" "4:lan:1" + ucidef_add_static_modem_info "$model" "1-1.4" "2" "gps_out" + [ "${model:7:2}" = "06" ] && ucidef_set_hwinfo dual_sim usb gps \ + mobile wifi ethernet || ucidef_set_hwinfo dual_sim usb gps \ + mobile wifi ethernet ios + ucidef_add_serial_capabilities "rs232" \ + "200 300 600 1200 1800 2400 4800 9600 19200 38400 57600 115200 \ + 230400 460800 500000 576000" \ + "5 6 7 8" + ucidef_add_serial_capabilities "rs485" \ + "300 600 1200 1800 2400 4800 9600 19200 38400 57600 115200 230400 \ + 460800 500000 576000 921600 1000000 1152000 1500000 2000000 \ + 2500000 3000000" \ + "8" + ;; + TRB140*) + ucidef_set_interface_lan "eth0 rndis0" + ucidef_add_trb14x_lte_modem "$model" + ucidef_add_nand_info "$model" + [ "${model:7:1}" = "2" ] && ucidef_set_hwinfo mobile ethernet || \ + ucidef_set_hwinfo mobile ethernet ios + ;; + TRB141*) + ucidef_set_interface_lan "rndis0" + ucidef_add_trb14x_lte_modem "$model" + ucidef_add_nand_info "$model" + ucidef_set_hwinfo mobile ios + ;; + TRB142* |\ + TRB145*) + ucidef_set_interface_lan "rndis0" + ucidef_add_trb14x_lte_modem "$model" + ucidef_add_nand_info "$model" + [ "${model:7:1}" = "2" ] && ucidef_set_hwinfo mobile || \ + ucidef_set_hwinfo mobile ios + [ "${model:5:1}" = "2" ] && local rs="rs232" + ucidef_add_serial_capabilities "${rs:-rs485}" \ + "300 600 1200 2400 4800 9600 19200 38400 57600 115200 460800" \ + "5 6 7 8" + [ "${model:5:2}" = "23" -o "${model:5:2}" = "52" ] && \ + ucidef_set_release_version "7.1" + ;; + TCR100*) + ucidef_set_led_switch "lan" "LAN" "eth1_led" "switch0" "0x10" + ucidef_set_led_netdev "wan" "WAN" "eth2_led" "eth1" + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_set_interface guest proto static type bridge \ + guest 1 _wireless true _dhcp true + ucidef_add_static_modem_info "$model" "1-1" "1" + ucidef_set_hwinfo mobile wifi dual_band_ssid wps ethernet + ;; + *) + echo "Unsupported hardware. Network interfaces not intialized" + ;; + esac +} + +#~ Get model name for RUTX products +model="$(mnf_info --name)" 2>/dev/null + +platform="$(cat /proc/device-tree/platform)" 2>/dev/null + +board_config_update +setup_json "$model" + +ucidef_set_board_platform "$platform" + +board_config_flush + +exit 0 diff --git a/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata new file mode 100644 index 00000000..88319423 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -0,0 +1,71 @@ +#!/bin/sh + +ath10kcal_die() { + echo "ath10cal: " "$*" + exit 1 +} + +ath10kcal_extract() { + local part=$1 + local offset=$2 + local count=$3 + local mtd + + mtd=$(find_mtd_chardev $part) + [ -n "$mtd" ] || \ + ath10kcal_die "no mtd device found for partition $part" + + dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \ + ath10kcal_die "failed to extract calibration data from $mtd" +} + +ensure_correct_art() { + # NOTE(rytis): Hardcoded hashes for 64 KiB file, filled with zeroes (md5b0) and ones (md5b1). + local md5b0="fcd6bcb56c1689fcef28b57c22475bad" + local md5b1="ecb99e6ffea7be1e5419350f725da86b" + local artdir="/dev/mtd12" + local bindir="/usr/share/art/art_rutx.bin" + local md5art="$(md5sum $artdir)" + md5art="${md5art%% *}" + local devicename="$(mnf_info -n)" + devicename="${devicename:0:6}" + + if [ "$devicename" != "RUTX08" ] && [ "$devicename" != "RUTX09" ]; then + if [ "$md5art" == "$md5b0" ] || [ "$md5art" == "$md5b1" ] && [ -e "$bindir" ]; then + mtd write $bindir $artdir + fi + else + if [ "$md5art" != "$md5b0" ] && [ "$md5art" != "$md5b1" ]; then + mtd erase $artdir + fi + fi +} + +[ -e /lib/firmware/$FIRMWARE ] && exit 0 + +. /lib/functions.sh +. /lib/functions/system.sh + +board=$(board_name) + +ensure_correct_art + +case "$FIRMWARE" in +"ath10k/pre-cal-ahb-a000000.wifi.bin") + case "$board" in + teltonika,rutx) + ath10kcal_extract "0:ART" 4096 12064 + ;; + esac + ;; +"ath10k/pre-cal-ahb-a800000.wifi.bin") + case "$board" in + teltonika,rutx) + ath10kcal_extract "0:ART" 20480 12064 + ;; + esac + ;; +*) + exit 1 + ;; +esac diff --git a/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/ieee80211/09_fix_wifi_mac b/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/ieee80211/09_fix_wifi_mac new file mode 100644 index 00000000..4c4893f4 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/hotplug.d/ieee80211/09_fix_wifi_mac @@ -0,0 +1,23 @@ +#!/bin/ash + +[ "$ACTION" == "add" ] || exit 0 + +PHYNBR=${DEVPATH##*/phy} + +[ -n $PHYNBR ] || exit 0 + +. /lib/functions.sh +. /lib/functions/system.sh + +board=$(board_name) + +case "$board" in + teltonika,rutx) + mac_addr=$(mtd_get_mac_binary 0:CONFIG 0) + if [ "$mac_addr" != "ff:ff:ff:ff:ff:ff" ]; then + echo $(macaddr_add $mac_addr $(($PHYNBR + 2)) ) > /sys${DEVPATH}/macaddress + fi + ;; + *) + ;; +esac diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/boot b/6.1/target/linux/ipq40xx/base-files/etc/init.d/boot new file mode 100755 index 00000000..85549882 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/boot @@ -0,0 +1,70 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=10 +STOP=90 + +uci_apply_defaults() { + . /lib/functions/system.sh + + cd /etc/uci-defaults || return 0 + files="$(find . -type f | sort)" + [ -z "$files" ] && return 0 + mkdir -p /tmp/.uci + for file in $files; do + ( . "./$file" ) && rm -f "$file" + done + uci commit +} + +boot() { + [ -f /proc/mounts ] || /sbin/mount_root + [ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc + + mkdir -p /var/run + mkdir -p /var/log + mkdir -p /var/lock + mkdir -p /var/state + mkdir -p /var/tmp + mkdir -p /tmp/.uci + chmod 0700 /tmp/.uci + touch /var/log/wtmp + touch /var/log/lastlog + mkdir -p /tmp/resolv.conf.d + touch /tmp/resolv.conf.d/resolv.conf.auto + ln -sf /tmp/resolv.conf.d/resolv.conf.auto /tmp/resolv.conf + grep -q debugfs /proc/filesystems && /bin/mount -o noatime -t debugfs debugfs /sys/kernel/debug + grep -q bpf /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime,mode=0700 -t bpf bpffs /sys/fs/bpf + grep -q pstore /proc/filesystems && /bin/mount -o noatime -t pstore pstore /sys/fs/pstore + + # mount all entries in fstab + /bin/mount -a & + + # /log directory might be created on preinit + # symlink /storage to /log on TRB14X devices + [ -d /storage -a ! -h /log ] && { + rm -rf /log + ln -sf /storage /log + } + + # Wifi --- + param=$(/sbin/mnf_info "--name") + router_name=${param:0:6} + if [ $router_name == "RUTX08" ] || [ $router_name == "RUTX09" ]; then + rm /etc/modules.d/ath10k + fi + + /bin/board_detect + + /sbin/kmodloader + + /bin/config_generate + uci_apply_defaults + + [ -f "/etc/config/teltonika" ] && rm /etc/config/teltonika + + # temporary hack until configd exists + /sbin/reload_config + # leave finished boot script indication + touch /var/run/boot-done +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/done b/6.1/target/linux/ipq40xx/base-files/etc/init.d/done new file mode 100755 index 00000000..b64e6e4d --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/done @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=95 +boot() { + mount_root done + rm -f /sysupgrade.tgz && sync + + # process user commands + [ -f /etc/rc.local ] && { + sh /etc/rc.local + } +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/gpio_switch b/6.1/target/linux/ipq40xx/base-files/etc/init.d/gpio_switch new file mode 100755 index 00000000..24d790b0 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/gpio_switch @@ -0,0 +1,66 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015 OpenWrt.org + +START=94 +STOP=10 +USE_PROCD=1 + + +load_gpio_switch() +{ + local name + local gpio_pin + local value + + config_get gpio_pin "$1" gpio_pin + config_get name "$1" name + config_get value "$1" value 0 + + [ -z "$gpio_pin" ] && { + echo >&2 "Skipping gpio_switch '$name' due to missing gpio_pin" + return 1 + } + + local gpio_path + if [ -n "$(echo "$gpio_pin" | grep -E "^[0-9]+$")" ]; then + gpio_path="/sys/class/gpio/gpio${gpio_pin}" + + # export GPIO pin for access + [ -d "$gpio_path" ] || { + echo "$gpio_pin" >/sys/class/gpio/export + # we need to wait a bit until the GPIO appears + [ -d "$gpio_path" ] || sleep 1 + } + + # direction attribute only exists if the kernel supports changing the + # direction of a GPIO + if [ -e "${gpio_path}/direction" ]; then + # set the pin to output with high or low pin value + { [ "$value" = "0" ] && echo "low" || echo "high"; } \ + >"$gpio_path/direction" + else + { [ "$value" = "0" ] && echo "0" || echo "1"; } \ + >"$gpio_path/value" + fi + else + gpio_path="/sys/class/gpio/${gpio_pin}" + + [ -d "$gpio_path" ] && { + { [ "$value" = "0" ] && echo "0" || echo "1"; } \ + >"$gpio_path/value" + } + fi +} + +service_triggers() +{ + procd_add_reload_trigger "system" +} + +start_service() +{ + [ -e /sys/class/gpio/ ] && { + config_load system + config_foreach load_gpio_switch gpio_switch + } +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/led b/6.1/target/linux/ipq40xx/base-files/etc/init.d/led new file mode 100755 index 00000000..277fb4e7 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/led @@ -0,0 +1,140 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008 OpenWrt.org + +START=96 + +load_led() { + local name + local sysfs + local trigger + local dev + local ports + local mode + local default + local delayon + local delayoff + local interval + + config_get sysfs $1 sysfs + config_get name $1 name "$sysfs" + config_get trigger $1 trigger "none" + config_get dev $1 dev + config_get ports $1 port + config_get mode $1 mode + config_get_bool default $1 default "0" + config_get delayon $1 delayon + config_get delayoff $1 delayoff + config_get interval $1 interval "50" + config_get port_state $1 port_state + config_get delay $1 delay "150" + config_get message $1 message "" + config_get gpio $1 gpio "0" + config_get inverted $1 inverted "0" + + if [ "$trigger" = "rssi" ]; then + # handled by rssileds userspace process + return + fi + + [ "$trigger" = "usbdev" ] && { + # Backward compatibility: translate to the new trigger + trigger="usbport" + # Translate port of root hub, e.g. 4-1 -> usb4-port1 + ports=$(echo "$dev" | sed -n 's/^\([0-9]*\)-\([0-9]*\)$/usb\1-port\2/p') + # Translate port of extra hub, e.g. 2-2.4 -> 2-2-port4 + [ -z "$ports" ] && ports=$(echo "$dev" | sed -n 's/\./-port/p') + } + + [ -e /sys/class/leds/${sysfs}/brightness ] && { + echo "setting up led ${name}" + + printf "%s %s %d\n" \ + "$sysfs" \ + "$(sed -ne 's/^.*\[\(.*\)\].*$/\1/p' /sys/class/leds/${sysfs}/trigger)" \ + "$(cat /sys/class/leds/${sysfs}/brightness)" \ + >> /var/run/led.state + + [ "$default" = 0 ] && + echo 0 >/sys/class/leds/${sysfs}/brightness + + echo $trigger > /sys/class/leds/${sysfs}/trigger 2> /dev/null + ret="$?" + + [ $default = 1 ] && + cat /sys/class/leds/${sysfs}/max_brightness > /sys/class/leds/${sysfs}/brightness + + [ $ret = 0 ] || { + echo >&2 "Skipping trigger '$trigger' for led '$name' due to missing kernel module" + return 1 + } + case "$trigger" in + "netdev") + [ -n "$dev" ] && { + echo $dev > /sys/class/leds/${sysfs}/device_name + for m in $mode; do + [ -e "/sys/class/leds/${sysfs}/$m" ] && \ + echo 1 > /sys/class/leds/${sysfs}/$m + done + echo $interval > /sys/class/leds/${sysfs}/interval + } + ;; + + "timer"|"oneshot") + [ -n "$delayon" ] && \ + echo $delayon > /sys/class/leds/${sysfs}/delay_on + [ -n "$delayoff" ] && \ + echo $delayoff > /sys/class/leds/${sysfs}/delay_off + ;; + + "usbport") + local p + + for p in $ports; do + echo 1 > /sys/class/leds/${sysfs}/ports/$p + done + ;; + + "port_state") + [ -n "$port_state" ] && \ + echo $port_state > /sys/class/leds/${sysfs}/port_state + ;; + + "gpio") + echo $gpio > /sys/class/leds/${sysfs}/gpio + echo $inverted > /sys/class/leds/${sysfs}/inverted + ;; + + switch[0-9]*) + local port_mask speed_mask + + config_get port_mask $1 port_mask + [ -n "$port_mask" ] && \ + echo $port_mask > /sys/class/leds/${sysfs}/port_mask + config_get speed_mask $1 speed_mask + [ -n "$speed_mask" ] && \ + echo $speed_mask > /sys/class/leds/${sysfs}/speed_mask + [ -n "$mode" ] && \ + echo "$mode" > /sys/class/leds/${sysfs}/mode + ;; + esac + } +} + +start() { + [ -e /sys/class/leds/ ] && { + [ -s /var/run/led.state ] && { + local led trigger brightness + while read led trigger brightness; do + [ -e "/sys/class/leds/$led/trigger" ] && \ + echo "$trigger" > "/sys/class/leds/$led/trigger" + + [ -e "/sys/class/leds/$led/brightness" ] && \ + echo "$brightness" > "/sys/class/leds/$led/brightness" + done < /var/run/led.state + rm /var/run/led.state + } + + config_load system + config_foreach load_led led + } +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker b/6.1/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker new file mode 100755 index 00000000..46202b76 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Teltonika Networks +# Copyright (C) 2022 Ycarus (Yannick Chabanois) + +START=2 + +USE_PROCD=1 + +PROG=/bin/board_track +NAME=board_track +PIDCOUNT=1 + +start_service() { + . /lib/functions + + [ "$(board_name)" != "teltonika,rutx" ] && return 0 + local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid" + + procd_open_instance + procd_set_param command "$PROG" + procd_set_param file /etc/config/system + + procd_set_param respawn + + procd_set_param stdout 1 + procd_set_param pidfile $pid_file + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "system" +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/ntpserver b/6.1/target/linux/ipq40xx/base-files/etc/init.d/ntpserver new file mode 100755 index 00000000..78095bd4 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/ntpserver @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +# Copyright (C) 2021 Teltonika + +START=50 +STOP=51 +USE_PROCD=1 + +service_triggers() +{ + procd_add_reload_trigger "ntpserver" +} + +start_service() { + . /lib/functions.sh + local enabled + + config_load ntpserver + config_get enabled general enabled "0" + + [ "$enabled" -gt 0 ] || return + + logger -t "ntpd" "Starting NTP server" + procd_open_instance + procd_set_param respawn 0 + procd_set_param command "ntpd" -ln + procd_close_instance +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/powerctl b/6.1/target/linux/ipq40xx/base-files/etc/init.d/powerctl new file mode 100755 index 00000000..7b346fc5 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/powerctl @@ -0,0 +1,32 @@ +#!/bin/sh /etc/rc.common + +START=98 + +ipq40xx_power_auto() { + # change scaling governor as ondemand to enable clock scaling based on system load + echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor + + # set scaling min freq as 200 MHz + echo "716000" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq + + # Change sampling rate for frequency scaling decisions to 1s, from 10 ms + #echo "1000000" > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate + + # Change sampling rate for frequency down scaling decision to 10s + #echo 10 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor + + # Change the CPU load threshold above which frequency is up-scaled to + # turbo frequency,to 50% + #echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold +} + +start() { + . /lib/functions.sh + + local board=$(board_name) + case "$board" in + teltonika,rutx | ap-dk01.1-c1 | ap-dk01.1-c2 | ap-dk04.1-c1 | ap-dk04.1-c2 | ap-dk04.1-c3 | \ + ap-dk04.1-c4 | ap-dk04.1-c5 | ap-dk05.1-c1 | ap-dk06.1-c1 | ap-dk07.1-c1 | ap-dk07.1-c2 | ap-dk07.1-c3) + ipq40xx_power_auto ;; + esac +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysctl b/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysctl new file mode 100755 index 00000000..01416a5c --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysctl @@ -0,0 +1,46 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=11 + +apply_defaults() { + local mem="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" + local min_free frag_low_thresh frag_high_thresh + + if [ "$mem" -gt 65536 ]; then # 128M + min_free=16384 + elif [ "$mem" -gt 32768 ]; then # 64M + #Too high for RUT3 device, lets make 2048 + #min_free=8192 + min_free=2048 + else + min_free=1024 + frag_low_thresh=393216 + frag_high_thresh=524288 + fi + + sysctl -qw vm.min_free_kbytes="$min_free" + + [ "$frag_low_thresh" ] && sysctl -qw \ + net.ipv4.ipfrag_low_thresh="$frag_low_thresh" \ + net.ipv4.ipfrag_high_thresh="$frag_high_thresh" \ + net.ipv6.ip6frag_low_thresh="$frag_low_thresh" \ + net.ipv6.ip6frag_high_thresh="$frag_high_thresh" \ + net.netfilter.nf_conntrack_frag6_low_thresh="$frag_low_thresh" \ + net.netfilter.nf_conntrack_frag6_high_thresh="$frag_high_thresh" + + # first set default, then all interfaces to avoid races with appearing interfaces + if [ -d /proc/sys/net/ipv6/conf ]; then + echo 0 > /proc/sys/net/ipv6/conf/default/accept_ra + for iface in /proc/sys/net/ipv6/conf/*/accept_ra; do + echo 0 > "$iface" + done + fi +} + +start() { + apply_defaults + for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do + [ -f "$CONF" ] && sysctl -e -p "$CONF" >&- + done +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysfixtime b/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysfixtime new file mode 100755 index 00000000..47d7af61 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/sysfixtime @@ -0,0 +1,34 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013-2014 OpenWrt.org + +START=00 +STOP=90 + +RTC_DEV=/dev/rtc0 +HWCLOCK=/sbin/hwclock + +boot() { +# start && exit 0 + + local maxtime="$(maxtime)" + local curtime="$(date +%s)" + [ $curtime -lt $maxtime ] && date -s @$maxtime +} + +start() { + boot +} + +stop() { + [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -u -f $RTC_DEV && \ + logger -t sysfixtime "saved '$(date)' to $RTC_DEV" +} + +maxtime() { + local file newest + + for file in $( find /etc -type f ) ; do + [ -z "$newest" -o "$newest" -ot "$file" ] && newest=$file + done + [ "$newest" ] && date -r "$newest" +%s +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/system b/6.1/target/linux/ipq40xx/base-files/etc/init.d/system new file mode 100755 index 00000000..0e467091 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/system @@ -0,0 +1,45 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 OpenWrt.org + +START=10 +USE_PROCD=1 + +validate_system_section() { + uci_load_validate system system "$1" "$2" \ + 'hostname:string:%%NAME%%' \ + 'conloglevel:uinteger' \ + 'buffersize:uinteger' \ + 'timezone:string:UTC' \ + 'zonename:string' +} + +system_config() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + echo "$hostname" > /proc/sys/kernel/hostname + [ -z "$conloglevel" -a -z "$buffersize" ] || dmesg ${conloglevel:+-n $conloglevel} ${buffersize:+-s $buffersize} + echo "$timezone" > /tmp/TZ + [ -n "$zonename" ] && [ -f "/usr/share/zoneinfo/${zonename// /_}" ] \ + && ln -sf "/usr/share/zoneinfo/${zonename// /_}" /tmp/localtime \ + && rm -f /tmp/TZ + + # apply timezone to kernel + hwclock -u --systz +} + +reload_service() { + config_load system + config_foreach validate_system_section system system_config +} + +service_triggers() { + procd_add_reload_trigger "system" + procd_add_validation validate_system_section +} + +start_service() { + reload_service +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/init.d/umount b/6.1/target/linux/ipq40xx/base-files/etc/init.d/umount new file mode 100755 index 00000000..b764ae15 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/init.d/umount @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +STOP=90 + +restart() { + : +} + +stop() { + sync + /bin/umount -a -d -r +} diff --git a/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/01_mnf-info b/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/01_mnf-info new file mode 100644 index 00000000..0e5bf027 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/01_mnf-info @@ -0,0 +1,26 @@ +#!/bin/sh + +SECTION="hwinfo" +CONFIG="hwinfo" + +get_hw_info() { + param=$(/sbin/mnf_info "--name") + [ -n "$param" -a ${#param} == 12 ] && uci set "system"."@system[0]"."device_code"=$param + + hostname=${param:0:6} + [ -n "$hostname" -a ${#hostname} == 6 -a -z "$(uci -q get system.@system[0].hostname)" ] && uci set "system"."@system[0]"."hostname"=OpenMPTCProuter + + routername=${param:0:6} + [ -n "$routername" -a ${#routername} == 6 -a -z "$(uci -q get system.@system[0].routername)" ] && uci set "system"."@system[0]"."routername"=$routername + + version=$(cat /etc/version) + [ -n "$version" ] && uci set "system"."@system[0]"."device_fw_version"=$version + + uci commit "system" +} + +# get device information +echo "Reading device information" +get_hw_info + +exit 0 diff --git a/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/04_migrate-vlan b/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/04_migrate-vlan new file mode 100644 index 00000000..7b96fa48 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/etc/uci-defaults/04_migrate-vlan @@ -0,0 +1,34 @@ +#!/bin/sh +. /lib/functions.sh + +move_network(){ + local section=$1 + local device ports vlan + + config_get ports "$section" ports + config_get device "$section" device + config_get vlan "$section" vlan + + [ "$vlan" -eq 1 ] && { + if list_contains "ports" "0t" && list_contains "ports" "5"; then + uci_set network "$section" ports "${ports/0t/0}" + uci_set network "$section" vlan "2" + uci_remove network "$section" vid + fi + } + + [ "$vlan" -eq 2 ] && { + if list_contains ports "0t"; then + echo "Contains" + uci_set network "$section" ports "${ports/0t/0}" + uci_set network "$section" vlan "1" + uci_remove network "$section" vid + fi + } +} + +config_load network +config_foreach move_network switch_vlan +uci_commit network + +exit 0 diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/board.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/board.sh new file mode 100644 index 00000000..2f38cbdc --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/board.sh @@ -0,0 +1,40 @@ + +. /usr/share/libubox/jshn.sh + +# when device contains 2 internal modems, this function will return '2' if +# selected modem(inc_id) is builtin and primary. +# And if it's only builtin, then '1' +is_builtin_modem() { + local inc_id="$1" + local modem modems id builtin primary + + json_init + json_load_file "/etc/board.json" + + json_get_keys modems modems + json_select modems + + for modem in $modems; do + json_select "$modem" + json_get_vars id builtin primary + + [ "$id" = "$inc_id" ] && { + [ -n "$builtin" ] && { + [ -n "$primary" ] && { + echo 2 + return + } + + echo 1 + return + } + + echo 0 + return + } + + json_select .. + done + + echo 0 +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/migrate.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/migrate.sh new file mode 100644 index 00000000..634f9560 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/migrate.sh @@ -0,0 +1,196 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh + +CFG_PATH="/etc/config/" + +get_section_name() { + local ___var="$1" + [ "$#" -ge 1 ] && shift + local ___type="$1" + [ "$#" -ge 1 ] && shift + local section cfgtype + + [ -z "$CONFIG_SECTIONS" ] && return 0 + for section in ${CONFIG_SECTIONS}; do + config_get cfgtype "$section" TYPE + [ -n "$___type" -a "x$cfgtype" != "x$___type" ] && continue + eval export "${___var}=\${section}" + return 0 + done +} + +_set_option() { + local option="$1" + local value="$2" + + uci_set "$_NEW_CONFIG" "$_NEW_SEC_NAME" "$option" "$value" +} + +_set_list_option() { + local option="$1" + local value="$2" + + for element in $value; do + uci_add_list "$_NEW_CONFIG" "$_NEW_SEC_NAME" "$option" "$element" + done +} + +_del_uci_element() { + local section="$1" + local option="$2" + + uci_remove "$_OLD_CONFIG" "$section" "$option" +} +_option_cond_cb() { + local value=$3 + + json_select $2 + json_get_var old 1 + json_get_var new 2 + + [ "$old" = "$value" ] && _COND_VALUE="$new" + + json_select .. +} + +_parse_condition(){ + local value="$1" + + _COND_VALUE= + json_for_each_item _option_cond_cb "if" "$value" +} + +_option_rule_cb(){ + local rule="$1" + local option="$2" + local value + + [ -n "$rule" ] || return 0 + + json_select "$option" + json_get_vars new_name "if" default cb type + + if [ -n "$cb" ]; then + eval "$cb \"\$option\" \"\$_OLD_SEC_NAME\" \"\$_NEW_SEC_NAME\"" + [ "$?" -eq 0 ] && { + json_select .. + return 0 + } + + value="$_OPTION_VALUE" + else + config_get value $_OLD_SEC_NAME "$option" "$default" + fi + + [ -n "$if" ] && { + _parse_condition "$value" + value="${_COND_VALUE:-${value:-$default}}" + } + + if [ -n "$type" -a "$type" = "list" ]; then + _set_list_option "${new_name:-$option}" "$value" + else + _set_option "${new_name:-$option}" "$value" + fi + + json_select .. +} + +_init_section() { + local sec_t + + json_get_vars old_name new_name new_type old_type + [ -n "$old_name" -o -n "$old_type" ] || return 1 + + if [ -z "$old_name" ]; then + get_section_name _OLD_SEC_NAME "$old_type" + else + _OLD_SEC_NAME=$old_name + fi + + _NEW_SEC_NAME=$new_name + _OLD_SEC_TYPE=$old_type + _NEW_SEC_TYPE=${new_type:-$old_type} + [ -n "$_NEW_SEC_TYPE" ] || \ + eval "_NEW_SEC_TYPE=\$CONFIG_${_OLD_SEC_NAME}_TYPE" + + if [ -n "$_NEW_SEC_NAME" ]; then + uci set "$_NEW_CONFIG"."$_NEW_SEC_NAME"="$_NEW_SEC_TYPE" + else + _NEW_SEC_NAME="$(uci -q add "$_NEW_CONFIG" "$_NEW_SEC_TYPE")" + fi + + [ -n "$_NEW_SEC_NAME" ] || return 1 +} + +_section_rule_cb(){ + local rule="$1" + local section="$2" + local value + + [ -n "$rule" ] || return 0 + + json_select "$section" + json_get_vars cb old_name new_name new_type old_type remove + [ -n "$cb" ] && { + eval "$cb \"\$old_name\" \"\$new_name\" \"\$old_type\" \"\$new_type\"" + [ "$?" -eq 0 ] && { + json_select .. + return 0 + } + } + + _init_section + [ $? -ne 0 ] && { + logger -t "Migration" "Unable to init section" + json_select .. + + return 1 + } + + json_for_each_item _option_rule_cb options + json_select .. + [ -n "$remove" ] && { + _del_uci_element "$old_name" + uci_commit "$_OLD_CONFIG" + } +} + +_init_config() { + json_select config + json_get_vars old_name new_name + + [ -n "$old_name" ] || return 1 + [ -f "$CFG_PATH$old_name" ] || return 1 + [ -f "$CFG_PATH$new_name" ] || touch $CFG_PATH$new_name + + config_load "$old_name" + _NEW_CONFIG="${new_name:-$old_name}" + _OLD_CONFIG="$old_name" + + json_select .. +} + +migrate() { + local remove + local json_file="$1" + + [ -f "$json_file" ] || return 0 + + json_init + json_load_file "$json_file" + json_select + _init_config + [ $? -ne 0 ] && { + logger -t "Migration" "Unable to load config" + return 1 + } + + json_for_each_item _section_rule_cb sections + uci_commit "$_NEW_CONFIG" + + json_get_vars remove + [ -n "$remove" ] && rm "$CFG_PATH$_OLD_CONFIG" +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/network.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/network.sh new file mode 100644 index 00000000..a5d8d263 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/network.sh @@ -0,0 +1,313 @@ +# 1: destination variable +# 2: interface +# 3: path +# 4: separator +# 5: limit +__network_ifstatus() { + local __tmp + + [ -z "$__NETWORK_CACHE" ] && { + __tmp="$(ubus call network.interface dump 2>&1)" + case "$?" in + 4) : ;; + 0) export __NETWORK_CACHE="$__tmp" ;; + *) echo "$__tmp" >&2 ;; + esac + } + + __tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "${__NETWORK_CACHE:-{}}" -e "$1=@.interface${2:+[@.interface='$2']}$3")" + + [ -z "$__tmp" ] && \ + unset "$1" && \ + return 1 + + eval "$__tmp" +} + +# determine first IPv4 address of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddr() { + __network_ifstatus "$1" "$2" "['ipv4-address'][0].address"; +} + +# determine first IPv6 address of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddr6() { + __network_ifstatus "$1" "$2" "['ipv6-address'][0].address" || \ + __network_ifstatus "$1" "$2" "['ipv6-prefix-assignment'][0]['local-address'].address" || \ + return 1 +} + +# determine first IPv4 subnet of given logical interface +# 1: destination variable +# 2: interface +network_get_subnet() { + __network_ifstatus "$1" "$2" "['ipv4-address'][0]['address','mask']" "/" +} + +# determine first IPv6 subnet of given logical interface +# 1: destination variable +# 2: interface +network_get_subnet6() { + local __nets __addr + + if network_get_subnets6 __nets "$2"; then + # Attempt to return first non-fe80::/10, non-fc::/7 range + for __addr in $__nets; do + case "$__addr" in fe[8ab]?:*|f[cd]??:*) + continue + esac + export "$1=$__addr" + return 0 + done + + # Attempt to return first non-fe80::/10 range + for __addr in $__nets; do + case "$__addr" in fe[8ab]?:*) + continue + esac + export "$1=$__addr" + return 0 + done + + # Return first item + for __addr in $__nets; do + export "$1=$__addr" + return 0 + done + fi + + unset "$1" + return 1 +} + +# determine first IPv6 prefix of given logical interface +# 1: destination variable +# 2: interface +network_get_prefix6() { + __network_ifstatus "$1" "$2" "['ipv6-prefix'][0]['address','mask']" "/" +} + +# determine all IPv4 addresses of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddrs() { + __network_ifstatus "$1" "$2" "['ipv4-address'][*].address" +} + +# determine all IPv6 addresses of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddrs6() { + local __addr + local __list="" + + if __network_ifstatus "__addr" "$2" "['ipv6-address'][*].address"; then + for __addr in $__addr; do + __list="${__list:+$__list }${__addr}" + done + fi + + if __network_ifstatus "__addr" "$2" "['ipv6-prefix-assignment'][*]['local-address'].address"; then + for __addr in $__addr; do + __list="${__list:+$__list }${__addr}" + done + fi + + if [ -n "$__list" ]; then + export "$1=$__list" + return 0 + fi + + unset "$1" + return 1 +} + +# determine all IP addresses of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddrs_all() { + local __addr __addr6 + + network_get_ipaddrs __addr "$2" + network_get_ipaddrs6 __addr6 "$2" + + if [ -n "$__addr" -o -n "$__addr6" ]; then + export "$1=${__addr:+$__addr }$__addr6" + return 0 + fi + + unset "$1" + return 1 +} + +# determine all IPv4 subnets of given logical interface +# 1: destination variable +# 2: interface +network_get_subnets() { + __network_ifstatus "$1" "$2" "['ipv4-address'][*]['address','mask']" "/ " +} + +# determine all IPv6 subnets of given logical interface +# 1: destination variable +# 2: interface +network_get_subnets6() { + local __addr __mask + local __list="" + + if __network_ifstatus "__addr" "$2" "['ipv6-address'][*]['address','mask']" "/ "; then + for __addr in $__addr; do + __list="${__list:+$__list }${__addr}" + done + fi + + if __network_ifstatus "__addr" "$2" "['ipv6-prefix-assignment'][*]['local-address'].address" && \ + __network_ifstatus "__mask" "$2" "['ipv6-prefix-assignment'][*].mask"; then + for __addr in $__addr; do + __list="${__list:+$__list }${__addr}/${__mask%% *}" + __mask="${__mask#* }" + done + fi + + if [ -n "$__list" ]; then + export "$1=$__list" + return 0 + fi + + unset "$1" + return 1 +} + +# determine all IPv6 prefixes of given logical interface +# 1: destination variable +# 2: interface +network_get_prefixes6() { + __network_ifstatus "$1" "$2" "['ipv6-prefix'][*]['address','mask']" "/ " +} + +# determine IPv4 gateway of given logical interface +# 1: destination variable +# 2: interface +# 3: consider inactive gateway if "true" (optional) +network_get_gateway() { + __network_ifstatus "$1" "$2" ".route[@.target='0.0.0.0' && !@.table].nexthop" "" 1 && \ + return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive.route[@.target='0.0.0.0' && !@.table].nexthop" "" 1 +} + +# determine IPv6 gateway of given logical interface +# 1: destination variable +# 2: interface +# 3: consider inactive gateway if "true" (optional) +network_get_gateway6() { + __network_ifstatus "$1" "$2" ".route[@.target='::' && !@.table].nexthop" "" 1 && \ + return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive.route[@.target='::' && !@.table].nexthop" "" 1 +} + +# determine the DNS servers of the given logical interface +# 1: destination variable +# 2: interface +# 3: consider inactive servers if "true" (optional) +network_get_dnsserver() { + __network_ifstatus "$1" "$2" "['dns-server'][*]" && return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive['dns-server'][*]" +} + +# determine the domains of the given logical interface +# 1: destination variable +# 2: interface +# 3: consider inactive domains if "true" (optional) +network_get_dnssearch() { + __network_ifstatus "$1" "$2" "['dns-search'][*]" && return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive['dns-search'][*]" +} + +# 1: destination variable +# 2: addr +# 3: inactive +# 4: limit +__network_wan() +{ + limit=1 + [ -n "$4" ] && limit="$4" + __network_ifstatus "$1" "" \ + "[@.route[@.target='$2' && !@.table]].interface" "" $limit && \ + return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "" \ + "[@.inactive.route[@.target='$2' && !@.table]].interface" "" $limit +} + +# find the logical interface which holds the current IPv4 default route +# 1: destination variable +# 2: consider inactive default routes if "true" (optional) +network_find_wan() { __network_wan "$1" "0.0.0.0" "$2" "$3"; } + +# find the logical interface which holds the current IPv6 default route +# 1: destination variable +# 2: consider inactive default routes if "true" (optional) +network_find_wan6() { __network_wan "$1" "::" "$2"; } + +# test whether the given logical interface is running +# 1: interface +network_is_up() +{ + local __up + __network_ifstatus "__up" "$1" ".up" && [ "$__up" = 1 ] +} + +# determine the protocol of the given logical interface +# 1: destination variable +# 2: interface +network_get_protocol() { __network_ifstatus "$1" "$2" ".proto"; } + +# determine the uptime of the given logical interface +# 1: destination variable +# 2: interface +network_get_uptime() { __network_ifstatus "$1" "$2" ".uptime"; } + +# determine the metric of the given logical interface +# 1: destination variable +# 2: interface +network_get_metric() { __network_ifstatus "$1" "$2" ".metric"; } + +# determine the layer 3 linux network device of the given logical interface +# 1: destination variable +# 2: interface +network_get_device() { __network_ifstatus "$1" "$2" ".l3_device"; } + +# determine the layer 2 linux network device of the given logical interface +# 1: destination variable +# 2: interface +network_get_physdev() { __network_ifstatus "$1" "$2" ".device"; } + +# defer netifd actions on the given linux network device +# 1: device name +network_defer_device() +{ + ubus call network.device set_state \ + "$(printf '{ "name": "%s", "defer": true }' "$1")" 2>/dev/null +} + +# continue netifd actions on the given linux network device +# 1: device name +network_ready_device() +{ + ubus call network.device set_state \ + "$(printf '{ "name": "%s", "defer": false }' "$1")" 2>/dev/null +} + +# flush the internal value cache to force re-reading values from ubus +network_flush_cache() { unset __NETWORK_CACHE; } diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-defaults.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-defaults.sh new file mode 100755 index 00000000..5cb17a99 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-defaults.sh @@ -0,0 +1,284 @@ +#!/bin/ash + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh + +ucidef_add_nand_info() { + local model="$1" + + model=${model:0:7} + + json_select_object nand + + case "$model" in + TRB1412) + json_add_int blocksize 128 + json_add_int pagesize 2048 + json_add_int subpagesize 2048 + ;; + TRB1422 |\ + TRB1423 |\ + TRB1452) + json_add_int blocksize 256 + json_add_int pagesize 4096 + json_add_int subpagesize 4096 + ;; + TRB14*0) + json_add_int blocksize 128 + json_add_int pagesize 2048 + json_add_int subpagesize 2048 + ;; + TRB14*1) + json_add_int blocksize 256 + json_add_int pagesize 4096 + json_add_int subpagesize 4096 + ;; + esac + + json_select .. +} + +ucidef_add_static_modem_info() { + #Parameters: model usb_id sim_count other_params + local model usb_id count + local modem_counter=0 + local sim_count=1 + + model="$1" + usb_id="$2" + + [ -n "$3" ] && sim_count="$3" + + json_get_keys count modems + [ -n "$count" ] && modem_counter="$(echo "$count" | wc -w)" + + json_select_array "modems" + json_add_object + json_add_string id "$usb_id" + json_add_string num "$((modem_counter + 1))" + json_add_boolean builtin 1 + json_add_int simcount "$sim_count" + + for i in "$@"; do + case "$i" in + primary) + json_add_boolean primary 1 + ;; + gps_out) + json_add_boolean gps_out 1 + ;; + esac + done + + json_close_object + json_select .. +} + +ucidef_add_trb14x_lte_modem() { + print_array() { + json_add_array $1 + for element in $2 + do + json_add_string "" "$(echo $element)" + done + json_close_array + } + #Parameters: model primary + local model vendor product boudrate gps type desc control region modem_counter + modem_counter=1 + json_select_array "modems" + + model="$1" + + model=${model:0:7} + + case "$model" in + TRB1422) + vendor=05c6 + product=9215 + ;; + TRB1412 |\ + TRB1423 |\ + TRB1452 |\ + TRB140*) + vendor=2c7c + product=0125 + ;; + TRB14*) + vendor=2c7c + product=0121 + ;; + esac + + case "$model" in + TRB1412 |\ + TRB14*0) + region="EU" + [ "$product" = "0121" ] && { + lte_bands="1 3 7 8 20 28" + trysg_bands="wcdma_2100 wcdma_900" + dug_bands="gsm_1800 gsm_900" + } + [ "$product" = "0125" ] && { + lte_bands="1 3 7 8 20 28 38 40 41" + trysg_bands="wcdma_2100 wcdma_900" + dug_bands="gsm_1800 gsm_900" + } + ;; + TRB1422) + region="CE" + lte_bands="1 3 5 8 34 38 39 40 41" + trysg_bands="bc-0-a-system bc-0-b-system wcdma_2100 wcdma_900" + dug_bands="gsm_1800 gsm_900" + ;; + TRB1423 |\ + TRB1452 |\ + TRB14*1) + region="AU" + [ "$product" = "0121" ] && { + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="wcdma_2100 wcdma_1900 wcdma_900 wcdma_850" + dug_bands="gsm_1800 gsm_900 gsm_850 gsm_1900" + } + [ "$product" = "0125" ] && { + lte_bands="1 2 3 4 5 7 8 28 40" + trysg_bands="wcdma_2100 wcdma_1900 wcdma_900 wcdma_850" + dug_bands="gsm_1800 gsm_900 gsm_850 gsm_1900" + } + ;; + esac + + [ -f "/lib/network/wwan/$vendor:$product" ] && { + devicename="3-1" + json_set_namespace defaults old_cb + json_load "$(cat /lib/network/wwan/$vendor:$product)" + json_get_vars gps boudrate type desc control stop_bits + json_set_namespace $old_cb + + [ "${devicename%%:*}" = "$devicename" ] && { + json_add_object + json_add_string id "$devicename" + json_add_string num "$modem_counter" + json_add_string vendor "$vendor" + json_add_string product "$product" + json_add_string stop_bits "$stop_bits" + json_add_string gps "$gps" + json_add_string boudrate "$boudrate" + json_add_string type "$type" + json_add_string desc "$desc" + json_add_string region "$region" + json_add_string control "$control" + json_add_int simcount 1 + json_add_boolean builtin 1 + [ -n "$2" ] && json_add_boolean primary 1 + json_add_object service_modes + [ -z "$lte_bands" ] || print_array "4G" "$lte_bands" + [ -z "$trysg_bands" ] || print_array "3G" "$trysg_bands" + [ -z "$dug_bands" ] || print_array "2G" "$dug_bands" + json_close_object + json_close_object + } + } + json_select .. +} + +ucidef_add_serial_capabilities() { + json_select_array serial + json_add_object + [ -n "$1" ] && { + json_select_array devices + for d in $1; do + json_add_string "" $d + done + json_select .. + } + + json_select_array bauds + for b in $2; do + json_add_string "" $b + done + json_select .. + + json_select_array data_bits + for n in $3; do + json_add_string "" $n + done + json_select .. + json_close_object + json_select .. +} + +ucidef_set_hwinfo() { + local function + local dual_sim=0 + local wifi=0 + local dual_band_ssid=0 + local wps=0 + local mobile=0 + local gps=0 + local usb=0 + local bluetooth=0 + local ethernet=0 + local sfp_port=0 + local ios=0 + + for function in "$@"; do + case "$function" in + dual_sim) + dual_sim=1 + ;; + wifi) + wifi=1 + ;; + dual_band_ssid) + dual_band_ssid=1 + ;; + wps) + wps=1 + ;; + mobile) + mobile=1 + ;; + gps) + gps=1 + ;; + usb) + usb=1 + ;; + bluetooth) + bluetooth=1 + ;; + ethernet) + ethernet=1 + ;; + sfp_port) + sfp_port=1 + ;; + ios) + ios=1 + ;; + at_sim) + at_sim=1 + ;; + esac + done + + json_select_object hwinfo + json_add_boolean dual_sim "$dual_sim" + json_add_boolean usb "$usb" + json_add_boolean bluetooth "$bluetooth" + json_add_boolean wifi "$wifi" + json_add_boolean dual_band_ssid "$dual_band_ssid" + json_add_boolean wps "$wps" + json_add_boolean mobile "$mobile" + json_add_boolean gps "$gps" + json_add_boolean ethernet "$ethernet" + json_add_boolean sfp_port "$sfp_port" + json_add_boolean ios "$ios" + json_add_boolean at_sim "$at_sim" + json_select .. +} + +ucidef_set_release_version() { + json_add_string release_version "$1" +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-functions.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-functions.sh new file mode 100755 index 00000000..5381f81f --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/teltonika-functions.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +is_ios_enabled() { + local ios + json_load_file "/etc/board.json" && \ + json_select hwinfo && \ + json_get_var ios ios && [ "$ios" = "1" ] +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/functions/uci-defaults.sh b/6.1/target/linux/ipq40xx/base-files/lib/functions/uci-defaults.sh new file mode 100644 index 00000000..75381262 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/functions/uci-defaults.sh @@ -0,0 +1,626 @@ +#!/bin/ash + +. /lib/functions.sh +. /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 network=$1; shift + + [ -z "$network" ] && return + + json_select_object network + json_select_object "$network" + + while [ -n "$1" ]; do + local opt=$1; shift + local val=$1; shift + + [ -n "$opt" -a -n "$val" ] || break + case "$val" in + true) json_add_boolean "$opt" "1" ;; + false) json_add_boolean "$opt" "0" ;; + *) json_add_string "$opt" "$val" ;; + esac + done + + if ! json_is_a proto string; then + case "$network" in + lan) json_add_string proto static ;; + wan) json_add_string proto dhcp ;; + *) json_add_string proto none ;; + esac + fi + + json_select .. + json_select .. +} + +ucidef_set_board_id() { + json_select_object model + json_add_string id "$1" + json_select .. +} + +ucidef_set_board_platform() { + json_select_object model + json_add_string platform "$1" + json_select .. +} + +ucidef_set_model_name() { + json_select_object model + json_add_string name "$1" + json_select .. +} + +ucidef_set_compat_version() { + json_select_object system + json_add_string compat_version "${1:-1.0}" + json_select .. +} + +ucidef_set_interface_lan() { + ucidef_set_interface "lan" ifname "$1" proto "${2:-static}" +} + +ucidef_set_interface_wan() { + ucidef_set_interface "wan" ifname "$1" proto "${2:-dhcp}" +} + +ucidef_set_interfaces_lan_wan() { + local lan_if="$1" + local wan_if="$2" + + ucidef_set_interface_lan "$lan_if" + ucidef_set_interface_wan "$wan_if" +} + +_ucidef_add_switch_port() { + # inherited: $num $device $need_tag $want_untag $role $index $prev_role + # inherited: $n_cpu $n_ports $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5 + + n_ports=$((n_ports + 1)) + + json_select_array ports + json_add_object + json_add_int num "$num" + [ -n "$device" ] && json_add_string device "$device" + [ -n "$need_tag" ] && json_add_boolean need_tag "$need_tag" + [ -n "$want_untag" ] && json_add_boolean want_untag "$want_untag" + [ -n "$role" ] && json_add_string role "$role" + [ -n "$index" ] && json_add_int index "$index" + json_close_object + json_select .. + + # record pointer to cpu entry for lookup in _ucidef_finish_switch_roles() + [ -n "$device" ] && { + export "cpu$n_cpu=$n_ports" + n_cpu=$((n_cpu + 1)) + } + + # create/append object to role list + [ -n "$role" ] && { + json_select_array roles + + if [ "$role" != "$prev_role" ]; then + json_add_object + json_add_string role "$role" + json_add_string ports "$num" + json_close_object + + prev_role="$role" + n_vlan=$((n_vlan + 1)) + else + json_select_object "$n_vlan" + json_get_var port ports + json_add_string ports "$port $num" + json_select .. + fi + + json_select .. + } +} + +_ucidef_finish_switch_roles() { + # inherited: $name $n_cpu $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5 + local index role roles num device need_tag want_untag port ports + + json_select switch + json_select "$name" + json_get_keys roles roles + json_select .. + json_select .. + + for index in $roles; do + eval "port=\$cpu$(((index - 1) % n_cpu))" + + json_select switch + json_select "$name" + json_select ports + json_select "$port" + json_get_vars num device need_tag want_untag + json_select .. + json_select .. + + if [ ${need_tag:-0} -eq 1 -o ${want_untag:-0} -ne 1 ]; then + num="${num}t" + device="${device}.${index}" + fi + + json_select roles + json_select "$index" + json_get_vars role ports + json_add_string ports "$ports $num" + json_add_string device "$device" + json_select .. + json_select .. + json_select .. + json_select .. + + json_select_object network + local devices + + json_select_object "$role" + # attach previous interfaces (for multi-switch devices) + json_get_var devices ifname + if ! list_contains devices "$device"; then + devices="${devices:+$devices }$device" + fi + json_select .. + json_select .. + + ucidef_set_interface "$role" ifname "$devices" + done +} + +ucidef_set_ar8xxx_switch_mib() { + local name="$1" + local type="$2" + local interval="$3" + + json_select_object switch + json_select_object "$name" + json_add_int ar8xxx_mib_type $type + json_add_int ar8xxx_mib_poll_interval $interval + json_select .. + json_select .. +} + +ucidef_add_switch() { + local name="$1"; shift + local port num role device index need_tag prev_role + local cpu0 cpu1 cpu2 cpu3 cpu4 cpu5 + local n_cpu=0 n_vlan=0 n_ports=0 + + json_select_object switch + json_select_object "$name" + json_add_boolean enable 1 + json_add_boolean reset 1 + + for port in "$@"; do + case "$port" in + [0-9]*@*) + num="${port%%@*}" + device="${port##*@}" + need_tag=0 + want_untag=0 + [ "${num%t}" != "$num" ] && { + num="${num%t}" + need_tag=1 + } + [ "${num%u}" != "$num" ] && { + num="${num%u}" + want_untag=1 + } + ;; + [0-9]*:*:[0-9]*) + num="${port%%:*}" + index="${port##*:}" + role="${port#[0-9]*:}"; role="${role%:*}" + ;; + [0-9]*:*) + num="${port%%:*}" + role="${port##*:}" + ;; + esac + + if [ -n "$num" ] && [ -n "$device$role" ]; then + _ucidef_add_switch_port + fi + + unset num device role index need_tag want_untag + done + json_select .. + json_select .. + + _ucidef_finish_switch_roles +} + +ucidef_add_switch_attr() { + local name="$1" + local key="$2" + local val="$3" + + json_select_object switch + json_select_object "$name" + + case "$val" in + true|false) [ "$val" != "true" ]; json_add_boolean "$key" $? ;; + [0-9]) json_add_int "$key" "$val" ;; + *) json_add_string "$key" "$val" ;; + esac + + json_select .. + json_select .. +} + +ucidef_add_switch_port_attr() { + local name="$1" + local port="$2" + local key="$3" + local val="$4" + local ports i num + + json_select_object switch + json_select_object "$name" + + json_get_keys ports ports + json_select_array ports + + for i in $ports; do + json_select "$i" + json_get_var num num + + if [ -n "$num" ] && [ $num -eq $port ]; then + json_select_object attr + + case "$val" in + true|false) [ "$val" != "true" ]; json_add_boolean "$key" $? ;; + [0-9]) json_add_int "$key" "$val" ;; + *) json_add_string "$key" "$val" ;; + esac + + json_select .. + fi + + json_select .. + done + + json_select .. + json_select .. + json_select .. +} + +ucidef_set_interface_macaddr() { + local network="$1" + local macaddr="$2" + + ucidef_set_interface "$network" macaddr "$macaddr" +} + +ucidef_add_atm_bridge() { + local vpi="$1" + local vci="$2" + local encaps="$3" + local payload="$4" + local nameprefix="$5" + + json_select_object dsl + json_select_object atmbridge + json_add_int vpi "$vpi" + json_add_int vci "$vci" + json_add_string encaps "$encaps" + json_add_string payload "$payload" + json_add_string nameprefix "$nameprefix" + json_select .. + json_select .. +} + +ucidef_add_adsl_modem() { + local annex="$1" + local firmware="$2" + + json_select_object dsl + json_select_object modem + json_add_string type "adsl" + json_add_string annex "$annex" + json_add_string firmware "$firmware" + json_select .. + json_select .. +} + +ucidef_add_vdsl_modem() { + local annex="$1" + local tone="$2" + local xfer_mode="$3" + + json_select_object dsl + json_select_object modem + json_add_string type "vdsl" + json_add_string annex "$annex" + json_add_string tone "$tone" + json_add_string xfer_mode "$xfer_mode" + json_select .. + json_select .. +} + +ucidef_set_led_ataport() { + _ucidef_set_led_trigger "$1" "$2" "$3" ata"$4" +} + +_ucidef_set_led_common() { + local cfg="led_$1" + local name="$2" + local sysfs="$3" + + json_select_object led + + json_select_object "$1" + json_add_string name "$name" + json_add_string sysfs "$sysfs" +} + +ucidef_set_led_default() { + local default="$4" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string default "$default" + json_select .. + + json_select .. +} + +ucidef_set_led_gpio() { + local gpio="$4" + local inverted="$5" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string trigger "$trigger" + json_add_string type gpio + json_add_int gpio "$gpio" + json_add_boolean inverted "$inverted" + json_select .. + + json_select .. +} + +ucidef_set_led_ide() { + _ucidef_set_led_trigger "$1" "$2" "$3" disk-activity +} + +ucidef_set_led_netdev() { + local dev="$4" + local mode="${5:-link tx rx}" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string type netdev + json_add_string device "$dev" + json_add_string mode "$mode" + json_select .. + + json_select .. +} + +ucidef_set_led_oneshot() { + _ucidef_set_led_timer $1 $2 $3 "oneshot" $4 $5 +} + +ucidef_set_led_portstate() { + local port_state="$4" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string trigger port_state + json_add_string type portstate + json_add_string port_state "$port_state" + json_select .. + + json_select .. +} + +ucidef_set_led_rssi() { + local iface="$4" + local minq="$5" + local maxq="$6" + local offset="${7:-0}" + local factor="${8:-1}" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string type rssi + json_add_string name "$name" + json_add_string iface "$iface" + json_add_string minq "$minq" + json_add_string maxq "$maxq" + json_add_string offset "$offset" + json_add_string factor "$factor" + json_select .. + + json_select .. +} + +ucidef_set_led_switch() { + local trigger_name="$4" + local port_mask="$5" + local speed_mask="$6" + local mode="$7" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string trigger "$trigger_name" + json_add_string type switch + json_add_string mode "$mode" + json_add_string port_mask "$port_mask" + json_add_string speed_mask "$speed_mask" + json_select .. + + json_select .. +} + +_ucidef_set_led_timer() { + local trigger_name="$4" + local delayon="$5" + local delayoff="$6" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string type "$trigger_name" + json_add_string trigger "$trigger_name" + json_add_int delayon "$delayon" + json_add_int delayoff "$delayoff" + json_select .. + + json_select .. +} + +ucidef_set_led_timer() { + _ucidef_set_led_timer $1 $2 $3 "timer" $4 $5 +} + +_ucidef_set_led_trigger() { + local trigger_name="$4" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string trigger "$trigger_name" + json_select .. + + json_select .. +} + +ucidef_set_led_usbdev() { + local dev="$4" + + _ucidef_set_led_common "$1" "$2" "$3" + + json_add_string type usb + json_add_string device "$dev" + json_select .. + + json_select .. +} + +ucidef_set_led_usbhost() { + _ucidef_set_led_trigger "$1" "$2" "$3" usb-host +} + +ucidef_set_led_usbport() { + local obj="$1" + local name="$2" + local sysfs="$3" + shift + shift + shift + + _ucidef_set_led_common "$obj" "$name" "$sysfs" + + json_add_string type usbport + json_select_array ports + for port in "$@"; do + json_add_string port "$port" + done + json_select .. + json_select .. + + json_select .. +} + +ucidef_set_led_wlan() { + _ucidef_set_led_trigger "$1" "$2" "$3" "$4" +} + +ucidef_set_rssimon() { + local dev="$1" + local refresh="$2" + local threshold="$3" + + json_select_object rssimon + + json_select_object "$dev" + [ -n "$refresh" ] && json_add_int refresh "$refresh" + [ -n "$threshold" ] && json_add_int threshold "$threshold" + json_select .. + + json_select .. +} + +ucidef_add_gpio_switch() { + local cfg="$1" + local name="$2" + local pin="$3" + local default="${4:-0}" + + json_select_object gpioswitch + json_select_object "$cfg" + json_add_string name "$name" + json_add_int pin "$pin" + json_add_int default "$default" + json_select .. + json_select .. +} + +ucidef_set_hostname() { + local hostname="$1" + + json_select_object system + json_add_string hostname "$hostname" + json_select .. +} + +ucidef_set_ntpserver() { + local server + + json_select_object system + json_select_array ntpserver + for server in "$@"; do + json_add_string "" "$server" + done + json_select .. + json_select .. +} + +board_config_update() { + json_init + [ -f ${CFG} ] && json_load "$(cat ${CFG})" + + # auto-initialize model id and name if applicable + if ! json_is_a model object; then + json_select_object model + [ -f "/tmp/sysinfo/board_name" ] && \ + json_add_string id "$(cat /tmp/sysinfo/board_name)" + [ -f "/tmp/sysinfo/model" ] && \ + json_add_string name "$(cat /tmp/sysinfo/model)" + json_select .. + fi +} + +board_config_flush() { + json_dump -i -o ${CFG} +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/preinit/82_modem_power b/6.1/target/linux/ipq40xx/base-files/lib/preinit/82_modem_power new file mode 100644 index 00000000..2d77ee72 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/preinit/82_modem_power @@ -0,0 +1,20 @@ +set_state() { + local label="$1" + local disable + + [ -e "/sys/class/gpio/${label}_power/value" ] || return + + config_get disable ${label} disable + [ "${disable}" -eq 1 ] && \ + /sbin/mctl -s -m "${label}" || \ + /sbin/mctl -p -m "${label}" +} + +do_power_modem() { + /sbin/mctl -p || { + config_load system + config_foreach set_state mctl + } +} + +boot_hook_add preinit_main do_power_modem diff --git a/6.1/target/linux/ipq40xx/base-files/lib/upgrade/ipq_failsafe.sh b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/ipq_failsafe.sh new file mode 100644 index 00000000..dc59c6f9 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/ipq_failsafe.sh @@ -0,0 +1,383 @@ +find_mmc_part() { + local DEVNAME PARTNAME + + if grep -q "$1" /proc/mtd; then + echo "" && return 0 + fi + + for DEVNAME in /sys/block/mmcblk0/mmcblk*p*; do + PARTNAME=$(grep PARTNAME ${DEVNAME}/uevent | cut -f2 -d'=') + [ "$PARTNAME" = "$1" ] && echo "/dev/$(basename $DEVNAME)" && return 0 + done +} + +get_full_section_name() { + local img=$1 + local sec=$2 + + dumpimage -l ${img} | grep "^ Image.*(${sec})" | \ + sed 's,^ Image.*(\(.*\)),\1,' +} + +image_contains() { + local img=$1 + local sec=$2 + dumpimage -l ${img} | grep -q "^ Image.*(${sec}.*)" || return 1 +} + +print_sections() { + local img=$1 + + dumpimage -l ${img} | awk '/^ Image.*(.*)/ { print gensub(/Image .* \((.*)\)/,"\\1", $0) }' +} + +image_has_mandatory_section() { + local img=$1 + local mandatory_sections=$2 + + for sec in ${mandatory_sections}; do + image_contains $img ${sec} || {\ + return 1 + } + done +} + +image_demux() { + local img=$1 + + for sec in $(print_sections ${img}); do + local fullname=$(get_full_section_name ${img} ${sec}) + + local position=$(dumpimage -l ${img} | grep "(${fullname})" | awk '{print $2}') + dumpimage -i ${img} -o /tmp/${fullname}.bin -T "flat_dt" -p "${position}" ${fullname} > /dev/null || { \ + echo "Error while extracting \"${sec}\" from ${img}" + return 1 + } + done + return 0 +} + +image_is_FIT() { + if ! dumpimage -l $1 > /dev/null 2>&1; then + echo "$1 is not a valid FIT image" + return 1 + fi + return 0 +} + +switch_layout() { + local layout=$1 + local boot_layout=`find / -name boot_layout` + + # Layout switching is only required as the boot images (up to u-boot) + # use 512 user data bytes per code word, whereas Linux uses 516 bytes. + # It's only applicable for NAND flash. So let's return if we don't have + # one. + + [ -n "$boot_layout" ] || return + + case "${layout}" in + boot|1) echo 1 > $boot_layout;; + linux|0) echo 0 > $boot_layout;; + *) echo "Unknown layout \"${layout}\"";; + esac +} + +do_flash_mtd() { + local bin=$1 + local mtdname=$2 + local append="" + + local mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}') + local pgsz=$(cat /sys/class/mtd/${mtdpart}/writesize) + [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 -a "$2" == "rootfs" ] && append="-j $CONF_TAR" + + dd if=/tmp/${bin}.bin bs=${pgsz} conv=sync | mtd $append -e "/dev/${mtdpart}" write - "/dev/${mtdpart}" +} + +do_flash_emmc() { + local bin=$1 + local emmcblock=$2 + + dd if=/dev/zero of=${emmcblock} + dd if=/tmp/${bin}.bin of=${emmcblock} +} + +do_flash_partition() { + local bin=$1 + local mtdname=$2 + local emmcblock="$(find_mmc_part "$mtdname")" + + if [ -e "$emmcblock" ]; then + do_flash_emmc $bin $emmcblock + else + do_flash_mtd $bin $mtdname + fi +} + +do_flash_bootconfig() { + local bin=$1 + local mtdname=$2 + + # Fail safe upgrade + if [ -f /proc/boot_info/getbinary_${bin} ]; then + cat /proc/boot_info/getbinary_${bin} > /tmp/${bin}.bin + do_flash_partition $bin $mtdname + fi +} + +do_flash_failsafe_partition() { + local bin=$1 + local mtdname=$2 + local emmcblock + local primaryboot + + # Fail safe upgrade + [ -f /proc/boot_info/$mtdname/upgradepartition ] && { + default_mtd=$mtdname + mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition) + primaryboot=$(cat /proc/boot_info/$default_mtd/primaryboot) + if [ $primaryboot -eq 0 ]; then + echo 1 > /proc/boot_info/$default_mtd/primaryboot + else + echo 0 > /proc/boot_info/$default_mtd/primaryboot + fi + } + + emmcblock="$(find_mmc_part "$mtdname")" + + if [ -e "$emmcblock" ]; then + do_flash_emmc $bin $emmcblock + else + do_flash_mtd $bin $mtdname + fi + +} + +do_flash_ubi() { + local bin=$1 + local mtdname=$2 + local mtdpart + local primaryboot + + mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}') + ubidetach -p /dev/${mtdpart} + + # Fail safe upgrade + [ -f /proc/boot_info/$mtdname/upgradepartition ] && { + primaryboot=$(cat /proc/boot_info/$mtdname/primaryboot) + if [ $primaryboot -eq 0 ]; then + echo 1 > /proc/boot_info/$mtdname/primaryboot + else + echo 0 > /proc/boot_info/$mtdname/primaryboot + fi + + mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition) + } + + mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}') + ubiformat /dev/${mtdpart} -y -f /tmp/${bin}.bin +} + +do_flash_tz() { + local sec=$1 + local mtdpart=$(grep "\"0:QSEE\"" /proc/mtd | awk -F: '{print $1}') + local emmcblock="$(find_mmc_part "0:QSEE")" + + if [ -n "$mtdpart" -o -e "$emmcblock" ]; then + do_flash_failsafe_partition ${sec} "0:QSEE" + else + do_flash_failsafe_partition ${sec} "0:TZ" + fi +} + +do_flash_ddr() { + local sec=$1 + local mtdpart=$(grep "\"0:CDT\"" /proc/mtd | awk -F: '{print $1}') + local emmcblock="$(find_mmc_part "0:CDT")" + + if [ -n "$mtdpart" -o -e "$emmcblock" ]; then + do_flash_failsafe_partition ${sec} "0:CDT" + else + do_flash_failsafe_partition ${sec} "0:DDRPARAMS" + fi +} + +to_upper () { + echo $1 | awk '{print toupper($0)}' +} + +flash_section() { + local sec=$1 + + local board=$(board_name) + case "${sec}" in + hlos*) switch_layout linux; do_flash_failsafe_partition ${sec} "0:HLOS";; + rootfs*) switch_layout linux; do_flash_failsafe_partition ${sec} "rootfs";; + fs*) switch_layout linux; do_flash_failsafe_partition ${sec} "rootfs";; + ubi*) switch_layout linux; do_flash_ubi ${sec} "rootfs";; + #sbl1*) switch_layout boot; do_flash_partition ${sec} "0:SBL1";; + #sbl2*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:SBL2";; + #sbl3*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:SBL3";; + #mibib*) switch_layout boot; do_flash_partition ${sec} "0:MIBIB";; + #dtb-$(to_upper $board)*) switch_layout boot; do_flash_partition ${sec} "0:DTB";; + u-boot*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:APPSBL";; + #ddr-$(to_upper $board)*) switch_layout boot; do_flash_ddr ${sec};; + ddr-${board}-*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:CDT";; + #ssd*) switch_layout boot; do_flash_partition ${sec} "0:SSD";; + tz*) switch_layout boot; do_flash_tz ${sec};; + #rpm*) switch_layout boot; do_flash_failsafe_partition ${sec} "0:RPM";; + *) echo "Section ${sec} ignored"; return 1;; + esac + + echo "Flashed ${sec}" +} + +erase_emmc_config() { + local emmcblock="$(find_mmc_part "rootfs_data")" + if [ -e "$emmcblock" ]; then + dd if=/dev/zero of=${emmcblock} + mkfs.ext4 "$emmcblock" + fi +} + +platform_pre_upgrade() { + cp /sbin/upgraded /tmp + ubus call system nandupgrade "{\"path\": \"$1\" }" +} + +platform_check_image_ipq() { + local board=$(board_name) + + local mandatory_nand="ubi" + local mandatory_nor_emmc="hlos fs" + local mandatory_nor="hlos" + local mandatory_section_found=0 + local optional="sbl2 u-boot ddr-${board} ssd tz rpm" + local ignored="mibib bootconfig sbl1" + + image_is_FIT $1 || return 1 + + image_has_mandatory_section $1 ${mandatory_nand} && {\ + mandatory_section_found=1 + } + + image_has_mandatory_section $1 ${mandatory_nor_emmc} && {\ + mandatory_section_found=1 + } + + image_has_mandatory_section $1 ${mandatory_nor} && {\ + mandatory_section_found=1 + } + + if [ $mandatory_section_found -eq 0 ]; then + echo "Error: mandatory section(s) missing from \"$1\". Abort..." + return 1 + fi + + for sec in ${optional}; do + image_contains $1 ${sec} || {\ + echo "Warning: optional section \"${sec}\" missing from \"$1\". Continue..." + } + done + + for sec in ${ignored}; do + image_contains $1 ${sec} && {\ + echo "Warning: section \"${sec}\" will be ignored from \"$1\". Continue..." + } + done + + image_demux $1 || {\ + echo "Error: \"$1\" couldn't be extracted. Abort..." + return 1 + } + + [ -f /tmp/hlos_version ] && rm -f /tmp/*_version + dumpimage -c $1 2>/dev/null + return $? +} + +platform_version_upgrade() { + local version_files="appsbl_version sbl_version tz_version hlos_version rpm_version" + local sys="/sys/devices/system/qfprom/qfprom0/" + local tmp="/tmp/" + + for file in $version_files; do + [ -f "${tmp}${file}" ] && { + echo "Updating "${sys}${file}" with `cat "${tmp}${file}"`" + echo `cat "${tmp}${file}"` > "${sys}${file}" + rm -f "${tmp}${file}" + } + done +} + + +# The U-Boot loader of the OpenMesh devices requires image sizes and +# checksums to be provided in the U-Boot environment. +# The OpenMesh devices come with 2 main partitions - while one is active +# sysupgrade will flash the other. The boot order is changed to boot the +# newly flashed partition. If the new partition can't be booted due to +# upgrade failures the previously used partition is loaded. + +platform_do_upgrade_ipq() { + local board=$(board_name) + + # verify some things exist before erasing + if [ ! -e $1 ]; then + echo "Error: Can't find $1 after switching to ramfs, aborting upgrade!" + reboot + fi + + for sec in $(print_sections $1); do + if [ ! -e /tmp/${sec}.bin ]; then + echo "Error: Cant' find ${sec} after switching to ramfs, aborting upgrade!" + reboot + fi + done + + case "$board" in + teltonika,rutx) + for sec in $(print_sections $1); do + flash_section ${sec} + done + + switch_layout linux + # update bootconfig to register that fw upgrade has been done + do_flash_bootconfig bootconfig "0:BOOTCONFIG" + do_flash_bootconfig bootconfig1 "0:BOOTCONFIG1" + platform_version_upgrade + + erase_emmc_config + return 0; + ;; + esac + + echo "Upgrade failed!" + return 1; +} + +platform_copy_config_ipq() { + local emmcblock="$(find_mmc_part "rootfs_data")" + mkdir -p /tmp/overlay + + if [ -e "$emmcblock" ]; then + mount -t ext4 "$emmcblock" /tmp/overlay + cp /tmp/sysupgrade.tgz /tmp/overlay/ + sync + umount /tmp/overlay + else + local mtdname=rootfs + local mtdpart + + [ -f /proc/boot_info/$mtdname/upgradepartition ] && { + mtdname=$(cat /proc/boot_info/$mtdname/upgradepartition) + } + + mtdpart=$(grep "\"${mtdname}\"" /proc/mtd | awk -F: '{print $1}') + ubiattach -p /dev/${mtdpart} + mount -t ubifs ubi0:rootfs_data /tmp/overlay + cp /tmp/sysupgrade.tgz /tmp/overlay/ + sync + umount /tmp/overlay + fi +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 00000000..a7fc337d --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,216 @@ +PART_NAME=firmware +REQUIRE_IMAGE_METADATA=1 + +RAMFS_COPY_BIN='fw_printenv fw_setenv' +RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' + +platform_check_image() { + case "$(board_name)" in + asus,rt-ac42u |\ + asus,rt-ac58u) + local ubidev=$(nand_find_ubi $CI_UBIPART) + local asus_root=$(nand_find_volume $ubidev jffs2) + + [ -n "$asus_root" ] || return 0 + + cat << EOF +jffs2 partition is still present. +There's probably no space left +to install the filesystem. + +You need to delete the jffs2 partition first: +# ubirmvol /dev/ubi0 --name=jffs2 + +Once this is done. Retry. +EOF + return 1 + ;; + teltonika,rutx) + platform_check_image_ipq "$1" + ;; + zte,mf286d) + CI_UBIPART="rootfs" + local mtdnum="$( find_mtd_index $CI_UBIPART )" + [ ! "$mtdnum" ] && return 1 + ubiattach -m "$mtdnum" || true + local ubidev="$( nand_find_ubi $CI_UBIPART )" + local ubi_rootfs=$(nand_find_volume $ubidev ubi_rootfs) + local ubi_rootfs_data=$(nand_find_volume $ubidev ubi_rootfs_data) + + [ -n "$ubi_rootfs" ] || [ -n "$ubi_rootfs_data" ] || return 0 + + cat << EOF +ubi_rootfs partition is still present. + +You need to delete the stock partition first: +# ubirmvol /dev/ubi0 -N ubi_rootfs +Please also delete ubi_rootfs_data, if exist: +# ubirmvol /dev/ubi0 -N ubi_rootfs_data + +Once this is done. Retry. +EOF + return 1 + ;; + esac + return 0; +} + +askey_do_upgrade() { + local tar_file="$1" + + local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + + tar Oxf $tar_file ${board_dir}/root | mtd write - rootfs + + nand_do_upgrade "$1" +} + +zyxel_do_upgrade() { + local tar_file="$1" + + local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + + tar Oxf $tar_file ${board_dir}/kernel | mtd write - kernel + + if [ -n "$UPGRADE_BACKUP" ]; then + tar Oxf $tar_file ${board_dir}/root | mtd -j "$UPGRADE_BACKUP" write - rootfs + else + tar Oxf $tar_file ${board_dir}/root | mtd write - rootfs + fi +} + +platform_do_upgrade_mikrotik_nand() { + local fw_mtd=$(find_mtd_part kernel) + fw_mtd="${fw_mtd/block/}" + [ -n "$fw_mtd" ] || return + + local board_dir=$(tar tf "$1" | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + [ -n "$board_dir" ] || return + + local kernel_len=$(tar xf "$1" ${board_dir}/kernel -O | wc -c) + [ -n "$kernel_len" ] || return + + tar xf "$1" ${board_dir}/kernel -O | ubiformat "$fw_mtd" -y -S $kernel_len -f - + + CI_KERNPART="none" + nand_do_upgrade "$1" +} + +platform_do_upgrade() { + case "$(board_name)" in + 8dev,jalapeno |\ + aruba,ap-303 |\ + aruba,ap-303h |\ + aruba,ap-365 |\ + avm,fritzbox-7530 |\ + avm,fritzrepeater-1200 |\ + avm,fritzrepeater-3000 |\ + buffalo,wtr-m2133hp |\ + cilab,meshpoint-one |\ + edgecore,ecw5211 |\ + edgecore,oap100 |\ + engenius,eap2200 |\ + glinet,gl-ap1300 |\ + luma,wrtq-329acn |\ + mobipromo,cm520-79f |\ + netgear,wac510 |\ + p2w,r619ac-64m |\ + p2w,r619ac-128m |\ + qxwlan,e2600ac-c2) + nand_do_upgrade "$1" + ;; + glinet,gl-b2200) + CI_KERNPART="0:HLOS" + CI_ROOTPART="rootfs" + CI_DATAPART="rootfs_data" + emmc_do_upgrade "$1" + ;; + alfa-network,ap120c-ac) + part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')" + if [ "$part" = "rootfs1" ]; then + fw_setenv active 2 || exit 1 + CI_UBIPART="rootfs2" + else + fw_setenv active 1 || exit 1 + CI_UBIPART="rootfs1" + fi + nand_do_upgrade "$1" + ;; + asus,map-ac2200) + CI_KERNPART="linux" + nand_do_upgrade "$1" + ;; + asus,rt-ac42u |\ + asus,rt-ac58u) + CI_KERNPART="linux" + nand_do_upgrade "$1" + ;; + cellc,rtl30vw) + CI_UBIPART="ubifs" + askey_do_upgrade "$1" + ;; + compex,wpj419) + nand_do_upgrade "$1" + ;; + linksys,ea6350v3 |\ + linksys,ea8300 |\ + linksys,mr8300) + platform_do_upgrade_linksys "$1" + ;; + meraki,mr33) + CI_KERNPART="part.safe" + nand_do_upgrade "$1" + ;; + mikrotik,cap-ac|\ + mikrotik,hap-ac2|\ + mikrotik,lhgg-60ad|\ + mikrotik,sxtsq-5-ac) + [ "$(rootfs_type)" = "tmpfs" ] && mtd erase firmware + default_do_upgrade "$1" + ;; + mikrotik,hap-ac3) + platform_do_upgrade_mikrotik_nand "$1" + ;; + netgear,rbr50 |\ + netgear,rbs50 |\ + netgear,srr60 |\ + netgear,srs60) + platform_do_upgrade_netgear_orbi_upgrade "$1" + ;; + openmesh,a42 |\ + openmesh,a62 |\ + plasmacloud,pa1200 |\ + plasmacloud,pa2200) + PART_NAME="inactive" + platform_do_upgrade_dualboot_datachk "$1" + ;; + teltonika,rutx) + platform_do_upgrade_ipq "$1" + ;; + zte,mf286d) + CI_UBIPART="rootfs" + nand_do_upgrade "$1" + ;; + zyxel,nbg6617) + zyxel_do_upgrade "$1" + ;; + *) + default_do_upgrade "$1" + ;; + esac +} + +platform_copy_config() { + case "$(board_name)" in + glinet,gl-b2200) + emmc_copy_config + ;; + teltonika,rutx) + platform_copy_config_ipq + ;; + esac + return 0; +} diff --git a/6.1/target/linux/ipq40xx/base-files/lib/upgrade/stage2 b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/stage2 new file mode 100755 index 00000000..93792413 --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/lib/upgrade/stage2 @@ -0,0 +1,138 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/system.sh + +export IMAGE="$1" +COMMAND="$2" + +export INTERACTIVE=0 +export VERBOSE=1 +export CONFFILES=/tmp/sysupgrade.conffiles + +RAMFS_COPY_BIN= # extra programs for temporary ramfs root +RAMFS_COPY_DATA= # extra data files + +include /lib/upgrade + + +supivot() { # + /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1 + mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \ + /bin/mount -o noatime,move /proc $1/proc && \ + pivot_root $1 $1$2 || { + /bin/umount -l $1 $1 + return 1 + } + + /bin/mount -o noatime,move $2/sys /sys + /bin/mount -o noatime,move $2/dev /dev + /bin/mount -o noatime,move $2/tmp /tmp + /bin/mount -o noatime,move $2/overlay /overlay 2>&- + return 0 +} + +switch_to_ramfs() { + for binary in \ + /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \ + pivot_root mount_root reboot sync kill sleep \ + md5sum hexdump cat zcat bzcat dd tar \ + ls basename find cp mv rm mkdir rmdir mknod touch chmod \ + '[' printf wc grep awk sed cut \ + mtd partx losetup mkfs.ext4 nandwrite flash_erase \ + ubiupdatevol ubiattach ubiblock ubiformat \ + ubidetach ubirsvol ubirmvol ubimkvol \ + snapshot snapshot_tool date \ + dumpimage $RAMFS_COPY_BIN + do + local file="$(command -v "$binary" 2>/dev/null)" + [ -n "$file" ] && install_bin "$file" + done + install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh /lib/upgrade/do_stage2 /usr/share/libubox/jshn.sh $RAMFS_COPY_DATA + + [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64 + + supivot $RAM_ROOT /mnt || { + v "Failed to switch over to ramfs. Please reboot." + exit 1 + } + + /bin/mount -o remount,ro /mnt + /bin/umount -l /mnt + + grep /overlay /proc/mounts > /dev/null && { + /bin/mount -o noatime,remount,ro /overlay + /bin/umount -l /overlay + } +} + +kill_remaining() { # [ [ ] ] + local loop_limit=10 + + local sig="${1:-TERM}" + local loop="${2:-0}" + local run=true + local stat + local proc_ppid=$(cut -d' ' -f4 /proc/$$/stat) + + vn "Sending $sig to remaining processes ..." + + while $run; do + run=false + for stat in /proc/[0-9]*/stat; do + [ -f "$stat" ] || continue + + local pid name state ppid rest + read pid name state ppid rest < $stat + name="${name#(}"; name="${name%)}" + + # Skip PID1, our parent, ourself and our children + [ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue + + local cmdline + read cmdline < /proc/$pid/cmdline + + # Skip kernel threads + [ -n "$cmdline" ] || continue + + _vn " $name" + kill -$sig $pid 2>/dev/null + + [ $loop -eq 1 ] && run=true + done + + let loop_limit-- + [ $loop_limit -eq 0 ] && { + _v + v "Failed to kill all processes." + exit 1 + } + done + _v +} + +indicate_upgrade + +killall -9 telnetd +killall -9 dropbear +killall -9 ash + +kill_remaining TERM +sleep 3 +kill_remaining KILL 1 + +sleep 1 + +echo 3 > /proc/sys/vm/drop_caches + +if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then + platform_pre_upgrade "$IMAGE" +fi + +if [ -n "$(rootfs_type)" ]; then + v "Switching to ramdisk..." + switch_to_ramfs +fi + +# Exec new shell from ramfs +exec /bin/busybox ash -c "$COMMAND" diff --git a/6.1/target/linux/ipq40xx/base-files/sbin/mctl b/6.1/target/linux/ipq40xx/base-files/sbin/mctl new file mode 100755 index 00000000..f501cc2e --- /dev/null +++ b/6.1/target/linux/ipq40xx/base-files/sbin/mctl @@ -0,0 +1,120 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +PS_ON=1 +PS_OFF=2 + +MPS=0 +MLBL="modem" + +modem_reset() { + local label="$1" + + [ -e "/sys/class/gpio/${label}_reset/value" ] || return + + echo 1 > "/sys/class/gpio/${label}_reset/value" + sleep 1 + echo 0 > "/sys/class/gpio/${label}_reset/value" +} + +modem_off() { + local label="$1" + + [ -e "/sys/class/gpio/${label}_reset/value" ] || return + + echo 1 > "/sys/class/gpio/${label}_reset/value" +} + +modem_power() { + local label="$1" + + [ -e "/sys/class/gpio/${label}_power/value" ] || return + + # simulate power press + echo 1 > "/sys/class/gpio/${label}_power/value" + sleep 1 + echo 0 > "/sys/class/gpio/${label}_power/value" +} + +modem_list() { + local list="modem" + local label + + [ "$(modem_fetch_primary)" -eq 0 ] && { + echo "${list}" + return + } + + for m in /sys/class/gpio/modem*_power; do + label="$(basename $m | awk -F_ '{print $1}')" + [ "${label}" != "modem" ] && list="${list},${label}" + done + + echo "${list}" +} + +modem_fetch_primary() { + local modem modems primary + + json_init + json_load_file "/etc/board.json" + + json_get_keys modems modems + json_select modems + + for modem in $modems; do + json_select "$modem" + json_get_vars primary + + [ -n "$primary" ] && { + echo 1 + return + } + + json_select .. + done + echo 0 +} + +modem_is_available() { + local label="$1" + [ -e "/sys/class/gpio/${label}_power/value" ] +} + +usage() { + cat < +Control modem power state. + +Options: + -p, --power-on power on modem + -s, --shutdown shutdown modem + -r, --reboot reboot modem + -m, --modem