diff --git a/feeds/ucentral/modemmanager/files/modemmanager.init b/feeds/ucentral/modemmanager/files/modemmanager.init index 5258807e8..7f014dc56 100755 --- a/feeds/ucentral/modemmanager/files/modemmanager.init +++ b/feeds/ucentral/modemmanager/files/modemmanager.init @@ -36,14 +36,3 @@ start_service() { procd_set_param pidfile "${MODEMMANAGER_PID_FILE}" procd_close_instance } - -reload_service() -{ - stop - start -} - -service_triggers() -{ - procd_add_reload_trigger network -} diff --git a/feeds/ucentral/modemmanager/files/modemmanager.proto b/feeds/ucentral/modemmanager/files/modemmanager.proto index e97b768d0..4bf7a3ddb 100755 --- a/feeds/ucentral/modemmanager/files/modemmanager.proto +++ b/feeds/ucentral/modemmanager/files/modemmanager.proto @@ -403,6 +403,101 @@ modemmanager_set_preferred_mode() { } } +exec_at_command() { + local at_command=$1 + local serial_dev=$2 + + local resp_file="/tmp/at_response.txt" + local cmd_timeout=1 + local retry_limit=3 + local i=0 + local socat_pid reader_pid + + while [ $i -lt ${retry_limit} ]; do + # Flush old data + > ${resp_file} + + echo "${at_command}" | socat - /dev/${serial_dev},crnl & + socat_pid=$! + + { + cat /dev/${serial_dev} > ${resp_file} & + reader_pid=$! + sleep ${cmd_timeout} + kill -9 ${reader_pid} 2>/dev/null + } + + kill -9 ${socat_pid} 2>/dev/null + + case $(cat ${resp_file}) in + *OK*) + echo "AT command executed successfully" + break + ;; + *) + echo -n "AT command failed or no response" + [ -n "$i" ] && echo ", retry $i" || echo + ;; + esac + + let "i++" + done + + rm -f ${resp_file} +} + +_mm_get_processed_device() { + local mm_rundir="/var/run/modemmanager" + local mm_sysfs_cache="${mm_rundir}/sysfs.cache" + + awk -v status="processed" '!/^#/ && $0 ~ status {print $1}' "${mm_sysfs_cache}" +} + +proto_modemmanager_quectel_setup() { + local apn username password pdptype + local manufacturer ser_port context_id context_type at_command + json_get_vars apn username password pdptype + + local device=$(_mm_get_processed_device) + [ -n "${device}" ] || { + echo "No processed device" + return 1 + } + + # validate that ModemManager is handling the modem at the sysfs path + modemstatus=$(mmcli --modem="${device}" --output-keyvalue) + modempath=$(modemmanager_get_field "${modemstatus}" "modem.dbus-path") + [ -n "${modempath}" ] || { + echo "Device not managed by ModemManager" + return 1 + } + echo "modem available at ${modempath}" + + # workaround for Quectel embedded TCP/IP Stack + manufacturer=$(modemmanager_get_field "${modemstatus}" "modem.generic.manufacturer") + ser_port=$(mmcli --modem="${device}" -K | grep modem.generic.ports | grep tty | awk '{print $3}' | head -n 1) + if [ "${manufacturer}" = "Quectel" ]; then + echo "setup TCP/IP Context" + case "${pdptype}" in + ip) + context_type=1 + ;; + ipv6) + context_type=2 + ;; + ipv4v6|*) + context_type=3 + ;; + esac + if [ -n "${username}" ] && [ -n "${password}" ]; then + at_command="at+qicsgp=1,${context_type},\"${apn}\",\"${username}\",\"${password}\",3" + else + at_command="at+qicsgp=1,${context_type},\"${apn}\",\"\",\"\",0" + fi + exec_at_command "${at_command}" "${ser_port}" + fi +} + proto_modemmanager_setup() { local interface="$1" diff --git a/patches/0093-wwan-call-modemmanager-to-setup-Quectel-LTE.patch b/patches/0093-wwan-call-modemmanager-to-setup-Quectel-LTE.patch new file mode 100644 index 000000000..360efe0dd --- /dev/null +++ b/patches/0093-wwan-call-modemmanager-to-setup-Quectel-LTE.patch @@ -0,0 +1,59 @@ +From cd82a3d73e2a024367d5e1d9f8c19afdd05f1306 Mon Sep 17 00:00:00 2001 +From: build7 +Date: Tue, 15 Jul 2025 12:00:58 +0800 +Subject: [PATCH] wwan: call modemmanager script to setup Quectel LTE module + +--- + package/network/utils/wwan/files/wwan.sh | 9 ++++++ + 1 file changed, 9 insertions(+) + +diff --git a/package/network/utils/wwan/files/wwan.sh b/package/network/utils/wwan/files/wwan.sh +index 9907195e6c..47f4531d7b 100755 +--- a/package/network/utils/wwan/files/wwan.sh ++++ b/package/network/utils/wwan/files/wwan.sh +@@ -14,12 +14,14 @@ proto_qmi_setup() { echo "wwan[$$] qmi proto is missing"; } + proto_ncm_setup() { echo "wwan[$$] ncm proto is missing"; } + proto_3g_setup() { echo "wwan[$$] 3g proto is missing"; } + proto_directip_setup() { echo "wwan[$$] directip proto is missing"; } ++proto_modemmanager_quectel_setup() { echo "wwan[$$] modemmanager proto is missing"; } + + [ -f ./mbim.sh ] && . ./mbim.sh + [ -f ./ncm.sh ] && . ./ncm.sh + [ -f ./qmi.sh ] && . ./qmi.sh + [ -f ./3g.sh ] && { . ./ppp.sh; . ./3g.sh; } + [ -f ./directip.sh ] && . ./directip.sh ++[ -f ./modemmanager.sh ] && . ./modemmanager.sh + + proto_wwan_init_config() { + available=1 +@@ -37,6 +39,7 @@ proto_wwan_init_config() { + + proto_wwan_setup() { + local driver usb devicename desc bus ++ local is_quectel=0 + + json_get_vars bus + +@@ -67,6 +70,7 @@ proto_wwan_setup() { + usb=/lib/network/wwan/$vendor:$product + devicename=$a + } ++ [ "$vendor" = "2c7c" ] && is_quectel=1 + done + fi + +@@ -119,6 +123,11 @@ proto_wwan_setup() { + uci_set_state network "$interface" ctl_device "$ctl_device" + uci_set_state network "$interface" dat_device "$dat_device" + ++ if [ -n "${is_quectel}" ]; then ++ echo "wwan[$$]" "Setup Quectel chip" ++ proto_modemmanager_quectel_setup ++ fi ++ + case $driver in + qmi_wwan) proto_qmi_setup $@ ;; + cdc_mbim) proto_mbim_setup $@ ;; +-- +2.34.1 +