Commit Graph
122 Commits
Author SHA1 Message Date
Andrey Skvortsov 8b6116fe6c shared-qmi: handle inject position requests from the modem
To be able to have quick position fix GNSS engine needs to know
 - predicted orbits data,
 - current time,
 - approximate position.
Modem sends indications with requests, when it needs corresponding
information. Predicted orbits can be injected using
'mmcli -m any --location-inject-assistance-data=<file>'. But to
accelerate time to first fix after cold start extra information is
needed like time and coarse position.

Inject position requests are received, when GPS session is initiated
using QMI_LOC_START. In inject position request modem sends
information about its last known position. If last known position is
zero, when this is a cold start and inject position is needed to
improve TTFF.
Last position from the modem is cached in ModemManager and is injected
next time, when modem requests it. For example, if modem is restarted.

When timestamp on injected position is too old, than position is
ignored and location engine does cold start. Therefore current time is
used for injected position.

When injected position is far away the actual one (for example, after
flight), after some time location engine falls back to cold start.

Tested on Quectel EG25-G.

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2026-01-10 02:04:10 +03:00
Andrey Skvortsov 81101b0147 shared-qmi: handle inject time requests from the modem
To be able to have quick position fix GNSS engine needs to know
 - predicted orbits data,
 - current time,
 - approximate position.
Modem sends indications with requests, when it needs corresponding
information. Predicted orbits can be injected using
'mmcli -m any --location-inject-assistance-data=<file>'. But to
accelerate time to first fix after cold start extra information is
needed like time and coarse position. This commit injects UTC time.

UTC time inject requests are received, when GPS session is initiated
using QMI_LOC_START.

Tested on Quectel EG25-G.

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2026-01-10 02:04:10 +03:00
Andrey Skvortsov 9c4aeeb33a shared-qmi: unlock location engine at modem start
On SDM845 (OP6T) modem always starts with engine lock 'all'.
It doesn't allow to read assistance server settings at the beginning.
QMI call 'Get Predicted Orbits Data Source' (0x0036) fails with general
failure. As a result it's not possible to inject assistance data using
'mmcli -m any --location-inject-assistance-data=<file>'.

