Skip to content

Instantly share code, notes, and snippets.

@TravMurav
Last active June 29, 2021 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TravMurav/90bdd89f492bc39004d8ffb3d722f771 to your computer and use it in GitHub Desktop.
Save TravMurav/90bdd89f492bc39004d8ffb3d722f771 to your computer and use it in GitHub Desktop.
#!/sbin/openrc-run
# This script tries to automatically configure UIM application for Qualcomm QMI
# modems with more than one sim slot.
# Installation:
#
# sudo apk add libqmi
# wget https://gist.githubusercontent.com/TravMurav/90bdd89f492bc39004d8ffb3d722f771/raw/msm-uim-init
# chmod +x msm-uim-init
# sudo mv msm-uim-init /etc/init.d/
# sudo rc-update add msm-uim-init
#
name="UIM Slot selection"
description="Select UIM slot and application on the embedded QMI nodem."
depend() {
need rmtfs
before ofono
before modemmanager
# FIXME: This service may delay boot for some time, make sure that it
# runs after UI and sshd so preceived boot time isn't affected.
after tinydm
after sshd
}
# All of the logic is placed in the service start method as we want to block
# other services while the modem isn't ready yet.
start() {
# libqmi must be present to use this script.
if ! [ -x "$(command -v qmicli)" ]
then
eend 1 'qmicli is not installed.'
return 1
fi
# Prepare a qmicli command with desired modem path.
# The modem may appear after some delay, wait for it.
count=0
while [ -z "$QMICLI_MODEM" ] && [ "$count" -lt "45" ]
do
# Check if legacy rpmsg exported device exists.
if [ -e "/dev/modem" ]
then
QMICLI_MODEM="qmicli --silent -d /dev/modem"
veinfo "Using /dev/modem"
# Check if the qmi device from wwan driver exists.
elif [ -e "/dev/wwan0qmi0" ]
then
QMICLI_MODEM="qmicli --silent -d /dev/wwan0qmi0 --device-open-qmi"
veinfo "Using /dev/wwan0qmi0"
# Check if QRTR is available for new devices.
elif qmicli --silent -pd qrtr://0 --uim-noop > /dev/null
then
QMICLI_MODEM="qmicli --silent -pd qrtr://0"
veinfo "Using qrtr://0"
fi
sleep 1
count=$((count+1))
done
veinfo "Waited $count seconds for modem device to appear"
if [ -z "$QMICLI_MODEM" ]
then
eend 2 'No modem available.'
return 2
fi
QMI_CARDS=$($QMICLI_MODEM --uim-get-card-status)
# Fail if all slots are empty but wait a bit for the sim to appear.
count=0
while ! printf "$QMI_CARDS" | grep -Fq "Card state: 'present'" && [ "$count" -lt "11" ]
do
sleep 1
count=$((count+1))
QMI_CARDS=$($QMICLI_MODEM --uim-get-card-status)
done
if [ "$count" -gt "10" ]
then
eend 4 'No sim present.'
return 4
fi
veinfo "Waited $count seconds for modem to come up"
# Clear the selected application in case the modem is in a bugged state
if ! printf "$QMI_CARDS" | grep -Fq "Primary GW: session doesn't exist"
then
ewarn 'Application was already selected.'
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' > /dev/null
fi
# FIXME: There seems to be some race condition in some modem firmware
# that makes it report "SIM missing" on legacy interface that
# ModemManager uses. This causes MM to fail with same error despite UIM
# being actually present. Keep the delay until MM stops using that
# legacy interface.
vewarn "Delaying modem init..."
sleep 12
# Extract first available slot number and AID for usim application
# on it. This should select proper slot out of two if only one UIM is
# present or select the first one if both slots have UIM's in them.
FIRST_PRESENT_SLOT=$(printf "$QMI_CARDS" | grep "Card state: 'present'" -m1 -B1 | head -n1 | cut -c7-7)
FIRST_PRESENT_AID=$(printf "$QMI_CARDS" | grep "usim (2)" -m1 -A3 | tail -n1 | awk '{print $1}')
veinfo "Selecting $FIRST_PRESENT_AID on slot $FIRST_PRESENT_SLOT"
# Finally send the new configuration to the modem.
$QMICLI_MODEM --uim-change-provisioning-session="slot=$FIRST_PRESENT_SLOT,activate=yes,session-type=primary-gw-provisioning,aid=$FIRST_PRESENT_AID" > /dev/null
eend $?
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment