uqmi: update to latest HEAD

This commit is contained in:
coolsnowwolf 2024-09-15 23:19:40 +08:00
parent ef272b46c0
commit 06366c30e7
2 changed files with 126 additions and 65 deletions

View File

@ -1,19 +1,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=uqmi
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git
PKG_SOURCE_DATE:=2022-05-04
PKG_SOURCE_VERSION:=56cb2d4056fef132ccf78dfb6f3074ae5d109992
PKG_MIRROR_HASH:=cc832b5318805df8c8387a3650f250dee72d5f1dbda4e4866b5503e186b2210c
PKG_SOURCE_DATE:=2024-08-25
PKG_SOURCE_VERSION:=28b48a10dbcd1177095b73c6d8086d10114f49b8
PKG_MIRROR_HASH:=bf1f8112c94ce49a7c03a4b9593141129d63ce679f98594257c1f6ab9bc49766
PKG_MAINTAINER:=Matti Laakso <malaakso@elisanet.fi>
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=
PKG_FLAGS:=nonshared
PKG_BUILD_FLAGS:=gc-sections
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
@ -31,20 +32,16 @@ define Package/uqmi/description
the QMI-protocol.
endef
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include -ffunction-sections -fdata-sections
ifneq (,$(findstring $(GCC_MAJOR_VERSION), 12 13))
TARGET_CFLAGS += -Wno-error=dangling-pointer -Wno-error=maybe-uninitialized
endif
TARGET_LDFLAGS += -Wl,--gc-sections
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-Wno-error=maybe-uninitialized
CMAKE_OPTIONS += \
-DDEBUG=1
define Package/uqmi/install
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi $(1)/sbin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi/uqmi $(1)/sbin/
$(CP) ./files/* $(1)/
endef

View File

@ -11,6 +11,7 @@ proto_qmi_init_config() {
no_device=1
proto_config_add_string "device:device"
proto_config_add_string apn
proto_config_add_string v6apn
proto_config_add_string auth
proto_config_add_string username
proto_config_add_string password
@ -19,8 +20,11 @@ proto_qmi_init_config() {
proto_config_add_string modes
proto_config_add_string pdptype
proto_config_add_int profile
proto_config_add_int v6profile
proto_config_add_boolean dhcp
proto_config_add_boolean dhcpv6
proto_config_add_boolean sourcefilter
proto_config_add_boolean delegate
proto_config_add_boolean autoconnect
proto_config_add_int plmn
proto_config_add_int timeout
@ -31,14 +35,15 @@ proto_qmi_init_config() {
proto_qmi_setup() {
local interface="$1"
local dataformat connstat plmn_mode mcc mnc
local device apn auth username password pincode delay modes pdptype
local profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS
local device apn v6apn auth username password pincode delay modes pdptype
local profile v6profile dhcp dhcpv6 autoconnect plmn timeout mtu $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
local profile_pdptype
json_get_vars device apn auth username password pincode delay modes
json_get_vars pdptype profile dhcp dhcpv6 autoconnect plmn ip4table
json_get_vars device apn v6apn auth username password pincode delay modes
json_get_vars pdptype profile v6profile dhcp dhcpv6 sourcefilter delegate autoconnect plmn ip4table
json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS
[ "$timeout" = "" ] && timeout="10"
@ -81,7 +86,9 @@ proto_qmi_setup() {
echo "Waiting for SIM initialization"
local uninitialized_timeout=0
while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
# timeout 3s for first call to avoid hanging uqmi
uqmi -d "$device" -t 3000 --get-pin-status > /dev/null 2>&1
while uqmi -s -d "$device" -t 1000 --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
[ -e "$device" ] || return 1
if [ "$uninitialized_timeout" -lt "$timeout" -o "$timeout" = "0" ]; then
let uninitialized_timeout++
@ -94,9 +101,41 @@ proto_qmi_setup() {
fi
done
if uqmi -s -d "$device" --get-pin-status | grep '"Not supported"\|"Invalid QMI command"' > /dev/null; then
# Check if UIM application is stuck in illegal state
local uim_state_timeout=0
while true; do
json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
json_get_var card_application_state card_application_state
# SIM card is either completely absent or state is labeled as illegal
# Try to power-cycle the SIM card to recover from this state
if [ -z "$card_application_state" -o "$card_application_state" = "illegal" ]; then
echo "SIM in illegal state - Power-cycling SIM"
# Try to reset SIM application
uqmi -d "$device" -t 1000 --uim-power-off --uim-slot 1
sleep 3
uqmi -d "$device" -t 1000 --uim-power-on --uim-slot 1
if [ "$uim_state_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
let uim_state_timeout++
sleep 1
continue
fi
# Recovery failed
proto_notify_error "$interface" SIM_ILLEGAL_STATE
proto_block_restart "$interface"
return 1
else
break
fi
done
if uqmi -s -d "$device" -t 1000 --uim-get-sim-state | grep -q '"Not supported"\|"Invalid QMI command"' &&
uqmi -s -d "$device" -t 1000 --get-pin-status | grep -q '"Not supported"\|"Invalid QMI command"' ; then
[ -n "$pincode" ] && {
uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null || {
uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null || {
echo "Unable to verify PIN"
proto_notify_error "$interface" PIN_FAILED
proto_block_restart "$interface"
@ -104,9 +143,12 @@ proto_qmi_setup() {
}
}
else
. /usr/share/libubox/jshn.sh
json_load "$(uqmi -s -d "$device" --get-pin-status)"
json_load "$(uqmi -s -d "$device" -t 1000 --get-pin-status)"
json_get_var pin1_status pin1_status
if [ -z "$pin1_status" ]; then
json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
json_get_var pin1_status pin1_status
fi
json_get_var pin1_verify_tries pin1_verify_tries
case "$pin1_status" in
@ -127,7 +169,7 @@ proto_qmi_setup() {
return 1
}
if [ -n "$pincode" ]; then
uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || {
uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || {
echo "Unable to verify PIN"
proto_notify_error "$interface" PIN_FAILED
proto_block_restart "$interface"
@ -144,16 +186,17 @@ proto_qmi_setup() {
echo "PIN already verified"
;;
*)
echo "PIN status failed ($pin1_status)"
echo "PIN status failed (${pin1_status:-sim_not_present})"
proto_notify_error "$interface" PIN_STATUS_FAILED
proto_block_restart "$interface"
return 1
;;
esac
json_cleanup
fi
if [ -n "$plmn" ]; then
json_load "$(uqmi -s -d "$device" --get-plmn)"
json_load "$(uqmi -s -d "$device" -t 1000 --get-plmn)"
json_get_var plmn_mode mode
json_get_vars mcc mnc || {
mcc=0
@ -176,25 +219,17 @@ proto_qmi_setup() {
fi
fi
if [ -n "$mcc" -a -n "$mnc" ]; then
uqmi -s -d "$device" --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || {
echo "Unable to set PLMN"
proto_notify_error "$interface" PLMN_FAILED
proto_block_restart "$interface"
return 1
}
fi
# Cleanup current state if any
uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-ip-family ipv6 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
# Go online
uqmi -s -d "$device" --set-device-operating-mode online > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-device-operating-mode online > /dev/null 2>&1
# Set IP format
uqmi -s -d "$device" --set-data-format 802.3 > /dev/null 2>&1
uqmi -s -d "$device" --wda-set-data-format 802.3 > /dev/null 2>&1
dataformat="$(uqmi -s -d "$device" --wda-get-data-format)"
uqmi -s -d "$device" -t 1000 --set-data-format 802.3 > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --wda-set-data-format 802.3 > /dev/null 2>&1
dataformat="$(uqmi -s -d "$device" -t 1000 --wda-get-data-format)"
if [ "$dataformat" = '"raw-ip"' ]; then
@ -207,16 +242,33 @@ proto_qmi_setup() {
echo "Y" > /sys/class/net/$ifname/qmi/raw_ip
fi
uqmi -s -d "$device" --sync > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --sync > /dev/null 2>&1
uqmi -s -d "$device" --network-register > /dev/null 2>&1
uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
# PLMN selection must happen after the call to network-register
if [ -n "$mcc" -a -n "$mnc" ]; then
uqmi -s -d "$device" -t 1000 --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || {
echo "Unable to set PLMN"
proto_notify_error "$interface" PLMN_FAILED
proto_block_restart "$interface"
return 1
}
fi
[ -n "$modes" ] && {
uqmi -s -d "$device" -t 1000 --set-network-modes "$modes" > /dev/null 2>&1
sleep 3
# Scan network to not rely on registration-timeout after RAT change
uqmi -s -d "$device" -t 30000 --network-scan > /dev/null 2>&1
}
echo "Waiting for network registration"
sleep 1
sleep 5
local registration_timeout=0
local registration_state=""
while true; do
registration_state=$(uqmi -s -d "$device" --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
registration_state=$(uqmi -s -d "$device" -t 1000 --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
[ "$registration_state" = "registered" ] && break
@ -224,7 +276,7 @@ proto_qmi_setup() {
if [ "$registration_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
[ "$registration_state" = "searching" ] || {
echo "Device stopped network registration. Restart network registration"
uqmi -s -d "$device" --network-register > /dev/null 2>&1
uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
}
let registration_timeout++
sleep 1
@ -237,17 +289,23 @@ proto_qmi_setup() {
fi
proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED
proto_block_restart "$interface"
return 1
done
[ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" > /dev/null 2>&1
echo "Starting network $interface"
pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
pdptype="$(echo "$pdptype" | awk '{print tolower($0)}')"
[ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
# Configure PDP type and APN for profile 1.
# In case GGSN rejects IPv4v6 PDP, modem might not be able to
# establish a non-LTE data session.
profile_pdptype="$pdptype"
[ "$profile_pdptype" = "ip" ] && profile_pdptype="ipv4"
uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,1" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
if [ "$pdptype" = "ip" ]; then
[ -z "$autoconnect" ] && autoconnect=1
[ "$autoconnect" = 0 ] && autoconnect=""
@ -256,16 +314,16 @@ proto_qmi_setup() {
fi
[ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && {
cid_4=$(uqmi -s -d "$device" --get-client-id wds)
cid_4=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then
echo "Unable to obtain client ID"
proto_notify_error "$interface" NO_CID
return 1
fi
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
pdh_4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" \
pdh_4=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_4" \
--start-network \
${apn:+--apn $apn} \
${profile:+--profile $profile} \
@ -277,35 +335,38 @@ proto_qmi_setup() {
# pdh_4 is a numeric value on success
if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then
echo "Unable to connect IPv4"
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
proto_notify_error "$interface" CALL_FAILED
return 1
fi
# Check data connection state
connstat=$(uqmi -s -d "$device" --get-data-status)
connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --get-data-status)
[ "$connstat" == '"connected"' ] || {
echo "No data link!"
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
proto_notify_error "$interface" CALL_FAILED
return 1
}
}
[ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && {
cid_6=$(uqmi -s -d "$device" --get-client-id wds)
cid_6=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then
echo "Unable to obtain client ID"
proto_notify_error "$interface" NO_CID
return 1
fi
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \
: "${v6apn:=${apn}}"
: "${v6profile:=${profile}}"
pdh_6=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_6" \
--start-network \
${apn:+--apn $apn} \
${profile:+--profile $profile} \
${v6apn:+--apn $v6apn} \
${v6profile:+--profile $v6profile} \
${auth:+--auth-type $auth} \
${username:+--username $username} \
${password:+--password $password} \
@ -314,16 +375,16 @@ proto_qmi_setup() {
# pdh_6 is a numeric value on success
if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then
echo "Unable to connect IPv6"
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
proto_notify_error "$interface" CALL_FAILED
return 1
fi
# Check data connection state
connstat=$(uqmi -s -d "$device" --get-data-status)
connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 --get-data-status)
[ "$connstat" == '"connected"' ] || {
echo "No data link!"
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
proto_notify_error "$interface" CALL_FAILED
return 1
}
@ -348,7 +409,7 @@ proto_qmi_setup() {
[ -n "$pdh_6" ] && {
if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)"
json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_6 --get-current-settings)"
json_select ipv6
json_get_var ip_6 ip
json_get_var gateway_6 gateway
@ -376,11 +437,14 @@ proto_qmi_setup() {
json_init
json_add_string name "${interface}_6"
json_add_string ifname "@$interface"
[ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0"
json_add_string proto "dhcpv6"
[ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
proto_add_dynamic_defaults
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
json_add_string extendprefix 1
[ "$delegate" = "0" ] && json_add_boolean delegate "0"
[ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
[ -n "$zone" ] && json_add_string zone "$zone"
json_close_object
ubus call network add_dynamic "$(json_dump)"
@ -389,7 +453,7 @@ proto_qmi_setup() {
[ -n "$pdh_4" ] && {
if [ "$dhcp" = 0 ]; then
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)"
json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_4 --get-current-settings)"
json_select ipv4
json_get_var ip_4 ip
json_get_var gateway_4 gateway
@ -432,16 +496,16 @@ qmi_wds_stop() {
[ -n "$cid" ] || return
uqmi -s -d "$device" --set-client-id wds,"$cid" \
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
--stop-network 0xffffffff \
--autoconnect > /dev/null 2>&1
[ -n "$pdh" ] && {
uqmi -s -d "$device" --set-client-id wds,"$cid" \
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
--stop-network "$pdh" > /dev/null 2>&1
}
uqmi -s -d "$device" --set-client-id wds,"$cid" \
uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
--release-client-id wds > /dev/null 2>&1
}