2
0

ncm.sh 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #!/bin/sh
  2. [ -n "$INCLUDE_ONLY" ] || {
  3. . /lib/functions.sh
  4. . ../netifd-proto.sh
  5. init_proto "$@"
  6. }
  7. proto_ncm_init_config() {
  8. no_device=1
  9. available=1
  10. proto_config_add_string "device:device"
  11. proto_config_add_string ifname
  12. proto_config_add_string apn
  13. proto_config_add_string auth
  14. proto_config_add_string username
  15. proto_config_add_string password
  16. proto_config_add_string pincode
  17. proto_config_add_string delay
  18. proto_config_add_string mode
  19. proto_config_add_string pdptype
  20. proto_config_add_boolean sourcefilter
  21. proto_config_add_boolean delegate
  22. proto_config_add_int profile
  23. proto_config_add_defaults
  24. }
  25. proto_ncm_setup() {
  26. local interface="$1"
  27. local manufacturer initialize setmode connect finalize devname devpath ifpath
  28. local device ifname apn auth username password pincode delay mode pdptype profile $PROTO_DEFAULT_OPTIONS
  29. json_get_vars device ifname apn auth username password pincode delay mode pdptype sourcefilter delegate profile $PROTO_DEFAULT_OPTIONS
  30. local context_type
  31. [ "$metric" = "" ] && metric="0"
  32. [ -n "$profile" ] || profile=1
  33. pdptype=$(echo "$pdptype" | awk '{print toupper($0)}')
  34. [ "$pdptype" = "IP" -o "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] || pdptype="IP"
  35. [ "$pdptype" = "IPV4V6" ] && context_type=3
  36. [ -z "$context_type" -a "$pdptype" = "IPV6" ] && context_type=2
  37. [ -n "$context_type" ] || context_type=1
  38. [ -n "$ctl_device" ] && device=$ctl_device
  39. [ -n "$device" ] || {
  40. echo "No control device specified"
  41. proto_notify_error "$interface" NO_DEVICE
  42. proto_set_available "$interface" 0
  43. return 1
  44. }
  45. device="$(readlink -f $device)"
  46. [ -e "$device" ] || {
  47. echo "Control device not valid"
  48. proto_set_available "$interface" 0
  49. return 1
  50. }
  51. [ -z "$ifname" ] && {
  52. devname="$(basename "$device")"
  53. case "$devname" in
  54. 'ttyACM'*)
  55. devpath="$(readlink -f /sys/class/tty/$devname/device)"
  56. ifpath="$devpath/../*/net"
  57. ;;
  58. 'tty'*)
  59. devpath="$(readlink -f /sys/class/tty/$devname/device)"
  60. ifpath="$devpath/../../*/net"
  61. ;;
  62. *)
  63. devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
  64. ifpath="$devpath/net"
  65. ;;
  66. esac
  67. ifname="$(ls $(ls -1 -d $ifpath | head -n 1))"
  68. }
  69. [ -n "$ifname" ] || {
  70. echo "The interface could not be found."
  71. proto_notify_error "$interface" NO_IFACE
  72. proto_set_available "$interface" 0
  73. return 1
  74. }
  75. start=$(date +%s)
  76. while true; do
  77. manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
  78. [ "$manufacturer" = "error" ] && {
  79. manufacturer=""
  80. }
  81. [ -n "$manufacturer" ] && {
  82. break
  83. }
  84. [ -z "$delay" ] && {
  85. break
  86. }
  87. sleep 1
  88. elapsed=$(($(date +%s) - start))
  89. [ "$elapsed" -gt "$delay" ] && {
  90. break
  91. }
  92. done
  93. [ -z "$manufacturer" ] && {
  94. echo "Failed to get modem information"
  95. proto_notify_error "$interface" GETINFO_FAILED
  96. return 1
  97. }
  98. json_load "$(cat /etc/gcom/ncm.json)"
  99. json_select "$manufacturer"
  100. [ $? -ne 0 ] && {
  101. echo "Unsupported modem"
  102. proto_notify_error "$interface" UNSUPPORTED_MODEM
  103. proto_set_available "$interface" 0
  104. return 1
  105. }
  106. json_get_values initialize initialize
  107. for i in $initialize; do
  108. eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  109. echo "Failed to initialize modem"
  110. proto_notify_error "$interface" INITIALIZE_FAILED
  111. return 1
  112. }
  113. done
  114. [ -n "$pincode" ] && {
  115. PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
  116. echo "Unable to verify PIN"
  117. proto_notify_error "$interface" PIN_FAILED
  118. proto_block_restart "$interface"
  119. return 1
  120. }
  121. }
  122. json_get_values configure configure
  123. echo "Configuring modem"
  124. for i in $configure; do
  125. eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  126. echo "Failed to configure modem"
  127. proto_notify_error "$interface" CONFIGURE_FAILED
  128. return 1
  129. }
  130. done
  131. [ -n "$mode" ] && {
  132. json_select modes
  133. json_get_var setmode "$mode"
  134. [ -n "$setmode" ] && {
  135. echo "Setting mode"
  136. eval COMMAND="$setmode" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  137. echo "Failed to set operating mode"
  138. proto_notify_error "$interface" SETMODE_FAILED
  139. return 1
  140. }
  141. }
  142. json_select ..
  143. }
  144. echo "Starting network $interface"
  145. json_get_vars connect
  146. [ -n "$connect" ] && {
  147. echo "Connecting modem"
  148. eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  149. echo "Failed to connect"
  150. proto_notify_error "$interface" CONNECT_FAILED
  151. return 1
  152. }
  153. }
  154. json_get_vars finalize
  155. echo "Setting up $ifname"
  156. proto_init_update "$ifname" 1
  157. proto_add_data
  158. json_add_string "manufacturer" "$manufacturer"
  159. proto_close_data
  160. proto_send_update "$interface"
  161. local zone="$(fw3 -q network "$interface" 2>/dev/null)"
  162. [ "$pdptype" = "IP" -o "$pdptype" = "IPV4V6" ] && {
  163. json_init
  164. json_add_string name "${interface}_4"
  165. json_add_string ifname "@$interface"
  166. json_add_string proto "dhcp"
  167. proto_add_dynamic_defaults
  168. [ -n "$zone" ] && {
  169. json_add_string zone "$zone"
  170. }
  171. json_close_object
  172. ubus call network add_dynamic "$(json_dump)"
  173. }
  174. [ "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] && {
  175. json_init
  176. json_add_string name "${interface}_6"
  177. json_add_string ifname "@$interface"
  178. json_add_string proto "dhcpv6"
  179. json_add_string extendprefix 1
  180. [ "$delegate" = "0" ] && json_add_boolean delegate "0"
  181. [ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
  182. proto_add_dynamic_defaults
  183. [ -n "$zone" ] && {
  184. json_add_string zone "$zone"
  185. }
  186. json_close_object
  187. ubus call network add_dynamic "$(json_dump)"
  188. }
  189. [ -n "$finalize" ] && {
  190. eval COMMAND="$finalize" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  191. echo "Failed to configure modem"
  192. proto_notify_error "$interface" FINALIZE_FAILED
  193. return 1
  194. }
  195. }
  196. }
  197. proto_ncm_teardown() {
  198. local interface="$1"
  199. local manufacturer disconnect
  200. local device profile
  201. json_get_vars device profile
  202. [ -n "$ctl_device" ] && device=$ctl_device
  203. [ -n "$device" ] || {
  204. echo "No control device specified"
  205. proto_notify_error "$interface" NO_DEVICE
  206. proto_set_available "$interface" 0
  207. return 1
  208. }
  209. device="$(readlink -f $device)"
  210. [ -e "$device" ] || {
  211. echo "Control device not valid"
  212. proto_set_available "$interface" 0
  213. return 1
  214. }
  215. [ -n "$profile" ] || profile=1
  216. echo "Stopping network $interface"
  217. json_load "$(ubus call network.interface.$interface status)"
  218. json_select data
  219. json_get_vars manufacturer
  220. [ $? -ne 0 -o -z "$manufacturer" ] && {
  221. # Fallback to direct detect, for proper handle device replug.
  222. manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
  223. [ $? -ne 0 -o -z "$manufacturer" ] && {
  224. echo "Failed to get modem information"
  225. proto_notify_error "$interface" GETINFO_FAILED
  226. return 1
  227. }
  228. json_add_string "manufacturer" "$manufacturer"
  229. }
  230. json_load "$(cat /etc/gcom/ncm.json)"
  231. json_select "$manufacturer" || {
  232. echo "Unsupported modem"
  233. proto_notify_error "$interface" UNSUPPORTED_MODEM
  234. return 1
  235. }
  236. json_get_vars disconnect
  237. [ -n "$disconnect" ] && {
  238. eval COMMAND="$disconnect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
  239. echo "Failed to disconnect"
  240. proto_notify_error "$interface" DISCONNECT_FAILED
  241. return 1
  242. }
  243. }
  244. proto_init_update "*" 0
  245. proto_send_update "$interface"
  246. }
  247. [ -n "$INCLUDE_ONLY" ] || {
  248. add_protocol ncm
  249. }