lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

travelmate.sh (8834B)


      1 #!/bin/sh
      2 # travelmate, a wlan connection manager for travel router
      3 # written by Dirk Brenken (dev@brenken.org)
      4 
      5 # This is free software, licensed under the GNU General Public License v3.
      6 # You should have received a copy of the GNU General Public License
      7 # along with this program. If not, see <http://www.gnu.org/licenses/>.
      8 
      9 # set initial defaults
     10 #
     11 LC_ALL=C
     12 PATH="/usr/sbin:/usr/bin:/sbin:/bin"
     13 trm_ver="0.6.0"
     14 trm_sysver="$(ubus -S call system board | jsonfilter -e '@.release.description')"
     15 trm_enabled=0
     16 trm_debug=0
     17 trm_automatic=0
     18 trm_maxwait=30
     19 trm_maxretry=3
     20 trm_timeout=60
     21 trm_iw=1
     22 
     23 # source required system library
     24 #
     25 if [ -r "/lib/functions.sh" ]
     26 then
     27     . "/lib/functions.sh"
     28 else
     29     f_log "error" "required system library not found"
     30 fi
     31 
     32 # f_envload: load travelmate environment
     33 #
     34 f_envload()
     35 {
     36     # initialize lists
     37     #
     38     trm_aplist=""
     39     trm_stalist=""
     40     trm_radiolist=""
     41 
     42     # load uci config and check 'enabled' option
     43     #
     44     option_cb()
     45     {
     46         local option="${1}"
     47         local value="${2}"
     48         eval "${option}=\"${value}\""
     49     }
     50     config_load travelmate
     51 
     52     if [ ${trm_enabled} -ne 1 ]
     53     then
     54         f_log "info " "travelmate is currently disabled, please set 'trm_enabled' to '1' to use this service"
     55         exit 0
     56     fi
     57 
     58     # check for preferred wireless tool
     59     #
     60     if [ ${trm_iw} -eq 1 ]
     61     then
     62         trm_scanner="$(which iw)"
     63     else
     64         trm_scanner="$(which iwinfo)"
     65     fi
     66     if [ -z "${trm_scanner}" ]
     67     then
     68         f_log "error" "no wireless tool for wlan scanning found, please install 'iw' or 'iwinfo'"
     69     fi
     70 }
     71 
     72 # f_prepare: gather radio information & bring down all STA interfaces
     73 #
     74 f_prepare()
     75 {
     76     local config="${1}"
     77     local mode="$(uci -q get wireless."${config}".mode)"
     78     local radio="$(uci -q get wireless."${config}".device)"
     79     local disabled="$(uci -q get wireless."${config}".disabled)"
     80 
     81     if [ "${mode}" = "ap" ] && ([ -z "${disabled}" ] || [ "${disabled}" = "0" ]) && \
     82         ([ -z "${trm_radio}" ] || [ "${trm_radio}" = "${radio}" ])
     83     then
     84         trm_radiolist="${trm_radiolist} ${radio}"
     85     elif [ "${mode}" = "sta" ]
     86     then
     87         trm_stalist="${trm_stalist} ${config}_${radio}"
     88         if [ -z "${disabled}" ] || [ "${disabled}" = "0" ]
     89         then
     90             uci -q set wireless."${config}".disabled=1
     91         fi
     92     fi
     93     f_log "debug" "mode: ${mode}, radio: ${radio}, config: ${config}, disabled: ${disabled}"
     94 }
     95 
     96 # f_check: check interface status
     97 #
     98 f_check()
     99 {
    100     local ifname radio cnt=1 mode="${1}"
    101     trm_ifstatus="false"
    102 
    103     while [ ${cnt} -le ${trm_maxwait} ]
    104     do
    105         if [ "${mode}" = "ap" ]
    106         then
    107             for radio in ${trm_radiolist}
    108             do
    109                 trm_ifstatus="$(ubus -S call network.wireless status | jsonfilter -e "@.${radio}.up")"
    110                 if [ "${trm_ifstatus}" = "true" ]
    111                 then
    112                     trm_aplist="${trm_aplist} $(ubus -S call network.wireless status | jsonfilter -e "@.${radio}.interfaces[@.config.mode=\"ap\"].ifname")_${radio}"
    113                     ifname="${trm_aplist}"
    114                 else
    115                     trm_aplist=""
    116                     trm_ifstatus="false"
    117                     break
    118                 fi
    119             done
    120         else
    121             ifname="$(ubus -S call network.wireless status | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
    122             if [ -n "${ifname}" ]
    123             then
    124                 trm_ifstatus="$(ubus -S call network.interface dump | jsonfilter -e "@.interface[@.device=\"${ifname}\"].up")"
    125             fi
    126         fi
    127         if [ "${mode}" = "initial" ] || [ "${trm_ifstatus}" = "true" ]
    128         then
    129             break
    130         fi
    131         cnt=$((cnt+1))
    132         sleep 1
    133     done
    134     f_log "debug" "mode: ${mode}, name: ${ifname}, status: ${trm_ifstatus}, count: ${cnt}, max-wait: ${trm_maxwait}, automatic: ${trm_automatic}"
    135 }
    136 
    137 # f_ubus: update ubus service
    138 #
    139 f_ubus()
    140 {
    141     local active_triggers iface="${1}" radio="${2}" ssid="${3}"
    142 
    143     for name in ${trm_iface}
    144     do
    145         active_triggers="${active_triggers}[\"interface.*.down\",[\"if\",[\"eq\",\"interface\",\"${name}\"],[\"run_script\",\"/etc/init.d/travelmate\",\"start\"],1000]],"
    146     done
    147     active_triggers="${active_triggers}[\"config.change\",[\"if\",[\"eq\",\"package\",\"travelmate\"],[\"run_script\",\"/etc/init.d/travelmate\",\"start\"],1000]]"
    148 
    149     ubus call service add "{\"name\":\"travelmate\",
    150         \"instances\":{\"travelmate\":{\"command\":[\"/usr/bin/travelmate.sh\"],
    151         \"data\":{\"travelmate_version\":\"${trm_ver}\",
    152         \"station_interface\":\"${iface}\",
    153         \"station_radio\":\"${radio}\",
    154         \"station_ssid\":\"${ssid}\",
    155         \"last_rundate\":\"$(/bin/date "+%d.%m.%Y %H:%M:%S")\",
    156         \"online_status\":\"${trm_ifstatus}\",
    157         \"system\":\"${trm_sysver}\"}}},
    158         \"triggers\":[${active_triggers}]}"
    159 }
    160 
    161 # f_log: write to syslog, exit on error
    162 #
    163 f_log()
    164 {
    165     local class="${1}"
    166     local log_msg="${2}"
    167 
    168     if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${trm_debug} -eq 1 ])
    169     then
    170         logger -t "travelmate-[${trm_ver}] ${class}" "${log_msg}"
    171         if [ "${class}" = "error" ]
    172         then
    173             logger -t "travelmate-[${trm_ver}] ${class}" "Please check 'https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md' (${trm_sysver})"
    174             exit 255
    175         fi
    176     fi
    177 }
    178 
    179 # f_main: main function for connection handling
    180 #
    181 f_main()
    182 {
    183     local config ssid_list ap ap_radio sta_ssid sta_radio sta_iface cnt=1
    184 
    185     f_check "initial"
    186     if [ "${trm_ifstatus}" != "true" ]
    187     then
    188         config_load wireless
    189         config_foreach f_prepare wifi-iface
    190         if [ -n "$(uci -q changes wireless)" ]
    191         then
    192             uci -q commit wireless
    193             ubus call network reload
    194             sleep 5
    195         fi
    196         f_check "ap"
    197         f_log "debug" "ap-list: ${trm_aplist}, sta-list: ${trm_stalist}"
    198         if [ -z "${trm_aplist}" ] || [ -z "${trm_stalist}" ]
    199         then
    200             f_log "error" "no usable AP/STA configuration found"
    201         fi
    202         for ap in ${trm_aplist}
    203         do
    204             cnt=1
    205             ap_radio="${ap##*_}"
    206             ap="${ap%%_*}"
    207             if [ -z "$(printf "${trm_stalist}" | grep -Fo "_${ap_radio}")" ]
    208             then
    209                 continue
    210             fi
    211             while [ ${cnt} -le ${trm_maxretry} ]
    212             do
    213                 if [ ${trm_iw} -eq 1 ]
    214                 then
    215                     ssid_list="$(${trm_scanner} dev "${ap}" scan 2>/dev/null | \
    216                         awk '/SSID: /{if(!seen[$0]++){printf "\"";for(i=2; i<=NF; i++)if(i==2)printf $i;else printf " "$i;printf "\" "}}')"
    217                 else
    218                     ssid_list="$(${trm_scanner} "${ap}" scan | \
    219                         awk '/ESSID: ".*"/{ORS=" ";if (!seen[$0]++) for(i=2; i<=NF; i++) print $i}')"
    220                 fi
    221                 f_log "debug" "scanner: ${trm_scanner}, ap: ${ap}, ssids: ${ssid_list}"
    222                 if [ -n "${ssid_list}" ]
    223                 then
    224                     for sta in ${trm_stalist}
    225                     do
    226                         config="${sta%%_*}"
    227                         sta_radio="${sta##*_}"
    228                         sta_ssid="$(uci -q get wireless."${config}".ssid)"
    229                         sta_iface="$(uci -q get wireless."${config}".network)"
    230                         if [ -n "$(printf "${ssid_list}" | grep -Fo "\"${sta_ssid}\"")" ] && [ "${ap_radio}" = "${sta_radio}" ]
    231                         then
    232                             uci -q set wireless."${config}".disabled=0
    233                             ubus call network reload
    234                             f_check "sta"
    235                             if [ "${trm_ifstatus}" = "true" ]
    236                             then
    237                                 uci -q commit wireless
    238                                 f_log "info " "interface '${sta_iface}' on '${sta_radio}' connected to uplink '${sta_ssid}' (${trm_sysver})"
    239                                 sleep 5
    240                                 f_ubus "${sta_iface}" "${sta_radio}" "${sta_ssid}"
    241                                 return 0
    242                             else
    243                                 uci -q revert wireless
    244                                 ubus call network reload
    245                                 f_log "info " "interface '${sta_iface}' on '${sta_radio}' can't connect to uplink '${sta_ssid}' (${trm_sysver})"
    246                                 f_ubus "${sta_iface}" "${sta_radio}" "${sta_ssid}"
    247                             fi
    248                         fi
    249                     done
    250                 fi
    251                 cnt=$((cnt+1))
    252                 sleep 5
    253             done
    254         done
    255     fi
    256 }
    257 
    258 f_envload
    259 f_main
    260 while [ ${trm_automatic} -eq 1 ]
    261 do
    262     sleep ${trm_timeout}
    263     f_envload
    264     f_main
    265 done
    266 exit 0