Browse Source

comgt-ncm: do not attempt to connect if the control device is invalid

After a hardware reconnect, the control device might be unavailable and
attempting to interact with it will lead to hanging gcom calls, leaving
the protocol setup in an unrecoverable state.

Change the protocol handler to bail out early and notify netifd if the
control device is not defined or if the underlying device node does not
exist.

Also ensure that the "disconnect", "connect" and "setmode" commands are
actually defined before trying to invoke them.

Finally attempt to re-query the device manufacturer if it is unset in
the interface state in order to prevent UNUPPORTED_MODEM errors after
a modem hardware reconnect.

Signed-off-by: Rozhuk Ivan <[email protected]>
[reword subject and commit message]
Ref: https://github.com/openwrt/openwrt/pull/2352
Signed-off-by: Jo-Philipp Wich <[email protected]>
Rozhuk Ivan 6 years ago
parent
commit
ba7ddae9a9
1 changed files with 46 additions and 16 deletions
  1. 46 16
      package/network/utils/comgt/files/ncm.sh

+ 46 - 16
package/network/utils/comgt/files/ncm.sh

@@ -74,7 +74,7 @@ proto_ncm_setup() {
 	[ -n "$delay" ] && sleep "$delay"
 
 	manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
-	[ $? -ne 0 ] && {
+	[ $? -ne 0 -o -z "$manufacturer" ] && {
 		echo "Failed to get modem information"
 		proto_notify_error "$interface" GETINFO_FAILED
 		return 1
@@ -88,6 +88,7 @@ proto_ncm_setup() {
 		proto_set_available "$interface" 0
 		return 1
 	}
+
 	json_get_values initialize initialize
 	for i in $initialize; do
 		eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
@@ -119,22 +120,26 @@ proto_ncm_setup() {
 	[ -n "$mode" ] && {
 		json_select modes
 		json_get_var setmode "$mode"
-		echo "Setting mode"
-		eval COMMAND="$setmode" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
-			echo "Failed to set operating mode"
-			proto_notify_error "$interface" SETMODE_FAILED
-			return 1
+		[ -n "$setmode" ] && {
+			echo "Setting mode"
+			eval COMMAND="$setmode" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+				echo "Failed to set operating mode"
+				proto_notify_error "$interface" SETMODE_FAILED
+				return 1
+			}
 		}
 		json_select ..
 	}
 
 	echo "Starting network $interface"
 	json_get_vars connect
-	echo "Connecting modem"
-	eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
-		echo "Failed to connect"
-		proto_notify_error "$interface" CONNECT_FAILED
-		return 1
+	[ -n "$connect" ] && {
+		echo "Connecting modem"
+		eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+			echo "Failed to connect"
+			proto_notify_error "$interface" CONNECT_FAILED
+			return 1
+		}
 	}
 
 	json_get_vars finalize
@@ -182,7 +187,6 @@ proto_ncm_setup() {
 			return 1
 		}
 	}
-
 }
 
 proto_ncm_teardown() {
@@ -195,6 +199,20 @@ proto_ncm_teardown() {
 
 	[ -n "$ctl_device" ] && device=$ctl_device
 
+	[ -n "$device" ] || {
+		echo "No control device specified"
+		proto_notify_error "$interface" NO_DEVICE
+		proto_set_available "$interface" 0
+		return 1
+	}
+
+	device="$(readlink -f $device)"
+	[ -e "$device" ] || {
+		echo "Control device not valid"
+		proto_set_available "$interface" 0
+		return 1
+	}
+
 	[ -n "$profile" ] || profile=1
 
 	echo "Stopping network $interface"
@@ -202,6 +220,16 @@ proto_ncm_teardown() {
 	json_load "$(ubus call network.interface.$interface status)"
 	json_select data
 	json_get_vars manufacturer
+	[ $? -ne 0 -o -z "$manufacturer" ] && {
+		# Fallback to direct detect, for proper handle device replug.
+		manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
+		[ $? -ne 0 -o -z "$manufacturer" ] && {
+			echo "Failed to get modem information"
+			proto_notify_error "$interface" GETINFO_FAILED
+			return 1
+		}
+		json_add_string "manufacturer" "$manufacturer"
+	}
 
 	json_load "$(cat /etc/gcom/ncm.json)"
 	json_select "$manufacturer" || {
@@ -211,10 +239,12 @@ proto_ncm_teardown() {
 	}
 
 	json_get_vars disconnect
-	eval COMMAND="$disconnect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
-		echo "Failed to disconnect"
-		proto_notify_error "$interface" DISCONNECT_FAILED
-		return 1
+	[ -n "$disconnect" ] && {
+		eval COMMAND="$disconnect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
+			echo "Failed to disconnect"
+			proto_notify_error "$interface" DISCONNECT_FAILED
+			return 1
+		}
 	}
 
 	proto_init_update "*" 0