Fix SIM2 QMI UIM provisioning, auto-enable ModemManager, PIN auto-prompt, call audio, and Dunst clearing
This commit is contained in:
@@ -8,7 +8,7 @@ if [ -r "$CONF_FILE" ]; then
|
||||
. "$CONF_FILE"
|
||||
fi
|
||||
|
||||
SIM_WAIT_TIME="${SIM_WAIT_TIME:-${sim_wait_time:-4}}"
|
||||
SIM_WAIT_TIME="${SIM_WAIT_TIME:-${sim_wait_time:-10}}"
|
||||
PREFERRED_SIM_SLOT="${PREFERRED_SIM_SLOT:-${preferred_sim_slot:-1}}"
|
||||
QMICLI_MODEM=""
|
||||
|
||||
@@ -16,15 +16,25 @@ detect_qmicli_modem() {
|
||||
if ! command -v qmicli >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
if [ -e "/dev/modem" ]; then
|
||||
QMICLI_MODEM="qmicli --silent -d /dev/modem"
|
||||
return 0
|
||||
elif [ -e "/dev/wwan0qmi0" ]; then
|
||||
QMICLI_MODEM="qmicli --silent -d /dev/wwan0qmi0 --device-open-qmi"
|
||||
return 0
|
||||
elif qmicli --silent -pd qrtr://0 --uim-noop >/dev/null 2>&1; then
|
||||
if qmicli --silent -pd qrtr://0 --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="qmicli --silent -pd qrtr://0"
|
||||
return 0
|
||||
elif [ -e "/dev/wwan0qmi0" ]; then
|
||||
if qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi"
|
||||
return 0
|
||||
elif qmicli --silent -d /dev/wwan0qmi0 --device-open-qmi --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="qmicli --silent -d /dev/wwan0qmi0 --device-open-qmi"
|
||||
return 0
|
||||
fi
|
||||
elif [ -e "/dev/modem" ]; then
|
||||
if qmicli --silent -pd /dev/modem --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="qmicli --silent -pd /dev/modem"
|
||||
return 0
|
||||
elif qmicli --silent -d /dev/modem --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="qmicli --silent -d /dev/modem"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
@@ -64,6 +74,8 @@ parse_uim_card_status() {
|
||||
pin1_state[s] = "not-initialized"
|
||||
pin1_ret[s] = 0
|
||||
puk1_ret[s] = 0
|
||||
want_aid[s] = 0
|
||||
need_aid_line[s] = 0
|
||||
}
|
||||
}
|
||||
/Primary GW:/ {
|
||||
@@ -95,7 +107,7 @@ parse_uim_card_status() {
|
||||
}
|
||||
if (!in_app && $0 ~ /Card state:/) {
|
||||
line = $0
|
||||
sub(/.*Card state: \x27/, "", line)
|
||||
sub(/.*Card state:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
rawstate[cur_slot] = line
|
||||
if (line == "present") cstate[cur_slot] = "present"
|
||||
@@ -104,25 +116,25 @@ parse_uim_card_status() {
|
||||
}
|
||||
if (!in_app && $0 ~ /UPIN state:/) {
|
||||
line = $0
|
||||
sub(/.*UPIN state: \x27/, "", line)
|
||||
sub(/.*UPIN state:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
upin_state[cur_slot] = line
|
||||
}
|
||||
if (!in_app && $0 ~ /UPIN retries:/) {
|
||||
line = $0
|
||||
sub(/.*UPIN retries: \x27/, "", line)
|
||||
sub(/.*UPIN retries:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
upin_ret[cur_slot] = line + 0
|
||||
}
|
||||
if (!in_app && $0 ~ /UPUK retries:/) {
|
||||
line = $0
|
||||
sub(/.*UPUK retries: \x27/, "", line)
|
||||
sub(/.*UPUK retries:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
upuk_ret[cur_slot] = line + 0
|
||||
}
|
||||
if (in_app && $0 ~ /Application type:/) {
|
||||
line = $0
|
||||
sub(/.*Application type: \x27/, "", line)
|
||||
sub(/.*Application type:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
if (line ~ /^usim/) {
|
||||
app_type[cur_slot] = "usim"
|
||||
@@ -130,13 +142,16 @@ parse_uim_card_status() {
|
||||
} else if (line ~ /^sim/ && app_type[cur_slot] != "usim") {
|
||||
app_type[cur_slot] = "sim"
|
||||
want_aid[cur_slot] = 1
|
||||
} else if (app_type[cur_slot] == "none") {
|
||||
app_type[cur_slot] = "sim"
|
||||
want_aid[cur_slot] = 1
|
||||
} else {
|
||||
want_aid[cur_slot] = 0
|
||||
}
|
||||
}
|
||||
if (in_app && $0 ~ /Application state:/ && want_aid[cur_slot] > 0) {
|
||||
line = $0
|
||||
sub(/.*Application state: \x27/, "", line)
|
||||
sub(/.*Application state:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
app_state[cur_slot] = line
|
||||
}
|
||||
@@ -147,26 +162,26 @@ parse_uim_card_status() {
|
||||
if (in_app && need_aid_line[cur_slot] == 1) {
|
||||
line = $0
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
|
||||
if (line != "") {
|
||||
if (line != "" && line !~ /:.*\x27/) {
|
||||
aid[cur_slot] = line
|
||||
}
|
||||
need_aid_line[cur_slot] = 0
|
||||
}
|
||||
if (in_app && $0 ~ /PIN1 state:/ && want_aid[cur_slot] > 0) {
|
||||
line = $0
|
||||
sub(/.*PIN1 state: \x27/, "", line)
|
||||
sub(/.*PIN1 state:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
pin1_state[cur_slot] = line
|
||||
}
|
||||
if (in_app && $0 ~ /PIN1 retries:/ && want_aid[cur_slot] > 0) {
|
||||
line = $0
|
||||
sub(/.*PIN1 retries: \x27/, "", line)
|
||||
sub(/.*PIN1 retries:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
pin1_ret[cur_slot] = line + 0
|
||||
}
|
||||
if (in_app && $0 ~ /PUK1 retries:/ && want_aid[cur_slot] > 0) {
|
||||
line = $0
|
||||
sub(/.*PUK1 retries: \x27/, "", line)
|
||||
sub(/.*PUK1 retries:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
puk1_ret[cur_slot] = line + 0
|
||||
}
|
||||
@@ -192,8 +207,116 @@ parse_uim_card_status() {
|
||||
'
|
||||
}
|
||||
|
||||
parse_nas_serving_system() {
|
||||
raw_nas="$1"
|
||||
printf "%s\n" "$raw_nas" | awk '
|
||||
BEGIN {
|
||||
reg_state = "unknown"
|
||||
cs_state = "unknown"
|
||||
ps_state = "unknown"
|
||||
rat = ""
|
||||
mcc = ""
|
||||
mnc = ""
|
||||
op_desc = ""
|
||||
roam = "off"
|
||||
in_rat = 0
|
||||
in_plmn = 0
|
||||
in_roam = 0
|
||||
}
|
||||
/^[[:space:]]*Registration state:/ {
|
||||
line = $0
|
||||
sub(/.*Registration state:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
reg_state = line
|
||||
in_rat = 0; in_plmn = 0; in_roam = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*CS:/ {
|
||||
line = $0
|
||||
sub(/.*CS:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
cs_state = line
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*PS:/ {
|
||||
line = $0
|
||||
sub(/.*PS:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
ps_state = line
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*Radio interfaces:/ {
|
||||
in_rat = 1; in_plmn = 0; in_roam = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*Data service capabilities:/ {
|
||||
in_rat = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*Current PLMN:/ {
|
||||
in_plmn = 1; in_rat = 0; in_roam = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*Roaming indicators:/ {
|
||||
in_roam = 1; in_plmn = 0; in_rat = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*Default roaming status:/ {
|
||||
line = $0
|
||||
sub(/.*Default roaming status:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
roam = line
|
||||
in_roam = 0
|
||||
next
|
||||
}
|
||||
in_rat && /^[[:space:]]*\[[0-9]+\]:/ {
|
||||
line = $0
|
||||
sub(/.*\[[0-9]+\]:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
if (line != "" && line != "none" && rat == "") rat = line
|
||||
}
|
||||
in_plmn && /MCC:/ {
|
||||
line = $0
|
||||
sub(/.*MCC:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
mcc = line
|
||||
}
|
||||
in_plmn && /MNC:/ {
|
||||
line = $0
|
||||
sub(/.*MNC:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
mnc = line
|
||||
}
|
||||
in_plmn && /Description:/ {
|
||||
line = $0
|
||||
sub(/.*Description:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
gsub(/[\r\n\t]/, " ", line)
|
||||
op_desc = line
|
||||
in_plmn = 0
|
||||
}
|
||||
in_roam && /^[[:space:]]*\[[0-9]+\]:/ {
|
||||
line = $0
|
||||
sub(/.*\[[0-9]+\]:[[:space:]]*\x27/, "", line)
|
||||
sub(/\x27.*/, "", line)
|
||||
if (line == "on") roam = "on"
|
||||
}
|
||||
END {
|
||||
printf "NAS_REG_STATE=%s\n", reg_state
|
||||
printf "NAS_CS_STATE=%s\n", cs_state
|
||||
printf "NAS_PS_STATE=%s\n", ps_state
|
||||
printf "NAS_RAT=%s\n", rat
|
||||
printf "NAS_MCC=%s\n", mcc
|
||||
printf "NAS_MNC=%s\n", mnc
|
||||
printf "NAS_OPERATOR=%s\n", op_desc
|
||||
printf "NAS_ROAMING=%s\n", roam
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
save_preferred_slot() {
|
||||
target_slot="$1"
|
||||
PREFERRED_SIM_SLOT="$target_slot"
|
||||
if [ -f "$CONF_FILE" ]; then
|
||||
if grep -q "^preferred_sim_slot=" "$CONF_FILE"; then
|
||||
sed -i "s/^preferred_sim_slot=.*/preferred_sim_slot=$target_slot/" "$CONF_FILE"
|
||||
@@ -201,7 +324,7 @@ save_preferred_slot() {
|
||||
printf "\npreferred_sim_slot=%s\n" "$target_slot" >> "$CONF_FILE"
|
||||
fi
|
||||
else
|
||||
printf "sim_wait_time=4\npreferred_sim_slot=%s\n" "$target_slot" > "$CONF_FILE"
|
||||
printf "sim_wait_time=10\npreferred_sim_slot=%s\n" "$target_slot" > "$CONF_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -214,52 +337,154 @@ provision_slot() {
|
||||
return 2
|
||||
fi
|
||||
|
||||
$QMICLI_MODEM --dms-set-operating-mode=online >/dev/null 2>&1 || true
|
||||
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
count=0
|
||||
while ! printf "%s" "$QMI_CARDS" | grep -Fq "Card state: 'present'"; do
|
||||
while : ; do
|
||||
if [ -n "$QMI_CARDS" ]; then
|
||||
eval "$(parse_uim_card_status "$QMI_CARDS" "$req_slot")"
|
||||
if [ "$req_slot" = "2" ] && [ "$SLOT2_STATE" = "present" ] && [ "$SLOT2_APP_TYPE" != "none" ]; then
|
||||
break
|
||||
elif [ "$req_slot" != "2" ] && [ "$SLOT1_STATE" = "present" ] && [ "$SLOT1_APP_TYPE" != "none" ]; then
|
||||
break
|
||||
elif [ "$count" -ge 3 ] && { { [ "$SLOT1_STATE" = "present" ] && [ "$SLOT1_APP_TYPE" != "none" ]; } || { [ "$SLOT2_STATE" = "present" ] && [ "$SLOT2_APP_TYPE" != "none" ]; }; }; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
if [ "$count" -ge "$SIM_WAIT_TIME" ]; then
|
||||
echo "No SIM detected after $SIM_WAIT_TIME seconds."
|
||||
return 0
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
count=$((count + 1))
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
done
|
||||
|
||||
if [ -z "$QMI_CARDS" ]; then
|
||||
echo "No SIM card status returned."
|
||||
return 0
|
||||
fi
|
||||
|
||||
eval "$(parse_uim_card_status "$QMI_CARDS" "$req_slot")"
|
||||
|
||||
chosen_slot=""
|
||||
chosen_aid=""
|
||||
if [ "$req_slot" = "2" ]; then
|
||||
if [ "$SLOT2_STATE" = "present" ] && [ -n "$SLOT2_AID" ]; then
|
||||
if [ "$SLOT2_STATE" = "present" ]; then
|
||||
chosen_slot="2"
|
||||
chosen_aid="$SLOT2_AID"
|
||||
elif [ "$SLOT1_STATE" = "present" ] && [ -n "$SLOT1_AID" ]; then
|
||||
elif [ "$SLOT1_STATE" = "present" ]; then
|
||||
chosen_slot="1"
|
||||
chosen_aid="$SLOT1_AID"
|
||||
fi
|
||||
else
|
||||
if [ "$SLOT1_STATE" = "present" ] && [ -n "$SLOT1_AID" ]; then
|
||||
if [ "$SLOT1_STATE" = "present" ]; then
|
||||
chosen_slot="1"
|
||||
chosen_aid="$SLOT1_AID"
|
||||
elif [ "$SLOT2_STATE" = "present" ] && [ -n "$SLOT2_AID" ]; then
|
||||
elif [ "$SLOT2_STATE" = "present" ]; then
|
||||
chosen_slot="2"
|
||||
chosen_aid="$SLOT2_AID"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$chosen_slot" ] || [ -z "$chosen_aid" ]; then
|
||||
echo "No valid USIM/SIM application found on any slot."
|
||||
if [ -z "$chosen_slot" ]; then
|
||||
echo "No SIM detected after $SIM_WAIT_TIME seconds."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$PRIMARY_GW_SLOT" != "0" ]; then
|
||||
if [ "$chosen_slot" != "$PREFERRED_SIM_SLOT" ]; then
|
||||
save_preferred_slot "$chosen_slot"
|
||||
fi
|
||||
|
||||
# If already provisioned on the chosen slot and application is ready, 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."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$PRIMARY_GW_SLOT" != "0" ] && [ "$PRIMARY_GW_SLOT" != "$chosen_slot" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
echo "Selecting AID $chosen_aid on slot $chosen_slot"
|
||||
$QMICLI_MODEM --uim-change-provisioning-session="slot=$chosen_slot,activate=yes,session-type=primary-gw-provisioning,aid=$chosen_aid" >/dev/null
|
||||
return $?
|
||||
if [ -n "$chosen_aid" ]; then
|
||||
echo "Selecting AID $chosen_aid on slot $chosen_slot"
|
||||
if ! $QMICLI_MODEM --uim-change-provisioning-session="slot=$chosen_slot,activate=yes,session-type=primary-gw-provisioning,aid=$chosen_aid" >/dev/null 2>&1; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session="slot=$chosen_slot,activate=yes,session-type=primary-gw-provisioning" >/dev/null 2>&1 || true
|
||||
fi
|
||||
else
|
||||
echo "Selecting slot $chosen_slot"
|
||||
$QMICLI_MODEM --uim-change-provisioning-session="slot=$chosen_slot,activate=yes,session-type=primary-gw-provisioning" >/dev/null 2>&1 || true
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
enable_and_register_modem() {
|
||||
target_slot="${1:-$PREFERRED_SIM_SLOT}"
|
||||
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
|
||||
fi
|
||||
|
||||
i=0
|
||||
mm_state=""
|
||||
while [ "$i" -lt 12 ]; do
|
||||
mm_state="$(mmcli -m any -K 2>/dev/null | awk -F': ' '/^modem\.generic\.state / {print $2; exit}' || true)"
|
||||
if [ -n "$mm_state" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [ "$mm_state" = "failed" ]; 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
|
||||
systemctl restart ModemManager >/dev/null 2>&1 || true
|
||||
fi
|
||||
i=0
|
||||
mm_state=""
|
||||
while [ "$i" -lt 12 ]; do
|
||||
mm_state="$(mmcli -m any -K 2>/dev/null | awk -F': ' '/^modem\.generic\.state / {print $2; exit}' || true)"
|
||||
if [ -n "$mm_state" ] && [ "$mm_state" != "failed" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$mm_state" ] || [ "$mm_state" = "locked" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [ "$i" -lt 10 ]; do
|
||||
mm_state="$(mmcli -m any -K 2>/dev/null | awk -F': ' '/^modem\.generic\.state / {print $2; exit}' || true)"
|
||||
case "$mm_state" in
|
||||
disabled)
|
||||
mmcli -m any -e >/dev/null 2>&1 || true
|
||||
;;
|
||||
enabled)
|
||||
mmcli -m any --3gpp-register-home >/dev/null 2>&1 || true
|
||||
break
|
||||
;;
|
||||
searching|registered|connected|connecting)
|
||||
break
|
||||
;;
|
||||
locked)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
mmcli -m any --3gpp-register-home >/dev/null 2>&1 || true
|
||||
if command -v sxmo_hook_statusbar.sh >/dev/null 2>&1; then
|
||||
DISPLAY="${DISPLAY:-:0}" sxmo_hook_statusbar.sh modem >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
cmd="${1:-boot}"
|
||||
@@ -276,7 +501,8 @@ case "$cmd" in
|
||||
;;
|
||||
esac
|
||||
provision_slot "$PREFERRED_SIM_SLOT" 45
|
||||
exit $?
|
||||
( enable_and_register_modem "$PREFERRED_SIM_SLOT" ) >/dev/null 2>&1 </dev/null &
|
||||
exit 0
|
||||
;;
|
||||
|
||||
status)
|
||||
@@ -293,6 +519,10 @@ case "$cmd" in
|
||||
fi
|
||||
echo "MODEM_AVAILABLE=1"
|
||||
parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT"
|
||||
QMI_NAS="$($QMICLI_MODEM --nas-get-serving-system 2>/dev/null || true)"
|
||||
if [ -n "$QMI_NAS" ]; then
|
||||
parse_nas_serving_system "$QMI_NAS"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
|
||||
@@ -303,13 +533,14 @@ case "$cmd" in
|
||||
exit 1
|
||||
fi
|
||||
save_preferred_slot "$target"
|
||||
SIM_WAIT_TIME=2
|
||||
SIM_WAIT_TIME=3
|
||||
provision_slot "$target" 5
|
||||
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
|
||||
systemctl restart ModemManager >/dev/null 2>&1 || true
|
||||
fi
|
||||
( enable_and_register_modem "$target" ) >/dev/null 2>&1 </dev/null &
|
||||
exit 0
|
||||
;;
|
||||
|
||||
@@ -320,18 +551,27 @@ case "$cmd" in
|
||||
echo "Missing PIN" >&2
|
||||
exit 1
|
||||
fi
|
||||
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
|
||||
exit 0
|
||||
fi
|
||||
verified=0
|
||||
if detect_qmicli_modem; then
|
||||
if $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
if $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=card-slot-$slot" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
verified=1
|
||||
elif $QMICLI_MODEM --uim-verify-pin="PIN1,$pin,session-type=primary-gw-provisioning" >/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
|
||||
verified=1
|
||||
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 &
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -343,18 +583,27 @@ case "$cmd" in
|
||||
echo "Missing PUK or new PIN" >&2
|
||||
exit 1
|
||||
fi
|
||||
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
|
||||
exit 0
|
||||
fi
|
||||
unblocked=0
|
||||
if detect_qmicli_modem; then
|
||||
if $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=primary-gw-provisioning" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
if $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=card-slot-$slot" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
unblocked=1
|
||||
elif $QMICLI_MODEM --uim-unblock-pin="PIN1,$puk,$newpin,session-type=primary-gw-provisioning" >/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
|
||||
unblocked=1
|
||||
fi
|
||||
fi
|
||||
if [ "$unblocked" = "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 &
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -366,6 +615,14 @@ case "$cmd" in
|
||||
echo "Usage: $0 set-pin-lock <1|2> <enable|disable> <pin>" >&2
|
||||
exit 1
|
||||
fi
|
||||
if detect_qmicli_modem; then
|
||||
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
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
sim_id="$(mmcli -m any 2>/dev/null | grep -oE 'SIM/[0-9]+' | head -n1 | cut -d'/' -f2 || true)"
|
||||
if [ -n "$sim_id" ]; then
|
||||
if [ "$mode" = "enable" ] && mmcli -i "$sim_id" --enable-pin --pin="$pin" >/dev/null 2>&1; then
|
||||
@@ -374,14 +631,6 @@ case "$cmd" in
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
if detect_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
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -393,17 +642,17 @@ case "$cmd" in
|
||||
echo "Usage: $0 change-pin <1|2> <oldpin> <newpin>" >&2
|
||||
exit 1
|
||||
fi
|
||||
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" --change-pin="$newpin" --pin="$oldpin" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
if detect_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
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
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" --change-pin="$newpin" --pin="$oldpin" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
@@ -505,7 +754,12 @@ case "$cmd" in
|
||||
exit 1
|
||||
fi
|
||||
resp=""
|
||||
for candidate in "$port" /dev/wwan0at1 /dev/wwan0at0; do
|
||||
if [ "$PREFERRED_SIM_SLOT" = "2" ]; then
|
||||
at_candidates="$port /dev/wwan0at1 /dev/wwan0at0"
|
||||
else
|
||||
at_candidates="$port /dev/wwan0at0 /dev/wwan0at1"
|
||||
fi
|
||||
for candidate in $at_candidates; do
|
||||
case "$candidate" in
|
||||
wwan0at0|wwan0at1)
|
||||
dev="/dev/$candidate"
|
||||
@@ -518,7 +772,7 @@ case "$cmd" in
|
||||
;;
|
||||
esac
|
||||
if [ -n "$dev" ] && [ -c "$dev" ]; then
|
||||
resp="$(timeout 2 sh -c '
|
||||
resp="$(timeout 3 sh -c '
|
||||
dev="$1"
|
||||
cmd="$2"
|
||||
tmpf="/tmp/at_resp_$$.txt"
|
||||
@@ -528,7 +782,7 @@ case "$cmd" in
|
||||
sleep 0.04
|
||||
printf "%s\r\n" "$cmd" > "$dev" 2>/dev/null || true
|
||||
i=0
|
||||
while [ "$i" -lt 12 ]; do
|
||||
while [ "$i" -lt 16 ]; do
|
||||
if grep -qE "(^|[[:space:]])(OK|ERROR|\+CME ERROR|\+CMS ERROR)([[:space:]]|$)" "$tmpf" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
@@ -558,6 +812,84 @@ case "$cmd" in
|
||||
exit 1
|
||||
;;
|
||||
|
||||
ussd)
|
||||
ussd_mode="${2:-initiate}"
|
||||
shift 2 2>/dev/null || true
|
||||
ussd_code="$*"
|
||||
if [ "$ussd_mode" = "cancel" ]; then
|
||||
mmcli -m any --3gpp-ussd-cancel >/dev/null 2>&1 || true
|
||||
"$0" at auto 'AT+CUSD=2' >/dev/null 2>&1 || true
|
||||
echo "USSD session cancelled."
|
||||
exit 0
|
||||
fi
|
||||
if [ -z "$ussd_code" ]; then
|
||||
echo "ERROR: Empty USSD code"
|
||||
exit 1
|
||||
fi
|
||||
mm_state="$(mmcli -m any -K 2>/dev/null | awk -F': ' '$1 == "modem.generic.state" {print $2; exit}')"
|
||||
if [ "$mm_state" = "disabled" ] || [ -z "$mm_state" ]; then
|
||||
mmcli -m any -e >/dev/null 2>&1 || true
|
||||
sleep 1
|
||||
fi
|
||||
if [ "$ussd_mode" = "respond" ]; then
|
||||
mm_out="$(mmcli -m any --3gpp-ussd-respond="$ussd_code" 2>&1)"
|
||||
mm_rc=$?
|
||||
else
|
||||
mmcli -m any --3gpp-ussd-cancel >/dev/null 2>&1 || true
|
||||
mm_out="$(mmcli -m any --3gpp-ussd-initiate="$ussd_code" 2>&1)"
|
||||
mm_rc=$?
|
||||
fi
|
||||
if [ "$mm_rc" -eq 0 ] && [ -n "$mm_out" ]; then
|
||||
printf "%s\n" "$mm_out" | sed -e "s/^USSD session initiated; new reply from network: '\(.*\)'$/\1/" -e "s/^USSD response sent; new reply from network: '\(.*\)'$/\1/"
|
||||
exit 0
|
||||
fi
|
||||
# Fallback to direct AT+CUSD on the active SIM AT port
|
||||
if [ "$PREFERRED_SIM_SLOT" = "2" ]; then
|
||||
at_candidates="/dev/wwan0at1 /dev/wwan0at0"
|
||||
else
|
||||
at_candidates="/dev/wwan0at0 /dev/wwan0at1"
|
||||
fi
|
||||
for dev in $at_candidates; do
|
||||
[ -c "$dev" ] || continue
|
||||
cusd_out="$(timeout 12 sh -c '
|
||||
dev="$1"
|
||||
code="$2"
|
||||
tmpf="/tmp/ussd_resp_$$.txt"
|
||||
rm -f "$tmpf"
|
||||
cat "$dev" > "$tmpf" 2>/dev/null &
|
||||
rpid=$!
|
||||
sleep 0.05
|
||||
printf "AT+CSCS=\"GSM\";+CUSD=1,\"%s\",15\r\n" "$code" > "$dev" 2>/dev/null || true
|
||||
i=0
|
||||
while [ "$i" -lt 80 ]; do
|
||||
if grep -qE "\+CUSD:[[:space:]]*[0-9]+" "$tmpf" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
if grep -qE "(^|[[:space:]])(\+CME ERROR|\+CMS ERROR|ERROR)([[:space:]]|$)" "$tmpf" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
i=$((i + 1))
|
||||
done
|
||||
kill "$rpid" 2>/dev/null || true
|
||||
wait "$rpid" 2>/dev/null || true
|
||||
tr -d "\r" < "$tmpf" 2>/dev/null || true
|
||||
rm -f "$tmpf"
|
||||
' _ "$dev" "$ussd_code" 2>/dev/null || true)"
|
||||
cusd_msg="$(printf "%s\n" "$cusd_out" | sed -n 's/.*+CUSD:[[:space:]]*[0-9]*,[[:space:]]*"\([^"]*\)".*/\1/p' | tail -n1)"
|
||||
if [ -n "$cusd_msg" ]; then
|
||||
printf "%s\n" "$cusd_msg"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
if [ -n "$mm_out" ]; then
|
||||
printf "%s\n" "$mm_out"
|
||||
else
|
||||
echo "ERROR: USSD request failed"
|
||||
fi
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sim-contacts-import)
|
||||
req_slot="${2:-auto}"
|
||||
if ! wait_for_qmicli_modem 3; then
|
||||
@@ -688,8 +1020,8 @@ case "$cmd" in
|
||||
# Method 2: Direct QMI UIM EF_ADN (3F00:7F10:6F3A) record fallback
|
||||
if [ ! -s "$tmp_contacts" ]; then
|
||||
adn_attr="$($QMICLI_MODEM --uim-get-file-attributes=0x3F00,0x7F10,0x6F3A 2>/dev/null || true)"
|
||||
reclen="$(printf "%s\n" "$adn_attr" | awk -F"'" '/Record length:/ {print $2 + 0; exit}')"
|
||||
reccount="$(printf "%s\n" "$adn_attr" | awk -F"'" '/Record count:/ {print $2 + 0; exit}')"
|
||||
reclen="$(printf "%s\n" "$adn_attr" | awk '/Record (size|length):/ {gsub(/[^0-9]/, "", $NF); print $NF + 0; exit}')"
|
||||
reccount="$(printf "%s\n" "$adn_attr" | awk '/Record count:/ {gsub(/[^0-9]/, "", $NF); print $NF + 0; exit}')"
|
||||
if [ -n "$reclen" ] && [ -n "$reccount" ] && [ "$reclen" -ge 14 ] 2>/dev/null && [ "$reccount" -ge 1 ] 2>/dev/null; then
|
||||
if [ "$reccount" -gt 250 ]; then
|
||||
reccount=250
|
||||
|
||||
Reference in New Issue
Block a user