Commit 90843b7a0d ("shared-qmi: Lock and unlock GPS engine when
starting and stopping") unlocks engine on GNSS start, that allows
geolocation to work on SDM845, but it locks engine back on GNSS stop.
As a result after GNSS stop it's not possible to inject XTRA data again.

On EG25-G engine lock settings is stored in NV storage and is preserved after
modem restart. By default engine lock is 'none'. But currently on GNSS
stop this value is changed to 'all', that blocks location engine.
If previous ModemManager version is installed after
stopping geolocation and locking the engine, geolocation will not
work, since the engine is still locked and modem restart will not help.

This commit unlocks engine on modem start so all following operations
with an engine succeed. Engine isn't locked back.

Tested on SDM845 (OP6T) and Quectel EG25-G.

Fixes: 90843b7a0d ("shared-qmi: Lock and unlock GPS engine when starting and stopping")

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2025-10-20 15:30:54 -05:00
Andrey Skvortsov c0933d2f18 shared-qmi: replace tabs with whitespaces
Fixes: 103eb9cf29 ("shared-qmi,modem-helpers-qmi: Add support for NR5G band preference")

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2025-09-27 09:01:57 -05:00
Andrey Skvortsov 0e1bfdb5b6 shared-qmi: fix setting URL to supl server
Function mm_parse_suple_address returns TRUE on valid input data
regardless of its type (URL or IP). As a result
qmi_message_loc_set_server_input_set_ipv4 was always called on valid
data. If URL was provided, then 0.0.0.0 ip address was sent to the
modem instead of provided URL.

Fixes: 6e84f3d459 ("iface-modem-location: validate SUPL server address")

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2025-08-16 21:02:14 +00:00
Richard Acayan 0d69304702 shared-qmi: Register NMEA types indication callbacks earlier
It might be too late to register the indication callbacks after the
response is received. Register the callbacks when the request is made so
an requested indication will always be handled.

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-16 11:32:16 -05:00
Richard Acayan 90843b7a0d shared-qmi: Lock and unlock GPS engine when starting and stopping
Newer modem firmware requires the use of the GPS engine lock, which
controls what the GPS engine can do. Set the GPS engine lock when
appropriate to handle this newer firmware.

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-16 11:32:16 -05:00
Richard Acayan b529b69fb6 shared-qmi: always set NMEA types
By default, the Pixel 3a only emits $PQXXX traces, even when all the
desired traces are reported as enabled. A request to set the NMEA types
must still be sent to enable the GGA/GSA/GSV traces. Remove the
optimization that prevents the request from happening automatically.

Signed-off-by: Richard Acayan <mailingradian@gmail.com>
2025-08-16 11:32:16 -05:00
Andrey Skvortsov f51cc9488b shared-qmi: fix byteorder for supl server IP
It was noted, that when supl server is set using IP address. Modem
doesn't connect to the SUPL server anymore. When IP address is inverted,
then modem connects to SUPL server successfuly.

IP address is stored as uint32_t. According to Telit's documentation [1]
numeric values are encoded in little-endian format in QMI.

After converting IP address from string to binary using inet_pton
IP address is stored in network byte order (big-endian). Therefore it's
needed another convertion from big-endian to host endianness. Final
conversion from host endianness to endianness needed for QMI will be
done in generated
qmi_message_pds_set_agps_config_input_set_location_server_address.

Vendor's Android GNSS hal uses htonl() to convert from struct in_addr
(already in big-endian) before sending QMI request as well [2].

Tested on Quectel EG25-G and SDM845 (OnePlus 6T).

1. FN980 Family Telit Proprietary QMI Command Reference Guide. 4.1.3.1 Byte Ordering
2. https://github.com/ugly-kid-af/device_xiaomi_violet/blob/snow/gps/gnss/GnssAdapter.cpp#L1110

Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
2025-08-10 21:05:13 +00:00
Dan Williams f5ae14d0b2 modem-helpers-qmi: better handle no supported modes
Dell Snapdragon X62 before FCC Unlock reports no radio interfaces
from QMI and no device capabilities from MBIM. Instead of asserting
in mm_filter_supported_modes() when called from
mm_supported_modes_from_qmi_supported_modes_context() gracefully
handle the lack of supported modes.

Signed-off-by: Dan Williams <dan@ioncontrol.co>
2025-04-09 13:19:50 +00:00
Guido Günther 68933455df treewide: Fix typos
Signed-off-by: Guido Günther <agx@sigxcpu.org>
2025-03-11 23:15:57 +01:00
Aleksander Morgado 87e1e8b2d4 shared-qmi: don't assume LOC assistance data servers is initialized once
0x00007bcb78abf8b4	(libglib-2.0.so.0 -gtestutils.c:3450)		??g_assertion_message
  0x00007bcb78abf928	(libglib-2.0.so.0 -gtestutils.c:3476)		??g_assertion_message_expr
  0x00005594f143b221	(ModemManager -mm-shared-qmi.c:6651)		loc_location_get_predicted_orbits_data_source_indication_cb
  0x00007bcb78866043	(libgobject-2.0.so.0 -gmarshal.c:1686)		??g_cclosure_marshal_VOID__BOXEDv
  0x00007bcb7886338b	(libgobject-2.0.so.0 -gclosure.c:895)		_g_closure_invoke_va
  0x00007bcb78878a10	(libgobject-2.0.so.0 -gsignal.c:3472)		??g_signal_emit_valist
  0x00007bcb78879486	(libgobject-2.0.so.0 -gsignal.c:3622)		??g_signal_emit
  0x00007bcb785acc70	(libqmi-glib.so.5 -qmi-loc.c:16976)		process_indication
  0x00007bcb78520ede	(libqmi-glib.so.5 -qmi-device.c:1697)		process_indication_idle
  0x00007bcb78a9b75c	(libglib-2.0.so.0 -gmain.c:3460)		??g_main_dispatch
  0x00007bcb78a9b75c	(libglib-2.0.so.0 -gmain.c:4200)		??g_main_context_dispatch
  0x00007bcb78a9ba81	(libglib-2.0.so.0 -gmain.c:4276)		g_main_context_iterate
  0x00007bcb78a9bcff	(libglib-2.0.so.0 -gmain.c:4479)		??g_main_loop_run
  0x00005594f13a7463	(ModemManager -main.c:236)		??main
  0x00007bcb7825c705	(libc.so.6 -libc_start_call_main.h:58)		??__libc_start_call_main
  0x00007bcb7825c7c1	(libc.so.6 -libc-start.c:360)		??__libc_start_main_impl
  0x00005594f13a6da0	(ModemManager + 0x000b5da0)		??_start
2024-11-12 18:21:25 +00:00
Lubomir Rintel a42d12f660 shared-qmi: fix a leak in error handling path
str needs to be freed in pds_get_agps_config_ready().
2024-05-31 10:46:30 +00:00
Lubomir Rintel 7dfd59157e shared-qmi: do not leak a string in error path 2024-05-31 10:39:59 +00:00
Aleksander Morgado aa94b21e0a iface-modem-location: use G_DECLARE|DEFINE_INTERFACE() macros 2024-05-06 13:45:38 +00:00
Rukun Mao b7433b4c14 iface-modem: new logic to detect SIM swap with explicit IMSI/ICCID query
This improves SIM hot swap check process, and it can help avoid unnecessary
modem reprobe during suspend-resume without SIM inserted.

The changes in this CL implemented the new logic ONLY for MBIM, and the
new logic has not been implemented for QMI and AT yet. Thus, we keep the
legacy `mm_iface_modem_check_for_sim_swap()' till the new logic for QMI
and AT has been implemented.
2023-10-11 14:01:33 +00:00
Andrey Skvortsov 5eb3acee0a shared-qmi: fix memory leak in set_supl_server command
ctx->supl is allocated in mm_shared_qmi_location_set_supl_server
using g_strdup. g_strdup requires to free string when unneeded.

The problem could be reproduced using following commands
```
 while true; do
       mmcli -m any --location-set-supl-server="supl.google.com:7276";
       mem=$(cat /proc/$(pgrep ModemManager)/statm | awk '{print $6}')
       echo $(date +"%s"), $mem | tee -a mm-leak.log;
 done;
```
2023-06-23 23:19:53 +03:00
Aleksander Morgado 4db5635f44 iface-modem: sim swap check always refers to the active SIM
Since 503e886c02 the events on inactive SIMs don't trigger a full
modem reprobe, and the slot index check is fully unused.
2023-06-14 13:54:32 +00:00
Aleksander Morgado f3cdafb746 shared-qmi: don't assume cancellation signal handler is setup in the registration wait
The cancellation_id will not be set if the cancellable is already
cancelled by the time g_cancellable_connect() is called.
2023-05-03 14:25:51 +00:00
Aleksander Morgado 28eec45dbb shared-qmi: ensure cancellation is setup last in the registration wait
register_in_network_cancelled() may be called early if the given
cancellable is already cancelled, and if so, we want it to remove the
timeout and signal handler, which should have been configured before
setting up the cancellation signal handler.
2023-05-03 14:21:31 +00:00
Ulrich Mohr 5ed79518be broadband-modem-mbim,qmi-shared: Fallback from qmi uim service only when not supported
When using qmi uim service from mbim broadband modem, a fallback from using
qmi uim service to normal mbim operations is done every time a call to
qmi_set_primary_sim_slot fails. But this may fall for various reasons,
and a fallback only makes sense when the device does not support that call

Patch reworked by Aleksander Morgado <aleksandermj@chromium.org>
2023-01-18 11:14:14 +00:00
Aleksander Morgado b3f315ad2d core,log: new 'MSG' log level between 'INFO' and 'WARN'
We're bumping the current "INFO" level messages to the new "MSG"
level, also making the new level the default.

The old "INFO" level will be used to setup an intermediate level of
logging which is not as verbose as "DEBUG" but still provides some
capabilities to analyze the behavior of a modem.
2022-11-04 13:12:56 +00:00
Akash Aggarwal 20c558546c mm-shared-qmi: Fix current modes
Modem reports 2G+3G+4G+5G current modes, while 2G is not supported.

Consider device capabilities in deciding current modes.
2022-08-20 01:46:58 +05:30
Aleksander Morgado a783d9f68a shared-qmi: minor rework SetPacketServiceState()
Port to using g_autoptr() so that we avoid the gotos.
2022-08-04 14:26:33 +00:00
Akash Aggarwal d008e437c3 broadband-modem-qmi,mm-shared-qmi: implement support for 'SetPacketServiceState()' 2022-08-04 14:26:33 +00:00
Aleksander Morgado 41ff262006 shared-qmi: improve logging of steps in SIM hot swap setup 2022-07-16 22:24:25 +02:00
Aleksander Morgado e96a111a63 shared-qmi: only transfer state to priv info if SIM hotswap setup succeeds
Don't transfer state to the private info until we know the operation
has fully succeeded.
2022-07-16 22:24:23 +02:00
Aleksander Morgado c994ae1b3a shared-qmi: move indication callbacks out of the SIM hot swap setup 2022-07-16 22:24:20 +02:00
Aleksander Morgado ba3b15fe29 shared-qmi: return error if none of the methods succeeded in SIM hot swap setup 2022-07-16 22:24:17 +02:00
Aleksander Morgado b7da236567 shared-qmi: avoid jumps in the SIM hot swap setup state machine
Always transition to the next step, and decide what to do based on the
state tracked by the previously run steps.
2022-07-16 22:24:14 +02:00
Aleksander Morgado 21d24657eb shared-qmi: make refresh all non-fatal during SIM hot swap setup
If for any reason "Refresh all" fails, don't return an error, as we
may have already configured SIM slot status correctly.
2022-07-16 22:24:02 +02:00
Aleksander Morgado d2bc73f394 shared-qmi: add slot status indication in its own step during SIM hot swap setup 2022-07-16 22:23:57 +02:00
Aleksander Morgado 405f5867c7 shared-qmi: add slot status check in its own step during SIM hot swap setup
Also, don't make the "Get Slot Status" operation fatal; just go on
assuming that the slot status indications are unsupported.
2022-07-16 22:23:53 +02:00
Aleksander Morgado 76c0896535 shared-qmi: new step in SIM hot swap setup to connect to refresh signal
Instead of connecting to the signal in multiple places, do it in one
single place in the logic.
2022-07-16 22:23:45 +02:00
Prakash Pabba 5c0db37432 mm-iface-modem,mm-broadband-modem,mm-shared-qmi: support SIM IMSI switch
It is possible that SIM IMSI might change in roaming conditions for a sim.

Register for UIM refresh indication always and reprobe if ICCID or IMSI changes for QMI modem.
2022-07-16 22:22:59 +02:00
Aleksander Morgado b497de325a iface-modem: common SIM event reporting logic
We no longer have separate mm_base_modem_process_sim_event() and
mm_broadband_modem_sim_hot_swap_detected() methods. The only
difference between both of them was that one of them would attempt to
cleanup the ports context associated to the SIM hot swap event logic
as soon as a swap was detected, in order to avoid queueing up multiple
such events.

The previous logic wasn't working well, though, as there could be
mixed AT+QMI or AT+MBIM devices that would also require that same
cleanup and so we didn't always know which one should have been
called.

Now we have a single mm_iface_modem_process_sim_event() method, which
will trigger the reprobe and disabling, but which will also perform
the cleanup of the SIM ports swap setup as specified by the
implementation.

So, if a plugin explicitly initializes the serial ports context for
SIM hot swap handling, it should also explicitly clean it up.

Also, the initialization of the serial ports context for SIM hot swap
handling is no longer done automatically for all modems, it will be
done only for those modems using it; i.e. the modems that explicitly
report support SIM hot swap handling using AT URCs.
2022-05-20 09:03:54 +00:00
Aleksander Morgado d5805002c1 core: remove "all rights reserved" from copyright lines
The rights each contributor has are the ones stated by the GPL/LGPL,
not more and not less.
2022-03-29 16:36:15 +02:00
Stephan Gerhold 8d95c82f9c shared-qmi: ignore slot status indications until initial status is known
Recent ModemManager versions no longer work on the Samsung A5 (Qualcomm
MSM8916) smartphone: MM ends up in an infinite loop trying to probe the
modem over and over again.

Looking at the debug log it seems to be related to a "Slot Status"
indication that comes in during probe time and causes MM to restart
the probing process:

    [/dev/wwan0qmi0] Sent generic request (translated)...
      << QMUX: service = "uim"
      << QMI: message = "Register Events" (0x002E)
      << TLV: translated = physical-slot-status
    [/dev/wwan0qmi0] Received generic indication (translated)...
      << QMUX: service = "uim"
      << QMI: message = "Slot Status" (0x0048)
      << TLV: translated = { [0] = '[ physical_card_status = 'present', ...
    [/dev/wwan0qmi0] Received generic response (translated)...
      << QMUX: service = "uim"
      << QMI: message = "Register Events" (0x002E)
      << TLV: translated = SUCCESS
    [modem42] registered for slot status indications
    [/dev/wwan0qmi0] Sent generic request (translated)...
      << QMUX: service = "uim"
      << QMI: message = "Get Slot Status" (0x0047)
    [modem42] received slot status indication
    [modem42] An active slot had a status change, will reprobe the modem
     <infinite loop>

The "Slot Status" indication (uim_slot_status_indication_cb) arrives
immediately after starting to listen for the event, which is before
ModemManager has actually loaded the initial slot status in
uim_get_slot_status_ready. In this situation !slot_array_status_equal()
will always cause the modem to reprobe, even though it is not necessary
during the probe phase.

To fix this add a simple check to uim_slot_status_indication_cb() that
ignores the indication if the initial slot status was not loaded yet.
2022-03-23 20:39:14 +01:00
Prakash Pabba 92db190f37 mm-shared-qmi: Return an error in load_current_capabilities() if none is found. 2022-03-09 14:01:23 +00:00
Aleksander Morgado 18aa526f8c shared-qmi: use the new QmiSlotEidElement type
This type was introduced to avoid having GArrays of GArrays in libqmi.
2022-02-28 21:54:24 +01:00
Aleksander Morgado a21b7740d8 shared-qmi: avoid the deprecated QmiConfigTypeAndId type
This type was a JSON description bug in libqmi, it should have never
been a struct by itself. This was changed in libqmi by the 1.31.3
snapshot, so let's use the new methods instead of the deprecated ones.
2022-02-28 21:54:24 +01:00
Aleksander Morgado 9c08e54fb9 shared-qmi: filter out modes not currently available
Do not build the mask of "all" modes based only on the supported radio
interfaces, also filter out those modes that would not be available
based on the current capabilities enabled.
2022-01-31 22:48:57 +01:00
Aleksander Morgado c7ff014e07 modem-helpers-qmi: multimode devices shouldn't always have 4G/5G only modes
In GSM/UMTS+CDMA/EVDO multimode devices, the 4G and 5G mode switching
operations are exclusively limited to the capability selection that
has LTE+5GNR exclusively.

We cannot allow switching to 4G-only, 5G-only or 4G+5G if the current
capabilities have GSM/UMTS or CDMA/EVDO.

Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/503
2022-01-31 22:48:57 +01:00
Aleksander Morgado b323a73137 modem-helpers-qmi: new helper to build array of supported modes 2022-01-31 22:48:57 +01:00
Aleksander Morgado d0c87c5877 modem-helpers-qmi: new helper to build array of supported capabilities 2022-01-31 22:48:57 +01:00
Aleksander Morgado f370c096ec modem-helpers-qmi: refer explicitly to current capabilities in helper method
The helper method for which we have unit tests available refers
exclusively to the current capabilities loading, so rename it to
clarify that.
2022-01-31 22:48:57 +01:00
Prakash Pabba 38f067c4e4 mm-shared-qmi,mm-modem-helpers: Fix supported capabilities and modes for multimode device
We use capability switching logic exclusively for configuring GSM/UMTS+CDMA/EVDO devices
(regardless of whether it has LTE/5GNR or not) to add or remove the GSM/UMTS and CDMA/EVDO
capabilities.

Based on the same logic, we will allow 4 combinations for GSM/UMTS+CDMA/EVDO+LTE+5GNR device:
"GSM/UMTS+CDMA/EVDO+LTE+5GNR", "GSM/UMTS+LTE+5GNR", "CDMA/EVDO+LTE+5GNR" and "LTE+5GNR"

Similarly, we will allow 4 combinations for GSM/UMTS+CDMA/EVDO+LTE device:
"GSM/UMTS+CDMA/EVDO+LTE", "GSM/UMTS+LTE", "CDMA/EVDO+LTE" and "LTE"

And, we will allow 3 combinations for GSM/UMTS+CDMA/EVDO device:
"GSM/UMTS+CDMA/EVDO", "GSM/UMTS" and "CDMA/EVDO"

Also, supported combination modes should be based on current capabilities and not entirely
upon supported radio interfaces.

1) If current capability has "gsm-umts" or "cdma-evdo" or both, do not
   support 4G only, 5G only, or 4G+5G combination modes
2) If current capability neither has "gsm-umts" nor "cdma-evdo", only support
   combination modes involving 4G and 5G.
2022-01-30 15:37:05 +00:00
Aleksander Morgado 81302efa66 iface-modem: use external dispatcher to attempt FCC unlock
We remove the built-in FCC unlock procedures from the ModemManager, we
will no longer run them automatically, and instead rely on external
scripts/programs to do that.

Packages providing the external FCC unlock tools can install them in
${pkglibdir}/fcc-unlock.d.

Users manually enabling external FCC unlock tools can install them in
${pkgsysconfdir}/fcc-unlock.d.

The user-enabled path takes precedence over the package-enabled one.
2021-11-17 11:30:01 +01:00
Prakash Pabba 103eb9cf29 shared-qmi,modem-helpers-qmi: Add support for NR5G band preference
Implement support for the NR5G band list to get current NR5G bands.
This will also allow us to configure supported NR5G bands via mmcli.
2021-11-14 20:19:37 +05:30
Prakash Pabba 6e1cb371ca shared-qmi,modem-helpers-qmi: Add support for NR5G band capability
Implement support for the NR5G band list to get supported NR5G
band capabilities.

  localhost ~ # qmicli -d qrtr://0 --dms-get-band-capabilities
  [qrtr://0] Device band capabilities retrieved:
        Bands: 'bc-0-a-system, bc-0-b-system, bc-1-all-blocks, gsm-dcs-1800, gsm-900-extended, bc-10, gsm-850, gsm-pcs-1900, wcdma-2100, wcdma-pcs-1900, wcdma-1700-us, wcdma-850-us, wcdma-800, wcdma-900, wcdma-850-japan'
        LTE bands: '1, 2, 3, 4, 5, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20, 21, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 43'
        LTE bands (extended): '1, 2, 3, 4, 5, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20, 21, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 43, 46, 48, 66, 68, 71'
        NR5G bands: '1, 2, 3, 5, 7, 8, 12, 13, 14, 18, 20, 25, 26, 28, 29, 30, 38, 40, 41, 48, 66, 70, 71, 77, 78, 79'
2021-11-14 20:19:37 +05:30