#!/bin/sh /etc/rc.common USE_PROCD=1 START=99 STOP=01 CONFIGURATION=dcwapd VERBOSE=1 # NOTE: all functions write the result to the $result variable result= get_channelsets() { # default to empty result= channelsets=$(uci show $CONFIGURATION | grep "=channel-set$") for channelset in $channelsets; do channelset=$(echo "$channelset" | sed -rn "s/$CONFIGURATION\.(.*)=.*/\1/p") result="$result $channelset" done if [ $VERBOSE -eq 1 ]; then echo "Channel Sets: $result" 2>&1 | logger fi } # $1 : the channel set name get_channelset_enabled() { # default to disabled result=0 if [ -n "$1" ]; then result=$(uci get $CONFIGURATION."$1".enabled) fi if [ $VERBOSE -eq 1 ]; then echo "Channel Set \"$1\" Enabled: $result" 2>&1 | logger fi } # $1 : the channel set name get_primary_bridge() { result= if [ -n "$1" ]; then result=$(uci get $CONFIGURATION."$1".bridge) fi if [ $VERBOSE -eq 1 ]; then echo "Channel Set \"$1\" Primary Bridge: $result" 2>&1 | logger fi } # $1 : the channel set name get_datachannels() { # default to empty result= if [ -n "$1" ]; then result=$(uci get $CONFIGURATION."$1".data_channels) fi if [ $VERBOSE -eq 1 ]; then echo "Channel Set \"$1\" Data Channels: $result" 2>&1 | logger fi } # $1 : the wlan interface name get_wifi_iface_num() { result= if [ -n "$1" ];then #result=$(echo "$1" | sed -n "s/wlan//p") result=$(echo "$1" | sed -rn "s/wlan([0-9]*).*/\1/p") fi } # $1 : the bridge name get_bridge_network_name() { result= if [ -n "$1" ];then result=$(echo "$1" | sed -n "s/br-//p") fi } # $1 : the wlan interface name set_iface_init_state() { result= if [ -n "$1" ]; then iface=$1 # need to extract the "X" from wlanX get_wifi_iface_num "$iface" iface_num=$result if [ -n "$iface_num" ]; then # get the iface network init_net=$(uci get wireless.@wifi-iface[$iface_num].network) if [ -n "$init_net" ]; then # if the iface network is a bridge, but doesn't start with "br-" # I think we need to prepend it? net_type=$(uci get network."$init_net".type) if [ -n "$net_type" ] && [ "$net_type" = "bridge" ]; then prefix_ok=$(echo "$init_net" | grep "^br-") if [ -z "$prefix_ok" ]; then init_net="br-$init_net" fi fi fi # make sure that the init_net section exists init_net_section=$(uci get dcwapd.init_net) if [ "$init_net_section" != "init_net" ]; then # the section did not exist uci set dcwapd.init_net=init_net fi # save the initial network if [ $VERBOSE -eq 1 ]; then echo "Saving '$iface' initial network '$init_net'" 2>&1 | logger fi uci set $CONFIGURATION.init_net."$iface"="$init_net" uci commit # save the initial network in the result variable result=$init_net fi fi } # $1 : the wlan interface name get_iface_init_state() { result= if [ -n "$1" ];then init_net=$(uci get $CONFIGURATION.init_net."$iface") # if the response starts with "uci: ", it was an error not the real result err=$(echo "$init_net" | grep "^uci: ") if [ -z "$err" ]; then # no error, set the result result=$init_net if [ $VERBOSE -eq 1 ]; then echo "Got '$iface' initial network '$init_net'" 2>&1 | logger fi fi fi } # $1 : the name of the data channel name to bring up datachannel_up() { if [ -n "$1" ]; then bridge=$(uci get $CONFIGURATION."$1".bridge) interfaces=$(uci get $CONFIGURATION."$1".interfaces) if [ $VERBOSE -eq 1 ]; then echo "Creating Data Channel Bridge: $bridge" 2>&1 | logger fi get_bridge_network_name "$bridge" netname=$result if [ -n "$netname" ]; then uci set network."$netname"=interface uci set network."$netname".type=bridge uci set network."$netname".proto=static uci set network."$netname".bridge_empty='1' fi # create the bridge uci commit /etc/init.d/network reload for iface in $interfaces; do # if iface is in a bridge, the bridge name should be stored in result set_iface_init_state "$iface" init_bridge=$result # update uci with the new bridge info get_wifi_iface_num "$iface" iface_num=$result if [ -n "$iface_num" ]; then uci set wireless.@wifi-iface[$iface_num].network="$netname" fi # manually put the interface into the data bridge # if iface is in a bridge, remove it before adding it to the data bridge if [ -n "$init_bridge" ]; then brctl delif "$init_bridge" "$iface" 2>&1 | logger fi brctl addif "$bridge" "$iface" 2>&1 | logger done # commit uci changes and reload the network uci commit /etc/init.d/network reload #/etc/init.d/network restart # while [ 1 ]; do # ifconfig "$bridge" > /dev/null 2>&1 # if [ $? == 0 ]; then # break; # fi # sleep 1 # done fi } # $1 : the name of the data channel to bring down datachannel_down() { if [ -n "$1" ]; then bridge=$(uci get $CONFIGURATION."$1".bridge) interfaces=$(uci get $CONFIGURATION."$1".interfaces) for iface in $interfaces; do if [ $VERBOSE -eq 1 ]; then echo "Deconfiguring Data Channel Interface: $iface" 2>&1 | logger fi # manually remove the interface from the data bridge brctl delif "$bridge" "$iface" 2>&1 | logger get_iface_init_state "$iface" init_bridge=$result if [ -n "$init_bridge" ]; then # manually move the interface back to the original bridge brctl addif "$init_bridge" "$iface" 2>&1 | logger # update uci with the new bridge and interface configuration get_wifi_iface_num "$iface" iface_num=$result get_bridge_network_name "$init_bridge" netname=$result if [ -n "$iface_num" ] && [ -n "$netname" ]; then uci set wireless.@wifi-iface[$iface_num].network="$netname" fi fi done if [ $VERBOSE -eq 1 ]; then echo "Deconfiguring Data Channel Bridge: $bridge" 2>&1 | logger fi # delete the bridge from uci get_bridge_network_name "$bridge" netname=$result if [ -n "$netname" ]; then uci delete network."$netname" fi # commit uci changes and reload the network uci commit /etc/init.d/network reload #`/etc/init.d/network restart` fi } start_service() { config_load "$CONFIGURATION" local enabled config_get enabled general enabled if [ "$enabled" != "1" ]; then echo "dcwapd is disabled in UCI" return 1 fi get_channelsets # get the list of channel sets channelsets=$result for channelset in $channelsets; do if [ -n "$channelset" ]; then get_channelset_enabled "$channelset" enabled=$result if [ "$enabled" = "1" ]; then # the channel set is enabled # get the list of data channels used by the channel set get_datachannels "$channelset" datachannels=$result for datachannel in $datachannels; do datachannel_up "$datachannel" done fi fi done procd_open_instance procd_set_param file /etc/config/dcwapd procd_set_param command dcwapd procd_set_param stdout 1 procd_set_param stderr 1 procd_close_instance } stop_service() { get_channelsets # get the list of channel sets channelsets=$result for channelset in $channelsets; do if [ -n "$channelset" ]; then # we don't care if it is enabled, tear it down # get_channelset_enabled $channelset # enabled=$result # if [ $enabled = "1" ]; then # # the channel set is enabled # get the list of data channels used by the channel set get_datachannels "$channelset" datachannels=$result for datachannel in $datachannels; do datachannel_down "$datachannel" done # fi fi done sleep 1 } service_triggers() { procd_add_reload_trigger dcwapd } reload_service() { stop start }