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.

194 lines
5.9 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (c) 2016-2022 Dirk Brenken (dev@brenken.org)
  3. # This is free software, licensed under the GNU General Public License v3.
  4. # set (s)hellcheck exceptions
  5. # shellcheck disable=2034,2086,2154,3043,3060
  6. START=25
  7. USE_PROCD=1
  8. extra_command "scan" "[<radio>|<ifname>] Scan for available nearby uplinks"
  9. extra_command "assoc" "[<radio>|<ifname>] Get MAC adresses of associated wlan stations"
  10. extra_command "setup" "[<iface>] [<zone>] [<metric>] Setup the travelmate uplink interface, by default 'trm_wwan' with firewall zone 'wan' and metric '100'"
  11. trm_init="/etc/init.d/travelmate"
  12. trm_script="/usr/bin/travelmate.sh"
  13. trm_pidfile="/var/run/travelmate.pid"
  14. boot() {
  15. if [ -s "${trm_pidfile}" ]; then
  16. : >"${trm_pidfile}"
  17. fi
  18. rc_procd start_service
  19. }
  20. start_service() {
  21. if "${trm_init}" enabled; then
  22. if [ "${action}" = "boot" ]; then
  23. return 0
  24. fi
  25. procd_open_instance "travelmate"
  26. procd_set_param command "${trm_script}" "${@}"
  27. procd_set_param pidfile "${trm_pidfile}"
  28. procd_set_param nice "$(uci_get travelmate global trm_nice "0")"
  29. procd_set_param stdout 1
  30. procd_set_param stderr 1
  31. procd_close_instance
  32. fi
  33. }
  34. reload_service() {
  35. local ppid pid timeout
  36. timeout="$(uci_get travelmate global trm_timeout)"
  37. if [ -s "${trm_pidfile}" ]; then
  38. ppid="$(cat "${trm_pidfile}" 2>/dev/null)"
  39. if [ -n "${ppid}" ]; then
  40. pid="$(pgrep -xnf "sleep ${timeout:-60} 0" -P ${ppid} 2>/dev/null)"
  41. if [ -n "${pid}" ]; then
  42. kill -INT ${pid} 2>/dev/null
  43. fi
  44. fi
  45. fi
  46. }
  47. stop_service() {
  48. rc_procd "${trm_script}" stop
  49. }
  50. status_service() {
  51. local key keylist value rtfile
  52. rtfile="$(uci_get travelmate global trm_rtfile "/tmp/trm_runtime.json")"
  53. json_load_file "${rtfile}" >/dev/null 2>&1
  54. if json_select data >/dev/null 2>&1; then
  55. printf "%s\n" "::: travelmate runtime information"
  56. json_get_keys keylist
  57. for key in ${keylist}; do
  58. json_get_var value "${key}"
  59. printf " + %-18s : %s\n" "${key}" "${value}"
  60. done
  61. else
  62. printf "%s\n" "::: no travelmate runtime information available"
  63. fi
  64. }
  65. scan() {
  66. local result scan_name radio="${1}"
  67. if [ -z "${radio}" ]; then
  68. scan_name="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.up=true].interfaces[0].ifname')"
  69. fi
  70. result="$(iwinfo "${radio:-${scan_name}}" scan 2>/dev/null |
  71. awk 'BEGIN{FS="[[:space:]]"}/Address:/{var1=$NF}/ESSID:/{var2="";
  72. for(i=12;i<=NF;i++)if(var2==""){var2=$i}else{var2=var2" "$i}}/Channel:/{var3=$NF}/Quality:/{split($NF,var0,"/")}/Encryption:/{var4="";
  73. for(j=12;j<=NF;j++)if(var4==""){var4=$j}else{var4=var4" "$j};printf " %-11i%-10s%-35s%-20s%s\n",(var0[1]*100/var0[2]),var3,var2,var1,var4}' |
  74. sort -rn)"
  75. printf "%s\n" "::: Available nearby uplinks on '${radio:-${scan_name}}'"
  76. printf "%s\n" ":::"
  77. if [ -n "${result}" ]; then
  78. printf "%-15s%-10s%-35s%-20s%s\n" " Strength" "Channel" "ESSID" "BSSID" "Encryption"
  79. printf "%s\n" " --------------------------------------------------------------------------------------"
  80. printf "%s\n" "${result}"
  81. else
  82. printf "%s\n" "::: Empty resultset"
  83. fi
  84. }
  85. setup() {
  86. local iface cnt=0 input="${1:-"trm_wwan"}" zone="${2:-"wan"}" metric="${3:-"100"}"
  87. iface="$(uci_get travelmate global trm_iface)"
  88. input="${input//[+*~%&\$@\"\' ]/}"
  89. zone="${zone//[+*~%&\$@\"\' ]/}"
  90. metric="${metric//[^0-9]/}"
  91. if [ -n "${iface}" ] && [ "${iface}" = "${input}" ]; then
  92. printf "%s\n" "The uplink interface '${input}' has been already configured"
  93. elif [ -n "${input}" ]; then
  94. if [ -n "${iface}" ]; then
  95. uci -q batch <<-EOC
  96. del network."${iface}"
  97. del network."${iface}6"
  98. EOC
  99. fi
  100. uci -q batch <<-EOC
  101. set travelmate.global.trm_enabled="1"
  102. set travelmate.global.trm_iface="${input}"
  103. set network."${input}"="interface"
  104. set network."${input}".proto="dhcp"
  105. set network."${input}".metric="${metric}"
  106. set network."${input}6"=interface
  107. set network."${input}6".device="@${input}"
  108. set network."${input}6".proto="dhcpv6"
  109. commit travelmate
  110. commit network
  111. EOC
  112. while [ -n "$(uci -q get firewall.@zone["${cnt}"].name)" ]; do
  113. if [ "$(uci -q get firewall.@zone["${cnt}"].name)" = "${zone}" ]; then
  114. if [ -n "${iface}" ]; then
  115. uci -q batch <<-EOC
  116. del_list firewall.@zone["${cnt}"].network="${iface}"
  117. del_list firewall.@zone["${cnt}"].network="${iface}6"
  118. EOC
  119. fi
  120. uci -q batch <<-EOC
  121. add_list firewall.@zone["${cnt}"].network="${input}"
  122. add_list firewall.@zone["${cnt}"].network="${input}6"
  123. commit firewall
  124. EOC
  125. break
  126. fi
  127. cnt=$((cnt + 1))
  128. done
  129. if [ -n "${iface}" ]; then
  130. cnt=0
  131. while [ -n "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" ]; do
  132. if [ "$(uci -q get wireless.@wifi-iface["${cnt}"].network)" = "${iface}" ]; then
  133. uci -q set wireless.@wifi-iface["${cnt}"].network="${input}"
  134. fi
  135. cnt=$((cnt + 1))
  136. done
  137. uci -q commit wireless
  138. fi
  139. /etc/init.d/network reload >/dev/null 2>&1
  140. /etc/init.d/firewall reload >/dev/null 2>&1
  141. "${trm_init}" restart
  142. fi
  143. }
  144. assoc() {
  145. local result assoc_name radio="${1}"
  146. if [ -z "${radio}" ]; then
  147. assoc_name="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@[@.*.*.config.mode="ap"].interfaces[0].ifname')"
  148. fi
  149. result="$(iwinfo "${radio:-${assoc_name}}" assoc 2>/dev/null | awk '/^[A-Z0-9:]+/{printf " %s\n",$1}')"
  150. printf "%s\n" "::: Associated wlan stations on '${radio:-${assoc_name}}'"
  151. printf "%s\n" ":::"
  152. if [ -n "${result}" ]; then
  153. printf "%s\n" " MAC addresses"
  154. printf "%s\n" " -----------------"
  155. printf "%s\n" "${result}"
  156. else
  157. printf "%s\n" "::: Empty resultset"
  158. fi
  159. }
  160. service_triggers() {
  161. local iface delay
  162. iface="$(uci_get travelmate global trm_iface)"
  163. delay="$(uci_get travelmate global trm_triggerdelay "2")"
  164. PROCD_RELOAD_DELAY=$((delay * 1000))
  165. if [ -n "${iface}" ]; then
  166. procd_add_interface_trigger "interface.*.down" "${iface}" "${trm_init}" reload
  167. fi
  168. procd_add_raw_trigger "interface.*.up" "${PROCD_RELOAD_DELAY}" "${trm_init}" start
  169. procd_add_config_trigger "config.change" "travelmate" "${trm_init}" restart
  170. }