#!/bin/sh /etc/rc.common # we must run after S95done because jffs2 overlay must be ready for writing to /lib/firmware/plc START=96 STOP=10 USE_PROCD=1 if [ -f /lib/ar71xx.sh ]; then PLATFORM=ar71xx . /lib/ar71xx.sh elif [ -f /lib/ipq806x.sh ]; then PLATFORM=ipq806x . /lib/ipq806x.sh fi board=$(${PLATFORM}_board_name) . /lib/functions/system.sh . /lib/functions/leds.sh . /lib/firmware/plc/$board/fwconfig config_load plc config_get PLCIF plc interface 'br-lan' config_get INMK plc individual_nmk '0' config_get LED_SCHEME plc led_scheme 'on' config_get_bool DISABLED plc disabled '0' config_get_bool STANDBY plc standby '0' config_get COMPAT_MODE plc compat_mode config_get USER_NOTCHES plc user_notches [ -e /lib/dlan/baptization.sh ] && . /lib/dlan/baptization.sh [ -x /usr/sbin/plc-standby ] || STANDBY=0 logger() { command logger -t plc "$@" } set_ebtables() { reset_ebtables local PIB=/lib/firmware/plc/user.pib dlan_mac=$(getpib "$PIB" 0xC mac) while [ ! -d /sys/class/net/$PLCIF ]; do logger "Waiting for /sys/class/net/$PLCIF to appear..." sleep 1 done eth_mac=$(cat /sys/class/net/$PLCIF/address) ebtables -t broute -N plc -P RETURN ebtables -t broute -I BROUTING -p 0x88e1 -j plc ebtables -t broute -A plc -s 00:B0:52:00:00:01 -j DROP ebtables -t broute -A plc -s $dlan_mac -d Broadcast -j DROP ebtables -t broute -A plc -d $eth_mac -j DROP } reset_ebtables() { ebtables -t broute -D BROUTING -p 0x88e1 -j plc 2>/dev/null ebtables -t broute -X plc 2>/dev/null } set_dak() { local dak="$DlanDAK" if [ -n "$dak" ] ; then /usr/bin/modpib -D "$dak" "$1" || logger "Writing DAK to PIB failed" fi } update_dak() { local dak="$DlanDAK" if [ -z "$dak" ] ; then if [ ! -f $PLCFW_PATH/security-id ] ; then { tr -dc a-zA-Z $PLCFW_PATH/security-id; } 2>/dev/null fi local sid=$(head -n 1 $PLCFW_PATH/security-id) local dak=$(hpavkey -D $sid) if [ ! -f $PLCFW_PATH/dak ] || [ $(cat $PLCFW_PATH/dak) != $dak ] ; then echo $dak >$PLCFW_PATH/dak fi if [ "$(chkpib -v "$1" | sed -n '/DAK/s,:,,gp' | awk '{ print $2 }')" != "$dak" ]; then /usr/bin/modpib -D "$dak" "$1" || logger "Writing DAK to PIB failed" fi fi } set_nmk() { /usr/bin/modpib -N "$2" "$1" } set_individual_nmk() { local sid="$DlanDevicePassword" [ -z "$sid" ] && return 1 local prefix="lqaS0JTUC1FWY6OVivVsRqL57H6MjSom" local suffix="8cxJaMHJqsR9yug2fLTbqqVxuGw3OLfg" local nmk=$(echo -n "${prefix}${sid}${suffix}" |md5sum |sed s/../\&:/g | cut -c-47) set_nmk "$1" "$nmk" } set_mac_address() { local plc_mac="$DlanMacAddress" if [ -z "$plc_mac" ] ; then local base_mac=$(mtd_get_mac_binary art 4098 2>/dev/null) if [ "$board" = "dlan-pro-1200-n" ]; then plc_mac=$(macaddr_add $base_mac 2) else plc_mac=$(macaddr_add $base_mac 3) fi fi if [ -n "$plc_mac" ] ; then /usr/bin/modpib -M $(macaddr_canonicalize $plc_mac) "$1" fi } set_hostname() { modpib -U "$(uci_get system @system[0] hostname)" "$1" } ### compat_mode make_patch_file_name() { echo "${PLCFW_PATH}/${board}/patches_mt${1}_${2}.txt" } make_reset_patch_file_name() { echo "${PLCFW_PATH}/${board}/reset_patch_mt${1}.txt" } apply_patch_file() { local pib_file="$1" local patch_file="$2" logger "Applying compat mode patch file: $patch_file" [ -f "$patch_file" ] || { logger "Error: Patch file not found"; return; } # TODO: move copy+pasted patch file parsing (from build scripts) into common file while IFS='' read -r line; do local offset=$(echo "$line" | cut -d' ' -f1 | grep -E '^0x[0-9a-fA-F]+$') local data=$(echo "$line" | cut -d' ' -f2 | grep -E '^0x[0-9a-fA-F]+$' | sed -e 's/^0x//') if [ -z "$offset" ] || [ -z "$data" ]; then [ -z "$line" ] || logger "Malformed line: '$line'" continue fi logger "Patching offset: $offset" setpib "$pib_file" "$offset" data "$data" done < "$patch_file" } apply_compat_mode() { local pib_file="$1" local patch_file_reset=$(make_reset_patch_file_name "$MT") apply_patch_file "$pib_file" "$patch_file_reset" if [ -n "$COMPAT_MODE" ]; then local patch_file_selected=$(make_patch_file_name "$MT" "$COMPAT_MODE") apply_patch_file "$pib_file" "$patch_file_selected" fi } ### user_notches CHIPCLASS=$(basename "$PLCFW_PIB" | sed -e 's/-.*//') case "$CHIPCLASS" in qca7500) CARRIER_MIN=0 CARRIER_MAX=2689 CARRIER_OFFSET_PRI=5480 CARRIER_OFFSET_ALT=6948 ;; qca7420) CARRIER_MIN=0 CARRIER_MAX=2689 CARRIER_OFFSET_PRI=4840 CARRIER_OFFSET_ALT="" ;; *) CARRIER_MIN="" CARRIER_MAX="" CARRIER_OFFSET_PRI="" CARRIER_OFFSET_ALT="" ;; esac write_zeros_to_file() { local filename="$1" local ofs="$2" local len="$3" dd if=/dev/zero of="$filename" conv=notrunc bs=1 seek="$ofs" count="$len" } apply_notch_range_to_pib() { local pib_file="$1" local carr_s="$2" local carr_e="$3" if [ "$CHIPCLASS" = "qca7500" ] || [ "$CHIPCLASS" = "qca7420" ]; then carr_s=$(( $carr_s / 2 )) carr_e=$(( $carr_e / 2 )) fi local len=$(( $carr_e - $carr_s + 1 )) if [ -n "$CARRIER_OFFSET_PRI" ]; then write_zeros_to_file "$pib_file" $(( $CARRIER_OFFSET_PRI + $carr_s )) "$len" fi if [ -n "$CARRIER_OFFSET_ALT" ]; then write_zeros_to_file "$pib_file" $(( $CARRIER_OFFSET_ALT + $carr_s )) "$len" fi } notch_freq_to_carrier() { local freq="$1" echo $(awk "BEGIN { print int($freq * 0.04096 - 73.5) }") } apply_notch_range() { local pib_file="$1" local freq_s="$2" local freq_e="$3" [ "$freq_s" -le "$freq_e" ] || return local carr_s=$(notch_freq_to_carrier "$freq_s") local carr_e=$(notch_freq_to_carrier "$freq_e") carr_s=$(( $carr_s - 3 )) carr_e=$(( $carr_e + 3 )) [ "$carr_s" -gt "$CARRIER_MAX" ] && return [ "$carr_e" -lt "$CARRIER_MIN" ] && return [ "$carr_s" -lt "$CARRIER_MIN" ] && carr_s="$CARRIER_MIN" [ "$carr_e" -gt "$CARRIER_MAX" ] && carr_e="$CARRIER_MAX" logger "Applying notch range: carriers ${carr_s}-${carr_e}" apply_notch_range_to_pib "$pib_file" "$carr_s" "$carr_e" } apply_user_notches() { local pib_file="$1" logger "Applying user notches" local range for range in $(echo "$USER_NOTCHES" | tr "," "\n"); do local freq_s=$(echo "$range" | cut -d '-' -f 1) local freq_e=$(echo "$range" | cut -d '-' -f 2) apply_notch_range "$pib_file" "$freq_s" "$freq_e" done } ### set_user_pib() { if [ ! -f "$PLCFW_PATH/user.pib" ] ; then eval cp "\"$PLCFW_PATH/\${PLCFW_PIB_$MT:-$PLCFW_PIB}\"" /tmp/user.pib setpib /tmp/user.pib 6 word 0 set_dak /tmp/user.pib set_mac_address /tmp/user.pib set_hostname /tmp/user.pib [ -e /tmp/lh_nmk ] && . /tmp/lh_nmk && rm -f /tmp/lh_nmk if [ -n "$LH_NMK" ]; then set_nmk /tmp/user.pib "$LH_NMK" elif [ "$INMK" -eq 1 ]; then set_individual_nmk /tmp/user.pib fi mv /tmp/user.pib "$PLCFW_PATH" fi update_dak "$PLCFW_PATH/user.pib" cp -f "$PLCFW_PATH/user.pib" /tmp apply_compat_mode /tmp/user.pib apply_user_notches /tmp/user.pib mv -f /tmp/user.pib "$PLCFW_PATH" } do_gpios() { case "$board" in dlan-hotspot) echo 1 > /sys/class/gpio/gpio18/value echo 1 > /sys/class/gpio/gpio22/value sleep 1 echo 1 > /sys/class/gpio/gpio20/value ;; dlan-pro-500-wp) echo 1 > /sys/class/gpio/gpio17/value echo 1 > /sys/class/gpio/gpio13/value ;; dlan-550-wifi) echo 1 > /sys/class/gpio/gpio16/value ;; dlan-1000-ac) echo 1 > /sys/class/gpio/gpio2/value led_set_attr "devolo:status:dlan" inverted 1 ;; dlan-pro-1200-ac|\ dlan-pro-1200-n) echo 1 > /sys/class/gpio/gpio13/value led_set_attr "devolo:status:dlan" inverted 1 ;; devolo-home-control-cu) echo 1 > /sys/class/gpio/gpio19/value return ;; esac sleep 1 } get_pib_field() { ( chkpib -v "$1" | grep "$2 " | cut -d ' ' -f 2- ) 2>/dev/null } SERVICE_PID_FILE="/var/run/plchost.pid" PLC_CONFIG_FILE="/tmp/plc.conf" PLC_RUNTIME_FILE="/etc/plc/runtime" activate() { if chkpib -q "$PLCFW_PATH/user.pib.tmp" ; then mv "$PLCFW_PATH/user.pib.tmp" "$PLCFW_PATH/user.pib" fi PIB="$PLCFW_PATH/user.pib" if [ -f "$PLCFW_PATH/user.nvm.tmp" ] && [ -s "$PLCFW_PATH/user.nvm.tmp" ] ; then mv "$PLCFW_PATH/user.nvm.tmp" "$PLCFW_PATH/user.nvm" fi NVM="$PLCFW_PATH/user.nvm" if [ ! -s "$NVM" ] ; then NVM="$PLCFW_PATH/$PLCFW_NVM" fi # last minute changes to user pib before using it local changed= cp "$PIB" /tmp/user.pib # LED scheme [ -n "$LED_SCHEME" ] && [ -x "$PLCFW_SCHEMES/led_scheme_$LED_SCHEME" ] && { "$PLCFW_SCHEMES/led_scheme_$LED_SCHEME" /tmp/user.pib changed=1 } [ -n "$changed" ] && { mv /tmp/user.pib "$PIB.tmp" mv "$PIB.tmp" "$PIB" } [ -f "$NVM" ] && { logger "activate PLC Modem" logger "Firmware:" $NVM "Pib:" $PIB do_gpios procd_open_instance config_load wifi_son config_get SON_ENABLED son enabled '0' config_get IEEE19051 confsync ieee19051 '0' # run ***host - if it terminates try to save user.pib.tmp if it checks out if [ $SON_ENABLED = "1" ] && [ $IEEE19051 = "1" ]; then logger "PLC Modem: SON Enabled" plc_add_basic_config_plchost_son if [ ! -f "/lib/firmware/plc/7500/mac-release-X.nvm" ]; then mkdir -p "/lib/firmware/plc/7500/" cp -f "$NVM" "/lib/firmware/plc/7500/mac-release-X.nvm" fi procd_set_param command setsid sh -c ' trap "trap - TERM; kill \$CPID; exit" TERM /usr/sbin/plchost-son -c "'"$PLC_CONFIG_FILE"'" & CPID=$! wait $! chkpib -q /lib/firmware/plc/user.pib.tmp && mv /lib/firmware/plc/user.pib.tmp /lib/firmware/plc/user.pib' else logger "PLC Modem: SON Disabled" procd_set_param command setsid sh -c ' trap "trap - TERM; kill \$CPID; exit" TERM "'"$PLCFW_HOST"'" -i "'"$PLCIF"'" -N "'"$NVM"'" -P "'"$PIB"'" -n "'"$PLCFW_PATH/user.nvm.tmp"'" -p "'"$PLCFW_PATH/user.pib.tmp"'" & CPID=$! wait $! chkpib -q /lib/firmware/plc/user.pib.tmp && mv /lib/firmware/plc/user.pib.tmp /lib/firmware/plc/user.pib' fi procd_set_param respawn 3600 5 0 # output to logd procd_set_param stdout 1 procd_set_param stderr 1 procd_set_param pidfile $SERVICE_PID_FILE procd_close_instance [ $STANDBY = "1" ] && { procd_open_instance procd_set_param command /usr/sbin/plc-standby 600 procd_set_param respawn 3600 5 0 procd_close_instance } } } plc_cfg_append() { echo "$1" >> "$PLC_CONFIG_FILE" } plc_cfg_add_specific_str() { local Cfg="$1" local SubOpt="$2" local UciKey="$3" local DefVal="$4" local Val config_load plc config_get Val $SubOpt "$UciKey" "$DefVal" [ -n "$Val" ] && plc_cfg_append "$Cfg=$Val" } plc_cfg_add_bool() { local cfg="$1" local key="$2" local def="$3" local val config_get_bool val config "$key" "$def" [ -n "$val" ] && plc_cfg_append "$cfg=$val" } plc_cfg_add_nmk() { config_load plc config_get nmkselected config 'NmkSelected' 'true' case "$nmkselected" in true) plc_cfg_add_specific_str 'nmk' 'config' 'Nmk' '50d3e4933f855b7040784df815aa8db7' ;; false) plc_cfg_add_specific_str 'network_passwd' 'config' 'NetworkPassWd' 'HomePlugAV' ;; esac } plc_add_basic_config_plchost_son() { local ExecMode local FwPib_DownloadEn echo "# Config file for plc, automatically created by script" > "$PLC_CONFIG_FILE" echo "[PLC]" >> "$PLC_CONFIG_FILE" # plc_add_basic_config # plc_add_adv_config # plc_add_qos_tos_priority_config # plc_add_qos_vlan_priority_config # plc_add_qos_threshold_config # plc_add_rem_dev_config # plc_add_classifier_config config_load plc config_get plc_ifname config PlcIfname plc_cfg_add_nmk # Setup PLC interface name and bridge name config_get_bool enabled config 'VLANEnabled' '0' if [ "$enabled" == "1" ]; then bridge_ifname="br_lan" fi bridge_ifname=$plc_ifname plc_cfg_append "bridge_ifname=$bridge_ifname" plc_cfg_append "plc_ifname=$plc_ifname" #Below are Board specific information, will get rid of this later plc_cfg_add_specific_str 'aggr_link_rate' 'config' 'AggrLinkRate' '0' plc_cfg_add_specific_str 'fwpib_download' 'config' 'FwPib_Download' '0' plc_cfg_add_specific_str 'mac_addr_delta' 'config' 'MacAddrDelta' '2' plc_cfg_add_specific_str 'run_mode' 'config' 'PlcRunMode' 'HyFi' plc_cfg_add_specific_str 'max_rem_dev' 'config' 'MaxRemoteDevices' '6' plc_cfg_add_specific_str 'topo_disc_timeout' 'config' 'TopoDiscovTimeOut' '60' config_get ExecMode config PlcRunMode 'HyFi' config_get FwPib_DownloadEn config FwPib_Download if [ "$ExecMode" == "HyFi" ] then config_get PibFilepath config PibPath '/lib/firmware/plc/user.pib' if [ ! -f $PibFilepath ]; then # cat /dev/mtdblock5 > /etc/plc/FactoryDefault.pib # Temporary Workaround for REH172: copying factory PIB from file system, as the mtd partition is not ready yet. # SHOULD BE FIXED IN FINAL META!!! if [ "$FwPib_DownloadEn" == "1" ]; then cp $PIB $PibFilepath fi fi plc_cfg_add_specific_str 'pib_path' 'config' 'PibPath' $PibFilepath fi } stop_service() { logger "stop PLC" case "$board" in dlan-hotspot) echo 0 > /sys/class/gpio/gpio20/value ;; dlan-pro-500-wp) echo 0 > /sys/class/gpio/gpio13/value ;; dlan-550-wifi) echo 0 > /sys/class/gpio/gpio16/value ;; dlan-1000-ac) # reinstall normal led trigger potentially messed up by standby ( . /etc/init.d/led && config_load system && load_led led_plcw ) echo 0 > /sys/class/gpio/gpio2/value led_set_attr "devolo:status:dlan" inverted 0 ;; dlan-pro-1200-ac|\ dlan-pro-1200-n) # reinstall normal led trigger potentially messed up by standby ( . /etc/init.d/led && config_load system && load_led led_plcw ) echo 0 > /sys/class/gpio/gpio13/value led_set_attr "devolo:status:dlan" inverted 0 ;; devolo-home-control-cu) echo 0 > /sys/class/gpio/gpio19/value ;; esac reset_ebtables rm -rf "$SERVICE_PID_FILE" } check_plc_config_change() { CONFIG_FILE=$1 config_load plc config_get PLCINTERFACE plc interface 'br-lan' config_get INDIVIDUAL_NMK plc individual_nmk '0' config_get LEDSCHEME plc led_scheme 'on' config_get_bool STANDBY plc standby '0' config_get_bool PLC_DISABLED plc disabled '0' config_get COMPAT_MODE plc compat_mode config_get USER_NOTCHES plc user_notches config_get PLCIFNAME config PlcIfname config_get AGGRLINKRATE config AggrLinkRate config_get_bool PLC_ENABLED config Enabled config_get_bool VLANENABLED config VlanEnabled config_get FWPIB_DOWNLOAD config FwPib_Download local hostname="$(uci_get system @system[0] hostname)" local disabled_led_plcw="$(uci_get system led_plcw disabled 0)" local disabled_led_plcr="$(uci_get system led_plcr disabled 0)" local disabled_button_dLAN="$(uci_get system button_BTN_0 disabled 0)" cat >$CONFIG_FILE <