[OpenWrt-Devel] [PATCH v3] uqmi: allow matching IMSI for qmi networks

Piotr Dymacz pepe2k at gmail.com
Mon Nov 5 06:28:06 EST 2018


Hi Daniel,

On 05.11.2018 00:46, Daniel Golle wrote:
> Introduce 'imsi' configuration option for proto 'qmi' network
> interfaces. Setting it makes sure the configuration only gets used
> on the intended SIM card. In this way, one can have many configurations
> for different SIM cards selected automatically when the card was either
> swapped physically or in software (as possible on the APU3 board).
> In order to allow multiple configurations using the same character
> device, add locking in netifd protocol handler to avoid overlapping
> execution of uqmi of the same device.

As the general idea seems correct, I find it very limited and maybe 
problematic (is IMSI number always available before SIM is unlocked?). 
Personally, I would prefer to introduce a generic/universal solution, 
not limited to any of the wwan protocols.

I've been using for years slightly different approach which, in the same 
or modified version, might suit better than your idea, also in multi-SIM 
and/or multi-modem solutions or for users often changing SIM cards in a 
single device. Let me try to explain the idea below.

Instead of keeping SIM/operator related configuration (apn, pincode...) 
within the modem network configuration section (glued to a specific 
interface), we introduce a generic 'sim' config file (/etc/config/sim), 
as part of the wwan package, which by default contains only one, default 
configuration (no pin, no auth, generic apn, lets say: 'internet'). If 
the user wants to setup additional _SIM-specific_ configuration, section 
should be named with the SIM ICCID number, for example:

config sim
   option apn 'internet'

...

config sim '1234567890ABCDEFGHI'
   option apn 'internet6'
   option pincode '0000'
   option auth 'PAP'
   option username 'user'
   option password 'pass'

...

SIM ICCID is known to the user (operators print it on the SIM itself) 
and available for the software in advance, even before pin-unlocking.

Essentially, this idea maps whole or almost whole configuration required 
for Internet access to SIM, instead of the modem (or, device interface 
in system). During interface setup/bring-up, SIM configuration is 
searched for a specific section (based on the ICCID of the SIM in use) 
and in case it's missing, default one is used.

Of course, this approach requires all available wwan protocols to 
support fetching ICCID from the SIM and also inform the user about 
missing SIM-specific configuration if it's required (SIM requires PIN 
but SIM-specific configuration is missing).
Plus, some kind of migration mechanism would be required for current 
solution (SIM configuration in network config file).

-- 
Cheers,
Piotr

> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>   package/network/utils/uqmi/Makefile           |  2 +-
>   .../utils/uqmi/files/lib/netifd/proto/qmi.sh  | 54 ++++++++++++++++---
>   2 files changed, 49 insertions(+), 7 deletions(-)
> 
> diff --git a/package/network/utils/uqmi/Makefile b/package/network/utils/uqmi/Makefile
> index b2f3474400..8eaf0bff3f 100644
> --- a/package/network/utils/uqmi/Makefile
> +++ b/package/network/utils/uqmi/Makefile
> @@ -1,7 +1,7 @@
>   include $(TOPDIR)/rules.mk
>   
>   PKG_NAME:=uqmi
> -PKG_RELEASE:=5
> +PKG_RELEASE:=6
>   
>   PKG_SOURCE_PROTO:=git
>   PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git
> diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
> index 9b2f69f009..2edbe7c28e 100755
> --- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
> +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
> @@ -10,6 +10,7 @@ proto_qmi_init_config() {
>   	available=1
>   	no_device=1
>   	proto_config_add_string "device:device"
> +	proto_config_add_string imsi
>   	proto_config_add_string apn
>   	proto_config_add_string auth
>   	proto_config_add_string username
> @@ -28,12 +29,12 @@ proto_qmi_init_config() {
>   
>   proto_qmi_setup() {
>   	local interface="$1"
> -	local dataformat connstat
> -	local device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn timeout $PROTO_DEFAULT_OPTIONS
> +	local dataformat connstat imsi_actual
> +	local device imsi apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn timeout $PROTO_DEFAULT_OPTIONS
>   	local ip4table ip6table
>   	local cid_4 pdh_4 cid_6 pdh_6
>   	local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
> -	json_get_vars device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn ip4table ip6table timeout $PROTO_DEFAULT_OPTIONS
> +	json_get_vars device imsi apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn ip4table ip6table timeout $PROTO_DEFAULT_OPTIONS
>   
>   	[ "$timeout" = "" ] && timeout="10"
>   
> @@ -68,10 +69,16 @@ proto_qmi_setup() {
>   		return 1
>   	}
>   
> +	lockname="/var/lock/LCK..$devname"
> +	lock "$lockname"
> +
>   	echo "Waiting for SIM initialization"
>   	local uninitialized_timeout=0
>   	while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
> -		[ -e "$device" ] || return 1
> +		[ -e "$device" ] || {
> +			lock -u "$lockname"
> +			return 1
> +		}
>   		if [ "$uninitialized_timeout" -lt "$timeout" ]; then
>   			let uninitialized_timeout++
>   			sleep 1;
> @@ -79,16 +86,29 @@ proto_qmi_setup() {
>   			echo "SIM not initialized"
>   			proto_notify_error "$interface" SIM_NOT_INITIALIZED
>   			proto_block_restart "$interface"
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   	done
>   
> +	[ -n "$imsi" ] && {
> +		imsi_actual="$(uqmi -s -d "$device" --get-imsi | cut -d'"' -f2)"
> +		[ "$imsi" = "$imsi_actual" ] || {
> +			echo "Configured IMSI doesn't match SIM card."
> +			proto_notify_error "$interface" SIM_WRONG
> +			proto_set_available "$interface" 0
> +			lock -u "$lockname"
> +			return 1
> +		}
> +	}
> +
>   	if uqmi -s -d "$device" --get-pin-status | grep '"Not supported"' > /dev/null; then
>   		[ -n "$pincode" ] && {
>   			uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null || {
>   				echo "Unable to verify PIN"
>   				proto_notify_error "$interface" PIN_FAILED
>   				proto_block_restart "$interface"
> +				lock -u "$lockname"
>   				return 1
>   			}
>   		}
> @@ -106,6 +126,7 @@ proto_qmi_setup() {
>   				echo "SIM locked PUK required"
>   				proto_notify_error "$interface" PUK_NEEDED
>   				proto_block_restart "$interface"
> +				lock -u "$lockname"
>   				return 1
>   				;;
>   			not_verified)
> @@ -113,6 +134,7 @@ proto_qmi_setup() {
>   					echo "PIN verify count value is $pin1_verify_tries this is below the limit of 3"
>   					proto_notify_error "$interface" PIN_TRIES_BELOW_LIMIT
>   					proto_block_restart "$interface"
> +					lock -u "$lockname"
>   					return 1
>   				}
>   				if [ -n "$pincode" ]; then
> @@ -120,12 +142,14 @@ proto_qmi_setup() {
>   						echo "Unable to verify PIN"
>   						proto_notify_error "$interface" PIN_FAILED
>   						proto_block_restart "$interface"
> +						lock -u "$lockname"
>   						return 1
>   					}
>   				else
>   					echo "PIN not specified but required"
>   					proto_notify_error "$interface" PIN_NOT_SPECIFIED
>   					proto_block_restart "$interface"
> +					lock -u "$lockname"
>   					return 1
>   				fi
>   				;;
> @@ -136,6 +160,7 @@ proto_qmi_setup() {
>   				echo "PIN status failed ($pin1_status)"
>   				proto_notify_error "$interface" PIN_STATUS_FAILED
>   				proto_block_restart "$interface"
> +				lock -u "$lockname"
>   				return 1
>   			;;
>   		esac
> @@ -156,6 +181,7 @@ proto_qmi_setup() {
>   			echo "Unable to set PLMN"
>   			proto_notify_error "$interface" PLMN_FAILED
>   			proto_block_restart "$interface"
> +			lock -u "$lockname"
>   			return 1
>   		}
>   	}
> @@ -172,6 +198,7 @@ proto_qmi_setup() {
>   
>   		[ -f /sys/class/net/$ifname/qmi/raw_ip ] || {
>   			echo "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip"
> +			lock -u "$lockname"
>   			return 1
>   		}
>   
> @@ -184,7 +211,10 @@ proto_qmi_setup() {
>   	echo "Waiting for network registration"
>   	local registration_timeout=0
>   	while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
> -		[ -e "$device" ] || return 1
> +		[ -e "$device" ] || {
> +			lock -u "$lockname"
> +			return 1
> +		}
>   		if [ "$registration_timeout" -lt "$timeout" ]; then
>   			let registration_timeout++
>   			sleep 1;
> @@ -192,6 +222,7 @@ proto_qmi_setup() {
>   			echo "Network registration failed"
>   			proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED
>   			proto_block_restart "$interface"
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   	done
> @@ -215,6 +246,7 @@ proto_qmi_setup() {
>   		if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then
>   			echo "Unable to obtain client ID"
>   			proto_notify_error "$interface" NO_CID
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   
> @@ -234,6 +266,7 @@ proto_qmi_setup() {
>   			echo "Unable to connect IPv4"
>   			uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
>   			proto_notify_error "$interface" CALL_FAILED
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   
> @@ -243,6 +276,7 @@ proto_qmi_setup() {
>   			echo "No data link!"
>   			uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
>   			proto_notify_error "$interface" CALL_FAILED
> +			lock -u "$lockname"
>   			return 1
>   		}
>   	}
> @@ -252,6 +286,7 @@ proto_qmi_setup() {
>   		if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then
>   			echo "Unable to obtain client ID"
>   			proto_notify_error "$interface" NO_CID
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   
> @@ -271,6 +306,7 @@ proto_qmi_setup() {
>   			echo "Unable to connect IPv6"
>   			uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
>   			proto_notify_error "$interface" CALL_FAILED
> +			lock -u "$lockname"
>   			return 1
>   		fi
>   
> @@ -280,6 +316,7 @@ proto_qmi_setup() {
>   			echo "No data link!"
>   			uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
>   			proto_notify_error "$interface" CALL_FAILED
> +			lock -u "$lockname"
>   			return 1
>   		}
>   	}
> @@ -343,6 +380,7 @@ proto_qmi_setup() {
>   		json_close_object
>   		ubus call network add_dynamic "$(json_dump)"
>   	}
> +	lock -u "$lockname"
>   }
>   
>   qmi_wds_stop() {
> @@ -367,10 +405,12 @@ qmi_wds_stop() {
>   proto_qmi_teardown() {
>   	local interface="$1"
>   
> -	local device cid_4 pdh_4 cid_6 pdh_6
> +	local device localname cid_4 pdh_4 cid_6 pdh_6
>   	json_get_vars device
>   
>   	[ -n "$ctl_device" ] && device=$ctl_device
> +	lockname="/var/lock/LCK..$(basename "$device")"
> +	lock "$lockname"
>   
>   	echo "Stopping network $interface"
>   
> @@ -383,6 +423,8 @@ proto_qmi_teardown() {
>   
>   	proto_init_update "*" 0
>   	proto_send_update "$interface"
> +
> +	lock -u "$lockname"
>   }
>   
>   [ -n "$INCLUDE_ONLY" ] || {
> 


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list