Age | Commit message (Collapse) | Author |
|
Rather than make all of them rely on MMBaseModem for it. This
lets us disentangle dependencies for easier unit testing.
For interfaces, rather than casting directly to MMBaseModem
use intermediate interfaces (MMIfaceAuth and MMIfaceOpLock)
that tests can fake out.
Signed-off-by: Dan Williams <dan@ioncontrol.co>
|
|
|
|
The modem location interface loads modem location capabilities only during
the very first initialization of this interface.
On each later reinitialization it skips loading these capabilities from
modem, however it still goes through the whole interface initialization
state machine.
This state machine uses its own "ctx->capabilities" field for temporary
capabilities storage, which is set to MM_MODEM_LOCATION_SOURCE_NONE at the
start of the initialization process.
However, if we aren't actually loading modem location capabilities because
we're only reinitializing the interface we still need to set this
"ctx->capabilities" field to the existing (previously loaded) modem
location capabilities.
Otherwise the next interface initialization step (validation) will
permanently disable the whole location interface.
|
|
|
|
When the modem is in a failed state because of a SIM-related error,
like a missing SIM, or if the modem is SIM-locked, allow the
Location interface to initialize and be enabled anyway.
This allows someone without a SIM to use the GPS, which does not
particularly require a phone subscription. It also allows
someone with a SIM to use the GPS even if the SIM is still
locked.
This patch was reworked, while keeping the original idea, by:
Aleksander Morgado <aleksander@aleksander.es>
Fixes #183
|
|
We want to ensure that all errors reported via DBus operations are
normalized to MM-specific errors.
We don't want to return QMI or MBIM specific errors, as those are
protocol specific and we don't want DBus clients to need to rely on
knowing which is the protocol in use by the device.
|
|
Each with its expected corresponding length.
|
|
MMLocation3gpp provides MCC/MNC information as integers, so it can not
make distinction between operator codes such as XXX01 and XXX001.
This commit deprecates mm_location_3gpp_get_mobile_network_code() and
implements a new function mm_location_3gpp_get_operator_code() which
provides the MCC+MNC in string format.
The mm_location_3gpp_get_mobile_country_code() is still available as
returning the MCC as an integer does not have ambiguity issues.
|
|
|
|
The "Serving System" indications reported via QMI when the device is
moving may contain LAC/TAC+CID updates or just CID updates.
E.g. this one has "CID 3GPP" (0x1e):
Mon Aug 3 11:22:42 2020 daemon.debug [1567]: [/dev/cdc-wdm0] received
generic indication (translated)... <<<<<< QMUX: <<<<<< length = 33
<<<<<< flags = 0x80 <<<<<< service = "nas" <<<<<< client = 3
<<<<<< QMI: <<<<<< flags = "indication" <<<<<< transaction =
4512 <<<<<< tlv_length = 21 <<<<<< message = "Serving System"
(0x0024) <<<<<< TLV: <<<<<< type = "Serving System" (0x01)
<<<<<< length = 6 <<<<<< value = 01:01:01:02:01:08 <<<<<<
translated = [ registration_state = 'registered' cs_attach_state =
'attached' ps_attach_state = 'attached' selected_network = '3gpp'
radio_interfaces = '{ [0] = 'lte '}' ] <<<<<< TLV: <<<<<< type
= "Data Service Capability" (0x11) <<<<<< length = 2 <<<<<<
value = 01:0B <<<<<< translated = { [0] = 'lte '} <<<<<< TLV:
<<<<<< type = "CID 3GPP" (0x1e) <<<<<< length = 4 <<<<<<
value = 14:C2:A8:00 <<<<<< translated = 11059732
And this one has both "CID 3GPP" (0x1e) and "LTE TAC" (0x25):
Mon Aug 3 11:23:05 2020 daemon.debug [1567]: [/dev/cdc-wdm0] received
generic indication (translated)... <<<<<< QMUX: <<<<<< length = 38
<<<<<< flags = 0x80 <<<<<< service = "nas" <<<<<< client = 3
<<<<<< QMI: <<<<<< flags = "indication" <<<<<< transaction =
4513 <<<<<< tlv_length = 26 <<<<<< message = "Serving System"
(0x0024) <<<<<< TLV: <<<<<< type = "Serving System" (0x01)
<<<<<< length = 6 <<<<<< value = 01:01:01:02:01:08 <<<<<<
translated = [ registration_state = 'registered' cs_attach_state =
'attached' ps_attach_state = 'attached' selected_network = '3gpp'
radio_interfaces = '{ [0] = 'lte '}' ] <<<<<< TLV: <<<<<< type
= "Data Service Capability" (0x11) <<<<<< length = 2 <<<<<<
value = 01:0B <<<<<< translated = { [0] = 'lte '} <<<<<< TLV:
<<<<<< type = "CID 3GPP" (0x1e) <<<<<< length = 4 <<<<<<
value = 32:36:BC:00 <<<<<< translated = 12334642 <<<<<< TLV:
<<<<<< type = "LTE TAC" (0x25) <<<<<< length = 2 <<<
We should therefore allow changes only in the CID, maintaining
whatever LAC/TAC value we had before.
|
|
mm-iface-modem-location.c: In function 'location_gps_update_nmea':
mm-iface-modem-location.c:272:61: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
time (NULL) - ctx->location_gps_nmea_last_time >= mm_gdbus_modem_location_get_gps_refresh_rate (skeleton))) {
^~
mm-iface-modem-location.c:282:60: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
time (NULL) - ctx->location_gps_raw_last_time >= mm_gdbus_modem_location_get_gps_refresh_rate (skeleton))) {
^~
|
|
|
|
|
|
The helper method returning a variant from a MMLocationGpsRaw would
return already a full variant reference instead of a floating one, so
we were really increasing the refcount when doing g_variant_ref_sink()
in the location interface.
Fix this by consolidating all helper methods in libmm-glib that return
variants from the different MMLocationXX objects, so that they all
return full variants instead of floating ones.
|
|
mm-iface-modem-location.c: In function ‘interface_disabling_step’:
mm-iface-modem-location.c:1389:18: error: this statement may fall through [-Werror=implicit-fallthrough=]
1389 | ctx->step++;
| ~~~~~~~~~^~
mm-iface-modem-location.c:1391:5: note: here
1391 | case DISABLING_STEP_DISABLE_GATHERING:
| ^~~~
...
|
|
mm-iface-modem-location.c: In function ‘interface_disabling_step’:
mm-iface-modem-location.c:1386:5: error: switch missing default case [-Werror=switch-default]
1386 | switch (ctx->step) {
| ^~~~~~
mm-iface-modem-location.c: In function ‘interface_enabling_step’:
mm-iface-modem-location.c:1505:5: error: switch missing default case [-Werror=switch-default]
1505 | switch (ctx->step) {
| ^~~~~~
mm-iface-modem-location.c: In function ‘interface_initialization_step’:
mm-iface-modem-location.c:1709:5: error: switch missing default case [-Werror=switch-default]
1709 | switch (ctx->step) {
| ^~~~~~
|
|
mm-iface-modem-location.c: In function ‘update_location_source_status’:
mm-iface-modem-location.c:482:5: error: enumeration value ‘MM_MODEM_LOCATION_SOURCE_NONE’ not handled in switch [-Werror=switch-enum]
482 | switch (source) {
| ^~~~~~
|
|
The GVariants that we obtain during the processing of the "previous"
dictionary with g_variant_iter_next() are full references, while the
GVariants that we obtain processing the input MMLocationXX objects are
floating references.
The code was working well with the floating references only, as it was
assumed that g_variant_builder_add() would take ownership of them as
full references; but when the GVariant came from the
g_variant_iter_next() processing, g_variant_builder_add() would take a
full new extra reference, triggering the memory leak.
Fix this, by making sure that we always work with full GVariant
references in all cases, converting the floating ones with
g_variant_ref_sink() and making sure we explicitly unref them after
g_variant_builder_add().
==3146== 112 (48 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 4,532 of 4,887
==3146== at 0x483877F: malloc (vg_replace_malloc.c:309)
==3146== by 0x50D53DA: g_malloc (gmem.c:99)
==3146== by 0x50F19ED: g_slice_alloc (gslice.c:1024)
==3146== by 0x511D639: g_variant_alloc (gvariant-core.c:486)
==3146== by 0x511D6F9: g_variant_new_from_bytes (gvariant-core.c:529)
==3146== by 0x51146C3: g_variant_new_from_trusted (gvariant.c:326)
==3146== by 0x5115D28: g_variant_new_string (gvariant.c:1264)
==3146== by 0x48EC642: mm_location_3gpp_get_string_variant (mm-location-3gpp.c:294)
==3146== by 0x196350: build_location_dictionary (mm-iface-modem-location.c:162)
==3146== by 0x197E0C: handle_setup_auth_ready (mm-iface-modem-location.c:891)
==3146== by 0x4EC9160: g_task_return_now (gtask.c:1212)
==3146== by 0x4EC92AA: g_task_return (gtask.c:1281)
==3146== 41,658 (35,520 direct, 6,138 indirect) bytes in 740 blocks are definitely lost in loss record 4,887 of 4,887
==3146== at 0x483877F: malloc (vg_replace_malloc.c:309)
==3146== by 0x50D53DA: g_malloc (gmem.c:99)
==3146== by 0x50F19ED: g_slice_alloc (gslice.c:1024)
==3146== by 0x511E02B: g_variant_get_child_value (gvariant-core.c:1093)
==3146== by 0x5114FA7: g_variant_get_variant (gvariant.c:748)
==3146== by 0x511B196: g_variant_valist_get_nnp (gvariant.c:4934)
==3146== by 0x511B87B: g_variant_valist_get_leaf (gvariant.c:5051)
==3146== by 0x511BFBF: g_variant_valist_get (gvariant.c:5232)
==3146== by 0x511C145: g_variant_valist_get (gvariant.c:5267)
==3146== by 0x511C953: g_variant_iter_next (gvariant.c:5667)
==3146== by 0x1962F5: build_location_dictionary (mm-iface-modem-location.c:128)
==3146== by 0x19659A: notify_gps_location_update (mm-iface-modem-location.c:231)
|
|
|
|
This should never ever happen, so assert
|
|
|
|
Much clearer to understand when looping through them.
|
|
The A-GPS based implementations we currently have assume MSA A-GPS, so
rename the MMModemLocationSource enum value to reflect that.
|
|
But only if the plugin implementation allows to do so.
|
|
E.g. China Mobile (MCC 460, MNC 0).
$ mmcli -m toby --location-get
/org/freedesktop/ModemManager1/Modem/0
-------------------------
3GPP location | Mobile country code: '460'
| Mobile network code: '0'
| Location area code: '6188'
| Cell ID: '40955'
-------------------------
GPS NMEA traces | Not available
-------------------------
Raw GPS | Not available
-------------------------
CDMA BS | Not available
|
|
Devices will expect SUPL server given as either IP:PORT or FQDN:PORT,
so just avoid saying we require a 'URL' because it's not true.
We will use a new helper method to parse and validate user-provided
SUPL server address.
|
|
Sometimes SUPL-server based A-GPS is not possible, e.g. if the module
doesn't have Internet connectivity. In such cases, the modem may
support injecting additional "assistance data" that may be downloaded
from the Internet using external means (e.g. WiFi), in order to keep
having a quick time to first fix.
We now support using this location assistance data, with the following
new API elements:
* A new mask of supported assistance data types is provided in the
SupportedAssistanceData property.
* A new list of URLs from where the aassistance data may be
downloaded is also provided in a new AssistanceDataServers
property.
* A new InjectAssistanceData() method is provided, to perform the
data injection in the module once it's been downloaded to the host
system.
|
|
The "location area code" field is given in GSM/UMTS networks
exclusively. LTE networks use the concept of "tracking area code"
instead.
This patch updates the Location interface to Provide separate fields
for LAC and TAC, instead of giving TAC values in the LAC field.
|
|
|
|
|
|
|
|
|
|
The default setup uses a refresh time of 30s, which means that even if the GPS
location updates are received at a higher frequency, the DBus interface will
still expose at most one update every 30s.
This patch includes a new "SetGpsRefreshTime()" method in the Location
interface, which takes a single 'u' parameter, specifying the refresh rate to
use, in seconds. This method also allows 0 being passed, which will make the
implementation to publish the GPS location updates are soon as ModemManager
detects them.
Along with the new method, a "GpsRefreshTime" read-only property is exposed
to specify the refresh time in effect.
The new method and property will only be applicable if the device has GPS
capabilities.
https://bugs.freedesktop.org/show_bug.cgi?id=89924
|
|
Use debug level, which has to be explicitly requested by the user.
https://bugs.freedesktop.org/show_bug.cgi?id=87498
|
|
|
|
|
|
|
|
Standard GPS setup (raw/nmea) will both enable the GPS module and take full
control of the GPS port. This prevents other processes from reading the NMEA
traces from e.g. a tty. In order to handle this, a new 'unmanaged' GPS location
source is introduced, which will just enable/disable the GPS module, without
reading anything from the GPS port. Of course, both raw/nmea and unmanaged
setups cannot be enabled at the same time.
|
|
The Location property was never being updated properly.
|
|
|
|
The interfaces usually retrieve objects (e.g. skeletons) from the Modem object
using g_object_get(), but we didn't make sure that these objects were actually
valid before using them.
This should clean up errors happening when the modem gets unplugged and still
some actions are ongoing.
Should fix https://bugzilla.gnome.org/show_bug.cgi?id=685933
|
|
Both the ModemManager daemon and the mmcli will now include `libmm-glib.h' only.
We also handle two new special `_LIBMM_INSIDE_MM' and `LIBMM_INSIDE_MMCLI'
symbols, which if included before the `libmm-glib.h' library allow us to:
* Don't include the libmm-glib high level API in the ModemManager daemon, as
the object names would clash with those in the core.
* Define some of the methods of helper objects to be included only if compiling
ModemManager daemon or the mmcli.
|
|
|
|
This will allow implementations of location source enabling to actually update
the location information during the enabling phase.
|
|
|
|
|
|
|
|
Location sources can now be enabled or disabled by using the mask of sources
given in Setup() (similar previous Enable()).
|
|
|
|
* mm_base_modem_peek_port_* () will return either a port object (no new
reference), or NULL if none available.
You would usually peek() a port if you're going to use it just in the current
method, as there is no way to that reference to get invalid (we're single
threaded).
* mm_base_modem_get_port_* () will return either NEW references to valid
port objects, or NULL if none available.
And, you would usually get() a port, whenever you want the port object to be
valid even out of the current method, for example when keeping it in the
context of an async operation.
Also, we need to consider that the primary AT port MAY BE NULL when you
peek() or get() it. This is due to the fact that we may be releasing ports
(due to device disconnection) in the middle of async operations.
|