modem: bind QMI primary-gw-provisioning session before USIM PIN verification and fix SIM2 target slot resolution

This commit is contained in:
Luxferre
2026-10-25 11:50:57 +02:00
parent b56f310f21
commit 33d3d225c1
4 changed files with 142 additions and 54 deletions
@@ -396,14 +396,14 @@ provision_slot() {
save_preferred_slot "$chosen_slot"
fi
# If already provisioned on the chosen slot and application is ready, keep session intact
# If already provisioned on the chosen slot and application is ready or waiting for PIN, keep session intact
eval "chosen_app_state=\$SLOT${chosen_slot}_APP_STATE"
if [ "$PRIMARY_GW_SLOT" = "$chosen_slot" ] && [ "$chosen_app_state" = "ready" ]; then
echo "Slot $chosen_slot already active and ready."
if [ "$PRIMARY_GW_SLOT" = "$chosen_slot" ] && { [ "$chosen_app_state" = "ready" ] || [ "$chosen_app_state" = "pin1-or-upin-pin-required" ] || [ "$chosen_app_state" = "puk1-or-upin-puk-required" ]; }; then
echo "Slot $chosen_slot already bound to primary-gw-provisioning ($chosen_app_state)."
return 0
fi
if [ "$PRIMARY_GW_SLOT" != "0" ] && [ "$PRIMARY_GW_SLOT" != "$chosen_slot" ]; then
if [ "$PRIMARY_GW_SLOT" != "0" ]; then
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
fi
@@ -419,8 +419,39 @@ provision_slot() {
return 0
}
prepare_slot_for_pin_op() {
req_slot="${1:-1}"
slot="$req_slot"
target_aid=""
if detect_qmicli_modem; then
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
if [ -n "$QMI_CARDS" ]; then
eval "$(parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT")"
if [ "$slot" = "1" ] && [ "$SLOT1_STATE" != "present" ] && [ "$SLOT2_STATE" = "present" ]; then
slot="2"
elif [ "$slot" = "2" ] && [ "$SLOT2_STATE" != "present" ] && [ "$SLOT1_STATE" = "present" ]; then
slot="1"
fi
eval "target_aid=\$SLOT${slot}_AID"
if [ "$PRIMARY_GW_SLOT" != "$slot" ]; then
if [ "$PRIMARY_GW_SLOT" != "0" ]; then
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
fi
if [ -n "$target_aid" ]; then
$QMICLI_MODEM --uim-change-provisioning-session="slot=$slot,activate=yes,session-type=primary-gw-provisioning,aid=$target_aid" >/dev/null 2>&1 || \
$QMICLI_MODEM --uim-change-provisioning-session="slot=$slot,activate=yes,session-type=primary-gw-provisioning" >/dev/null 2>&1 || true
else
$QMICLI_MODEM --uim-change-provisioning-session="slot=$slot,activate=yes,session-type=primary-gw-provisioning" >/dev/null 2>&1 || true
fi
sleep 0.6
fi
fi
fi
}
enable_and_register_modem() {
target_slot="${1:-$PREFERRED_SIM_SLOT}"
force_unlock="${2:-0}"
if detect_qmicli_modem; then
$QMICLI_MODEM --dms-set-operating-mode=online >/dev/null 2>&1 || true
$QMICLI_MODEM --nas-initiate-network-register >/dev/null 2>&1 || true
@@ -437,7 +468,7 @@ enable_and_register_modem() {
i=$((i + 1))
done
if [ "$mm_state" = "failed" ]; then
if [ "$mm_state" = "failed" ] || { [ "$force_unlock" = "1" ] && [ "$mm_state" = "locked" ]; }; then
if command -v rc-service >/dev/null 2>&1; then
rc-service modemmanager restart >/dev/null 2>&1 || true
elif command -v systemctl >/dev/null 2>&1; then
@@ -501,7 +532,7 @@ case "$cmd" in
;;
esac
provision_slot "$PREFERRED_SIM_SLOT" 45
( enable_and_register_modem "$PREFERRED_SIM_SLOT" ) >/dev/null 2>&1 </dev/null &
( enable_and_register_modem "$PREFERRED_SIM_SLOT" 0 ) >/dev/null 2>&1 </dev/null &
exit 0
;;
@@ -540,7 +571,7 @@ case "$cmd" in
elif command -v systemctl >/dev/null 2>&1; then
systemctl restart ModemManager >/dev/null 2>&1 || true
fi
( enable_and_register_modem "$target" ) >/dev/null 2>&1 </dev/null &
( enable_and_register_modem "$target" 0 ) >/dev/null 2>&1 </dev/null &
exit 0
;;
@@ -551,25 +582,53 @@ case "$cmd" in
echo "Missing PIN" >&2
exit 1
fi
prepare_slot_for_pin_op "$slot"
verified=0
if detect_qmicli_modem; then
if $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=card-slot-$slot" >/dev/null 2>&1; then
sim_id="$(mmcli -m any 2>/dev/null | grep -oE 'SIM/[0-9]+' | head -n1 | cut -d'/' -f2 || true)"
if [ -n "$sim_id" ] && mmcli -i "$sim_id" --pin="$pin" >/dev/null 2>&1; then
verified=1
fi
if [ "$verified" = "0" ] && [ -n "$QMICLI_MODEM" ]; then
if $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
verified=1
elif $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
elif $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=card-slot-$slot" >/dev/null 2>&1; then
verified=1
elif $QMICLI_MODEM --uim-verify-pin="PIN1,$pin" >/dev/null 2>&1; then
verified=1
elif $QMICLI_MODEM --uim-verify-pin="UPIN,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
verified=1
elif $QMICLI_MODEM --uim-verify-pin="UPIN,$pin,session-type=card-slot-$slot" >/dev/null 2>&1; then
verified=1
elif $QMICLI_MODEM --dms-uim-verify-pin="PIN,$pin" >/dev/null 2>&1; then
verified=1
fi
fi
if [ "$verified" = "0" ]; then
sim_id="$(mmcli -m any 2>/dev/null | grep -oE 'SIM/[0-9]+' | head -n1 | cut -d'/' -f2 || true)"
if [ -n "$sim_id" ] && mmcli -i "$sim_id" --pin="$pin" >/dev/null 2>&1; then
at_cpin="$("$0" at auto "AT+CPIN=\"$pin\"" 2>/dev/null || true)"
if printf "%s\n" "$at_cpin" | grep -qE "(^|[[:space:]])OK([[:space:]]|$)"; then
verified=1
fi
fi
if [ "$verified" = "0" ] && [ -n "$QMICLI_MODEM" ]; then
QMI_CARDS_AFTER="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
if [ -n "$QMI_CARDS_AFTER" ]; then
eval "$(parse_uim_card_status "$QMI_CARDS_AFTER" "$slot")"
eval "after_pin1=\$SLOT${slot}_PIN1_STATE"
eval "after_app=\$SLOT${slot}_APP_STATE"
if [ "$after_pin1" = "enabled-verified" ] || [ "$after_pin1" = "disabled" ] || [ "$after_app" = "ready" ]; then
verified=1
fi
fi
fi
if [ "$verified" = "1" ]; then
save_preferred_slot "$slot"
SIM_WAIT_TIME=2
provision_slot "$slot" 3 >/dev/null 2>&1 || true
( enable_and_register_modem "$slot" ) >/dev/null 2>&1 </dev/null &
if [ -n "$sim_id" ]; then
mmcli -i "$sim_id" --pin="$pin" >/dev/null 2>&1 || true
fi
mmcli -m any -e >/dev/null 2>&1 || true
( enable_and_register_modem "$slot" 1 ) >/dev/null 2>&1 </dev/null &
exit 0
fi
exit 1
@@ -583,17 +642,26 @@ case "$cmd" in
echo "Missing PUK or new PIN" >&2
exit 1
fi
prepare_slot_for_pin_op "$slot"
unblocked=0
if detect_qmicli_modem; then
if $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=card-slot-$slot" >/dev/null 2>&1; then
sim_id="$(mmcli -m any 2>/dev/null | grep -oE 'SIM/[0-9]+' | head -n1 | cut -d'/' -f2 || true)"
if [ -n "$sim_id" ] && mmcli -i "$sim_id" --puk="$puk" --pin="$newpin" >/dev/null 2>&1; then
unblocked=1
fi
if [ "$unblocked" = "0" ] && [ -n "$QMICLI_MODEM" ]; then
if $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
unblocked=1
elif $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
elif $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=card-slot-$slot" >/dev/null 2>&1; then
unblocked=1
elif $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin" >/dev/null 2>&1; then
unblocked=1
elif $QMICLI_MODEM --dms-uim-unblock-pin="PIN,$puk,$newpin" >/dev/null 2>&1; then
unblocked=1
fi
fi
if [ "$unblocked" = "0" ]; then
sim_id="$(mmcli -m any 2>/dev/null | grep -oE 'SIM/[0-9]+' | head -n1 | cut -d'/' -f2 || true)"
if [ -n "$sim_id" ] && mmcli -i "$sim_id" --puk="$puk" --pin="$newpin" >/dev/null 2>&1; then
at_cpin="$("$0" at auto "AT+CPIN=\"$puk\",\"$newpin\"" 2>/dev/null || true)"
if printf "%s\n" "$at_cpin" | grep -qE "(^|[[:space:]])OK([[:space:]]|$)"; then
unblocked=1
fi
fi
@@ -601,7 +669,8 @@ case "$cmd" in
save_preferred_slot "$slot"
SIM_WAIT_TIME=2
provision_slot "$slot" 3 >/dev/null 2>&1 || true
( enable_and_register_modem "$slot" ) >/dev/null 2>&1 </dev/null &
mmcli -m any -e >/dev/null 2>&1 || true
( enable_and_register_modem "$slot" 1 ) >/dev/null 2>&1 </dev/null &
exit 0
fi
exit 1
@@ -615,11 +684,15 @@ case "$cmd" in
echo "Usage: $0 set-pin-lock <1|2> <enable|disable> <pin>" >&2
exit 1
fi
if detect_qmicli_modem; then
prepare_slot_for_pin_op "$slot"
if [ -n "$QMICLI_MODEM" ]; then
if $QMICLI_MODEM --uim-set-pin-protection="PIN1,$mode,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
exit 0
fi
if $QMICLI_MODEM --uim-set-pin-protection="PIN1,$mode,$pin,session-type=card-slot-$slot" >/dev/null 2>&1; then
exit 0
fi
if $QMICLI_MODEM --uim-set-pin-protection="PIN1,$mode,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
if $QMICLI_MODEM --dms-uim-set-pin-protection="PIN,$mode,$pin" >/dev/null 2>&1; then
exit 0
fi
fi
@@ -642,11 +715,15 @@ case "$cmd" in
echo "Usage: $0 change-pin <1|2> <oldpin> <newpin>" >&2
exit 1
fi
if detect_qmicli_modem; then
prepare_slot_for_pin_op "$slot"
if [ -n "$QMICLI_MODEM" ]; then
if $QMICLI_MODEM --uim-change-pin="PIN1,$oldpin,$newpin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
exit 0
fi
if $QMICLI_MODEM --uim-change-pin="PIN1,$oldpin,$newpin,session-type=card-slot-$slot" >/dev/null 2>&1; then
exit 0
fi
if $QMICLI_MODEM --uim-change-pin="PIN1,$oldpin,$newpin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
if $QMICLI_MODEM --dms-uim-change-pin="PIN,$oldpin,$newpin" >/dev/null 2>&1; then
exit 0
fi
fi