EG25-G reverse engineering
quectel_daemon
- makes
/sys/class/gpio/gpio1018/direction
an output - monitors
/sys/devices/virtual/android_usb/android0/state
and/sys/devices/virtual/android_usb/android0/usb_sleep
and passes the state to modem via qmi - monitors
/run/gpio_data
and updates/sys/class/gpio/gpio1018/direction
withhigh
/low
- opens various pcm devices (voice_pcm_service)
- handles call ringing and voice audio configuration
- touches
/tmp/quec_daemon_rdy
- talks
via
/run/voc_svr
in the main loop
quectel_monitor_daemon
- if
/data/ModemRestartSystem
exists it writesSYSTEM
to/sys/devices/4080000.qcom,mss/subsys1/restart_level
or/sys/devices/4080000.qcom,mss/subsys0/restart_level
- if
/data/ModemRestartRelated
exists it writesRELATED
to/sys/devices/4080000.qcom,mss/subsys1/restart_level
or/sys/devices/4080000.qcom,mss/subsys0/restart_level
- then
it monitors
/sys/devices/4080000.qcom,mss/subsys1/quec_state
and if it is changed to non-0 it restarts various daemons:- system(„killall atfwd_daemon“);
- system(„killall quectel_daemon“);
- system(„killall alsaucm_test“);
quectel_pcm_daemon
- waits for pcm codec to probe
- reads
/data/quec/conf/auxpcm.conf
(written byatfwd_daemon
via AT+QDAI command) - based on values therein
it:
- loads various kernel modules for supported
external codecs
- eg.:
system(„echo \"nau8814-codec.2–001a\“ > /sys/devices/soc:sound/codec_name");
system(„echo \"nau8814-aif1\“ > /sys/devices/soc:sound/rx_dai_name");
system(„echo \"nau8814-aif1\“ > /sys/devices/soc:sound/tx_dai_name");
system(„insmod /usr/lib/modules/3.18.44/kernel/sound/soc/codecs/snd-soc-nau8814.ko“);
- eg.:
- configures
PCM interface, like:
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/mode“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/sync“
„echo %d > /sys/devices/soc:sound/pcm_mode_select“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/frame“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/quant“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/data“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/rate“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/num_slots“
„echo %d > /sys/devices/soc:qcom,msm-sec-auxpcm/slot_mapping“
„echo %d > /sys/devices/soc:sound/quec_auxpcm_rate“
- loads various kernel modules for supported
external codecs
quectel_psm_aware
- creates fifo
/run/psm_aware_cmd
- reads this fifo and issues various
psm_*
calls to a library - some power saving stuff
- fifo is written from
atfwd_daemon
viaAT+QPSM="fifo string"
command
quectel_tts_service
- binds to 127.0.0.1:17824
- accepts connections and plays TTS audio from the issued command
sendcal
- creates
/run/sendcal
device - does some basic processing
subsystem_ramdump
- allow to dump ram to a file in /data
time_daemon
- reads RTC time from modem over qmi and updates the ARM CPU time
uim_test_client
- sim testing console client
quectel-uart-ddp
- reads
/data/quec/conf/dynamic_console
- passes data between debug
uart port and
/dev/smd9
quectel-thermal
- monitors
/sys/devices/virtual/thermal/thermal_zone%d/temp
- updates SAR and RF signal strength based on temperature via QMI
quectel-smd-atcmd
- probably supposed to
forward commands from
/dev/ttyGS0
to/dev/smd7
- does nothing, just prints some crap in a weird way to console/kmsg
- Sundy still didn't learn stdio so is using system(„echo %s > /dev/kmsg“); instead of fprintf
quectel-remotefs-service
- opens
/dev/smd8
- waits for commands from the modem over
/dev/smd8
and performs basic VFS operations, like open/close/read/write/seek, etc. - implements reaction to OMA DM push
message by executing
/data/ipth_dme
binary, which implements vendor (Verizon, AT&T) specific remote FOTA/system config updates- only if
fota_ip_a
orfota_ip_v
exist in/data/fota
directory
- only if
quectel-gps-handle
- Sundy strikes again, this time using stdio in addition to system() calls for debug output!
- writes 0 to
/data/quec/conf/gps_outport_flag
- opens
/dev/smd7
(modem's GPS data shmem device) - reads a number
from
/data/quec/conf/gps_outport_flag
- uses
/dev/ttyHSL0
or/dev/ttyGS0
for NMEA output based on the number
- uses
- forwards data from
/dev/sdm7
to one of the serial ports - monitors
/sys/class/android_usb/android0/state
and/sys/class/android_usb/f_serial/is_connected_flag
and presumably turns off GPS output if USB is not ‚CONNECTED‘
quec_wifi_bridge
- opens
/data/wifi_bridge_in_pipe
and/data/wifi_bridge_out_pipe
- listens on ‚0.0.0.0:5555‘
- forwards data from connections to
/data/wifi_bridge_in_pipe
as is - forwards data from
/data/wifi_bridge_out_pipe
to the last accepted connection
ql_usbcfg
- loads USB configuration for recovery mode
ql_manager_server / ql_manager_cli
- some WWAN/WIFI management server + cli client
- quectel code
…
Files
/tmp/.urc_sock
- Unix socket that can be used to send URCs from linux userspace
Un(der)-documented AT commands
AT+QPRINT=1
- (does literally
cat /proc/kmsg >/dev/ttyGS0 &
), you can get dmesg output fromcat /dev/ttyUSB1
on the A64 side
AT+QPRINT=0
- does literally
killall cat
AT+QFASTBOOT
- reboots the modem in fastboot mode
AT+QCFG=„modemrstlevel“,<val>
- /sys/bus/msm_subsys/devices/subsys1/restart_level
val == 0:
- echo SYSTEM > /sys/bus/msm_subsys/devices/subsys0/restart_level
- echo 00 > /data/ModemRestartSystem
- rm -rf /data/ModemRestartRelated
val == 1:
- echo RELATED > /sys/bus/msm_subsys/devices/subsys0/restart_level
- echo 11 > /data/ModemRestartRelated
- rm -rf /data/ModemRestartSystem
AT+QCFG=„aprstlevel“,<val>
- echo
val
> /sys/bus/msm_subsys/devices/subsys0/system_reset_mode
AT+QCFG=„usbid“
- handled by quectel-manager (see ql_mgmt_client_open C api)
AT+QCFG=„usbee“
- handled by quectel-manager (see ql_mgmt_client_open C api)
AT+QCFG=„usbcfg“
- handled by quectel-manager (see ql_mgmt_client_open C api)
AT+QCFG=„usbnet“
- handled by quectel-manager (see ql_mgmt_client_open C api)
AT+QCFG=„pcmclk“
- reads/writes /sys/devices/soc:qcom,msm-sec-auxpcm/enable_clk
- sets some params on alsa hw:0,0 device
AT+QCFG=„tone/incoming“,<val>
- reads/writes
DWORD
val
to /data/quec/conf/ringtype.conf
AT+QCFG=„sleepind/level“,<val>
- echo
val
> /sys/devices/soc:quec,quectel-power-manager/sleep_polarity - echo
val
> /data/quec/conf/sleepind.txt
AT+QCFG=„wakeupin/level“,<val>
- echo
val
> /data/quec/conf/wakeupin.txt
AT+QCFG=„thermal/modem“, „thermal/limit_rates“, „thermal/txpwrlmt“
- modifies /data/quec_thermal_threshold (37B binary file)
- modifies
/data/quec_therm_cfg
- format enable=%d,sensor=%d,tempthreshold=%d,duration=%d,trig_cnt=%d,clr_cnt=%d
AT+QCFG=„codec/powsave“
- echo
val
> /sys/devices/78b6000.i2c/i2c-2/2–001b/alc5616_pow_save_cfg
AT+QCFG=„qcautoconnect“,<val>
- sed -i ‚/<AutoConnect>[01]</<AutoConnect>‘$val'</g' /data/mobileap_cfg.xml
AT+QCFG=„ftm/mbim“
- opens /data/quec/usb/ftm_mbim and drops the fd, doesn't close it?
- kinda weird
AT+QCFG=„multi_ip_package“
- configures /sys/devices/virtual/android_usb/android0/multi_package_enabled
- and some other related sysfs files
AT+QCFG=„dbgctl“
echo 1 > /etc/dbgctl
- or
rm /etc/dbgctl
- of course it fails, since /etc is read-only fs
AT+QCFG=„bootup“,<op>
- 1 = start, 0 = stop, 2 = check if service (/etc/init.d) is running
AT+QCFG=„usbmode“
- echo %d > /data/usb/quec_usbmode_check
- cat /sys/devices/virtual/android_usb/android0/state (CONFIGURED / other)
- cat /sys/devices/virtual/android_usb/android0/usb_sleep (0/1)