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 <rozhuk.im@gmail.com>
[reword subject and commit message]
Ref: https://github.com/openwrt/openwrt/pull/2352
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
master
Rozhuk Ivan 5 years ago committed by Jo-Philipp Wich
parent 8fe9940db6
commit ba7ddae9a9

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

Loading…
Cancel
Save