modemmanager: add pin check attempts
authorFlorian Eckert <fe@dev.tdt.de>
Thu, 26 Sep 2024 09:02:49 +0000 (11:02 +0200)
committerRobert Marko <robimarko@gmail.com>
Thu, 17 Oct 2024 16:29:16 +0000 (18:29 +0200)
This new check in the proto modemanager prevents the SIM card from being
blocked and therefore PUK is not required. If the PIN is entered incorrectly
in the 'uci' configuration, it makes no sense to try this several times
until the PUK is required. Should it nevertheless happen that the PUK
is required, then this will logged.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
net/modemmanager/files/lib/netifd/proto/modemmanager.sh

index 23d73c75504f6dd57a08235da3a526fbddfef6e2..669acb38e0b412c201ba5edf44011858fb21ab28 100644 (file)
@@ -332,12 +332,63 @@ modemmanager_check_state_failed() {
        esac
 }
 
+modemmanager_check_state_lock_simpin() {
+       local interface="$1"
+       local unlock_value="$2"
+
+       [ $unlock_value -ge 2 ] && return 0
+
+       echo "please check PIN (remaining attempts: ${unlock_value})"
+       proto_notify_error "${interface}" MM_CHECK_UNLOCK_PIN
+       proto_block_restart "${interface}"
+       return 1
+}
+
+modemmanager_check_state_lock_simpuk() {
+       local interface="$1"
+       local unlock_value="$2"
+
+       echo "unlock with PUK required (remaining attempts: ${unlock_value})"
+       proto_notify_error "${interface}" MM_CHECK_UNLOCK_PIN
+       proto_block_restart "${interface}"
+       return 1
+}
+
+modemmanager_check_state_lock_sim() {
+       local interface="$1"
+       local unlock_lock="$2"
+       local unlock_value="$3"
+
+       case "$unlock_lock" in
+               "sim-pin")
+                       modemmanager_check_state_lock_simpin \
+                               "$interface" \
+                               "$unlock_value"
+                       [ "$?" -ne "0" ] && return 1
+                       ;;
+               "sim-puk")
+                       modemmanager_check_state_lock_simpuk \
+                               "$interface" \
+                               "$unlock_value"
+                       [ "$?" -ne "0" ] && return 1
+                       ;;
+               *)
+                       echo "PIN/PUK check '$unlock_lock' not implemented"
+                       ;;
+       esac
+
+       return 0
+}
+
 modemmanager_check_state_locked() {
        local device="$1"
        local interface="$2"
        local modemstatus="$3"
        local pincode="$4"
 
+       local unlock_required unlock_retries unlock_retry unlock_lock
+       local unlock_value unlock_match
+
        if [ -z "$pincode" ]; then
                echo "PIN required"
                proto_notify_error "${interface}" MM_PINCODE_REQUIRED
@@ -345,6 +396,39 @@ modemmanager_check_state_locked() {
                return 1
        fi
 
+       unlock_required="$(modemmanager_get_field "${modemstatus}" "modem.generic.unlock-required")"
+       unlock_retries="$(modemmanager_get_multivalue_field "${modemstatus}" "modem.generic.unlock-retries")"
+
+       # Output of unlock-retries:
+       #   'sim-pin (3), sim-puk (10), sim-pin2 (3), sim-puk2 (10)'
+       # Replace alle '<spaces>' of unlock-retures with '', so we could
+       # iterate in the for loop. Replace result is:
+       #   'sim-pin(3),sim-puk(10),sim-pin2(3),sim-puk2(10)'
+       unlock_match=0
+       for unlock_retry in $(echo "${unlock_retries// /}" | tr "," "\n"); do
+               unlock_lock="${unlock_retry%%(*}"
+
+               # extract x value from 'sim-puk(x)' || 'sim-pin(x)'
+               unlock_value="${unlock_retry##*(}"
+               unlock_value="${unlock_value:0:-1}"
+
+               [ "$unlock_lock" = "$unlock_required" ] && {
+                       unlock_match=1
+                       modemmanager_check_state_lock_sim \
+                               "$interface" \
+                               "$unlock_lock" \
+                               "$unlock_value"
+                               [ "$?" -ne "0" ] && return 1
+               }
+       done
+
+       if [ "$unlock_match" = "0" ]; then
+               echo "unable to check PIN/PUK attempts"
+               proto_notify_error "${interface}" MM_CHECK_UNLOCK_UNKNOWN
+               proto_block_restart "${interface}"
+               return 1
+       fi
+
        mmcli --modem="${device}" -i any --pin=${pincode} || {
                proto_notify_error "${interface}" MM_PINCODE_WRONG
                proto_block_restart "${interface}"