You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
7.5 KiB

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