Commit Graph
133 Commits
Author SHA1 Message Date
Aleksander Morgado 381e2f382b base-modem: separate method to lookup exact port by name
There's no point in returning a list of all ports with a given name,
just provide a lookup method that returns the single port with the
given name.
2021-02-25 14:13:03 +01:00
Pavan Holla 38f6704fa1 base-sim: Reprobe modem if lock status cannot be read after sending puk
If the lock status cannot be read during a puk unblock attempt, reprobe
the modem. It is likely that the SIM was permanently blocked if the lock
status cannot be read.
2020-11-26 08:53:14 +00:00
Aleksander Morgado 6e0380c165 base-modem: order ports by name by default
When there are multiple ports with the same purpose (e.g. multiple net
data ports, or multiple QMI control ports), sort them by name by
default.

The port order does not make any difference for ports that have
flagged with a specific purpose (e.g. AT primary).

The sorting is done both in the internal lists and when looking up
ports with find_ports().
2020-11-20 09:24:51 +00:00
Aleksander Morgado cab4b54ad1 core: new 'rpmsg' subsystem
Most older Qualcomm SoCs (e.g. MSM8916, MSM8974, ...) communicate with
the integrated modem via shared memory (SMD channels). This is similar
to QRTR on newer SoCs, but without the "network" layer. In fact, the
older SoCs also have QRTR, but the modem QMI services are not exposed
there.

The mainline Linux kernel exposes SMD channels via the "remote processor
messaging bus" (rpmsg). Through special IOCTL calls it is possible to
create a char device for a rpmsg/SMD channel. We can then use these to
send QMI/AT messages to the modem, much like the ordinary serial char
devices when using a Qualcomm modem through USB.

This commit introduces support for the new 'rpmsg' subsystem, which
allows exporting QMI-capable and AT-capable ports.

By default NO rpmsg port is flagged as candidate, it is assumed that
the plugin adding support for the rpmsg subsystem will add specific
rules to do so (e.g. so that non-modem ports are explicitly not
flagged as candidate).

All rpmsg ports will be probed for AT or QMI capabilities, unless
explicit port type hints (e.g. ID_MM_PORT_TYPE_QMI or
ID_MM_PORT_TYPE_AT_PRIMARY) are set.

These changes are highly based on the initial integration work done by
Stephan Gerhold <stephan@gerhold.net> in postmarketOS, see:
  https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/363
2020-11-20 09:24:51 +00:00
Aleksander Morgado 950abbf8ee core: stop monitoring the 'usb' subsystem
Back in Linux < 3.6 days, the cdc-wdm ports exposed by the QMI driver
were flagged as owned by the 'usb' subsystem. That changed in 3.6 when
the subsystem was renamed to 'usbmisc':

  https://mail.gnome.org/archives/networkmanager-list/2012-June/msg00125.html

This patch removes all monitoring of the 'usb' subsystem completely,
which is anyway a valid subsystem but for which we shouldn't need any
special handling. Right now, with newer kernels, we were using that
monitoring exclusively to get notified of full USB device remove
events, which is really not required as we already process the port
removals one by one.

We simplify the logic everywhere that attempted to match either the
'usb' or 'usbmisc' subsystems, and we no longer require the explicit
checks for the port name being named 'cdc-wdm[0-9]*' in the code, as
that is already taken care of by the ID_MM_CANDIDATE udev tag rule.
2020-11-13 08:57:06 +00:00
Aleksander Morgado 799c4c72ce port-qmi: allow specifying input subsystem
We have assumed until now that all QMI ports are based on the
qmi_wwan driver, exposed in the 'usbmisc' subsystem by the cdc-wdm
driver.

This may no longer be true, so allow creating QMI ports with
an explicit subsystem instead of defaulting always to USBMISC.
2020-11-09 18:41:57 +01:00
Aleksander Morgado 7faa3a5e25 port-mbim: allow specifying input subsystem
We have assumed until now that all MBIM ports are based on the
cdc_mbim driver, exposed in the 'usbmisc' subsystem by the cdc-wdm
driver.

This may no longer be true, so allow creating MBIM ports with
an explicit subsystem instead of defaulting always to USBMISC.
2020-11-09 18:41:57 +01:00
Aleksander Morgado 4ec2db75b8 port-serial-qcdm: allow specifying input subsystem
We have assumed until now that all QCDM ports are based on TTY
drivers, e.g. exposed via USB.

This may no longer be true, so allow creating QCDM ports with
an explicit subsystem instead of defaulting always to TTY.
2020-11-09 18:41:57 +01:00
Aleksander Morgado 56fca14473 base-modem: refactor port grabbing logic
Split in its own method the per-subsystem port creation mechanism, and
apply all common AT port settings (e.g. response parser, flags) in a
single place.
2020-11-09 18:41:57 +01:00
Aleksander Morgado f052e914c8 port: rename subsystem from 'usb' to 'usbmisc'
Back in Linux < 3.6 days, the cdc-wdm ports exposed by the QMI driver
were flagged as owned by the 'usb' subsystem. That changed in 3.6 when
the subsystem was renamed to 'usbmisc':

  https://mail.gnome.org/archives/networkmanager-list/2012-June/msg00125.html

So, rename the port subsystem type enumn to 'usbmisc'.
2020-11-09 18:41:57 +01:00
Aleksander Morgado b8f6fb59ed broadband-modem-qmi: peeking QMI port only in QMI modems
Move the logic out of the base modem, and make it applicable only for
QMI modems.
2020-11-09 18:41:57 +01:00
Aleksander Morgado 6defec2fae broadband-modem-mbim: peeking MBIM port only in MBIM modems
Move the logic out of the base modem, and make it applicable only for
MBIM modems.
2020-11-09 18:41:57 +01:00
Aleksander Morgado b2621b4336 huawei: plugin already processes generic tags
So don't re-process them in the generic modem when grabbing the port.
2020-11-04 11:15:18 +00:00
Aleksander Morgado c385031941 base-modem: sort port info array by port name
So that the list of ports shown in the Ports DBus property is also
alphabetically sorted by port name, instead of having a mess like
this:

  -----------------------------
  System   |            device: qcom-soc
           |           drivers: bam-dmux
           |            plugin: qcom-soc
           |      primary port: rpmsg0
           |             ports: rmnet5 (net), rmnet_usb0 (unknown), rmnet4 (net),
           |                    rpmsg1 (at), rmnet3 (net), rpmsg0 (qmi), rmnet2 (net), rmnet1 (net),
           |                    rmnet7 (net), rmnet0 (net), rmnet6 (net)
2020-10-30 09:30:46 +01:00
Stephan Gerhold a174edb74d api: expose ignored ports as MM_MODEM_PORT_TYPE_IGNORED
At the moment, ignored ports show up as (unknown) in the ports list
in mmcli. This makes it look like something went wrong while probing.

Actually ModemManager already tracks unknown and ignored ports separately
(MM_PORT_TYPE_UNKNOWN vs MM_PORT_TYPE_IGNORED) but the API always exposes
them as MM_MODEM_PORT_TYPE_UNKNOWN.

Add MM_MODEM_PORT_TYPE_IGNORED and use this for ignored ports so they
show up as (ignored) instead in mmcli.
2020-10-30 09:26:24 +01:00
Aleksander Morgado e20eebff47 base-modem: SIM switch handling at base modem level
When the SIM switch doesn't happen as part of an async hot swap
detection, we should trigger the switch handling at base modem level,
which e.g. doesn't require explicit cleanup of the SIM hot swap
detection port context.
2020-08-28 14:59:06 +00:00
Aleksander Morgado 875ef11a57 base-modem: port to use object logging
Also link all grabbed ports as owned by the modem.
2020-04-08 16:35:08 +02:00
Aleksander Morgado 9e50dda400 base-modem: set dbus id as soon as object is created 2020-04-08 16:35:08 +02:00
Aleksander Morgado 316f2fdff8 base-modem: fix warnings with -Wswitch-enum
mm-base-modem.c: In function ‘mm_base_modem_organize_ports’:
  mm-base-modem.c:1088:9: error: enumeration value ‘MM_PORT_TYPE_UNKNOWN’ not handled in switch [-Werror=switch-enum]
   1088 |         switch (mm_port_get_port_type (candidate)) {
        |         ^~~~~~
  mm-base-modem.c:1088:9: error: enumeration value ‘MM_PORT_TYPE_IGNORED’ not handled in switch [-Werror=switch-enum]
2020-01-30 11:59:14 +01:00
Aleksander Morgado 4bfd955e64 auth-provider: fix reference count in manager and modem objects
The auth provider is now a singleton (since 20ab6550), one single
object that lives throughout the whole program execution, and so we
don't need to keep our own full references around. This fix makes
sure we don't attempt to unref a full auth provider reference we
don't own.

Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/179
2020-01-28 10:33:50 +01:00
Aleksander Morgado 20ab6550fb auth-provider: refactor and simplify
The auth provider setup is a bit over-engineered. Simplify it by
making a single MMAuthProvider object that may or may not use polkit,
depending on configure options. This object is also setup as a
singleton object using the helper MM_DEFINE_SINGLETON_GETTER().
2020-01-23 11:50:23 +00:00
Aleksander Morgado a6a3db2184 base-modem: use g_steal_pointer() during dispose
g_steal_pointer() sets the original location to NULL already, so it's
very handy.
2020-01-22 18:21:25 +01:00
Aleksander Morgado 3490f997f9 base-modem: serial ports require 'timed-out' signal disconnection on cleanup
Fixes https://lists.freedesktop.org/archives/modemmanager-devel/2020-January/007686.html
2020-01-22 18:21:17 +01:00
Aleksander Morgado 9b56ce8ccc base-modem: new helper method to cleanup ports during modem dispose
The different types of ports available in the modem will require
different types of cleanup actions. E.g. QMI and MBIM ports need an
explicit device close, and some other port types may need other
cleanups.
2020-01-22 18:19:02 +01:00
Aleksander Morgado 377691afd4 port-qmi: asynchronous close operation always
To be in sync with the qmi_device_close_async() underlying method,
given that the synchronous one is deprecated.
2020-01-22 13:56:59 +01:00
Aleksander Morgado e793e4e6d8 base-modem: fix list iteration closing MBIM ports
The mm_port_mbim_close() operation needs 3 arguments explicitly, so
make sure we provide the two additional ones as NULL.
2020-01-22 13:09:19 +01:00
Aleksander Morgado e3a1364ddc core: allow flagging ports as 'audio'
Instead of flagging them as 'ignored' so that they aren't probed, we
can also flag them as 'audio' now, so that the logic knows which port
to report as used for audio in the Call object.
2019-10-15 13:19:10 +02:00
Aleksander Morgado 7510b3355d base-modem: fix segfault when disposing modem
If we have a modem reference around during an ongoing operation but
the modem has already been disposed after getting removed from the
system, we were trying to iterate a NULL hash table, which led to a
crash.

https://lists.freedesktop.org/archives/modemmanager-devel/2018-November/006915.html

Reported by Sebastien Fabre <sebastien.fabre@sigfox.com>
2018-11-28 11:58:34 +01:00
Ben Chan f7cb84788e base-modem: remove explicit GDestroyNotify cast on g_object_unref
g_object_unref is in form of  `void (*)(gpointer)`, which matches the
GDestroyNotify signature. An explicit GDestroyNotify cast on
g_object_unref is thus not needed.
2018-10-06 14:50:04 +02:00
Aleksander Morgado 2a1a0b88fb udev: define all generic tags as symbols
This prevents errors due to nasty typos in the strings.

We define all symbols in a single header file that is NOT considered
part of the API, as there is no need for MM clients to know about
these tags code-wise. These tags are only meaningful when associated
to devices in udev.

Information of each tag is included in the general API documentation.

https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/88
2018-09-25 17:55:53 +00:00
Aleksander Morgado 4c669d3bf4 modem-helpers: reuse nicknames for the flow control tags
And check that the string given in the tag is actually a valid one.
2018-09-12 17:15:46 +00:00
Aleksander Morgado b773e610eb port-serial,broadband-modem: minor coding style fixes 2018-09-12 17:15:46 +00:00
Alfonso Sánchez-Beato 94879ce1ce base-modem,port-probe: set serial port flow control from udev tag
Set the serial port flow control from the udev tag
ID_MM_TTY_FLOW_CONTROL before accessing the port.
2018-09-12 17:15:46 +00:00
Aleksander Morgado 548b7f8847 base-modem: load AT port type hints when adding port
We keep the pflags input in mm_base_modem_grab_port() so that plugins
can use other methods to gather port type hints (e.g. querying with AT
commands as in Huawei/Telit or looking at sysfs properties as in HSO).

For standard udev tag port type hints, it will be the base modem
looking them up.

Note that there is no longer any need to ignore non-flagged ports for
those modems that require primary/secondary flags. They will be
implicitly ignored when mm_base_modem_organize_ports() decides which
ports to use, as the flagged ones are preferred over the non-flagged
ones.
2018-08-10 04:19:13 +00:00
Aleksander Morgado c476612247 base-modem: allow parallel Enable() and Disable() requests
If additional Enable() requests are received while one is already
ongoing, we queue them and will end up completing all with the same
result once the first one finishes.

Same logic also for Disable().

https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/8
2018-08-08 18:38:05 +00:00
Aleksander Morgado 0e770b13f8 base-modem: setup a maximum number of timeouts also for USB modems
We have a maximum number of timeouts that could be enabled for TTY
modems, e.g. to detect whether the modem is available in the RS232
port or has been unplugged. This was required because RS232 modems
aren't notified via udev, so there was no other way to check presence
of the modem.

But, the same kind of checks may be used in order to detect failed
broken modems. If we have a modem that gets into an unstable state
where no AT port command goes through and all get timed out, we can
definitely flag the modem as invalid and get rid of it. If we don't do
this, we would end up leaving the modem exposed and available for
users of the API, but in a non-working state.

    ....
    <info>  Modem /org/freedesktop/ModemManager1/Modem/0: state changed (registered -> connecting)
    <debug> Launching 3GPP connection attempt with APN 'telefonica.es'
    <debug> Looking for best CID...
    <debug> (ttyACM2) device open count is 2 (open)
    <debug> (ttyACM2): --> 'AT+CGDCONT?<CR>'
    <debug> Unexpected +CGDCONT? error: 'Serial command timed out'
    <warn>  (tty/ttyACM2) at port timed out 9 consecutive times
    <debug> Using empty CID 1 with PDP type 'ipv4'
    <debug> (ttyACM2) device open count is 3 (open)
    <debug> (ttyACM2) device open count is 2 (close)
    <debug> (ttyACM2): --> 'AT+CGDCONT=1,"IP","telefonica.es"<CR>'
    <warn>  Couldn't initialize PDP context with our APN: 'Serial command timed out'
    <debug> Couldn't connect bearer '/org/freedesktop/ModemManager1/Bearer/0': 'Serial command timed out'
    <info>  Modem /org/freedesktop/ModemManager1/Modem/0: state changed (connecting -> registered)
    <debug> Couldn't connect bearer: 'Serial command timed out'
    <debug> (ttyACM2) device open count is 1 (close)
    <error> (tty/ttyACM2) at port timed out 10 consecutive times, marking modem '/org/freedesktop/ModemManager1/Modem/0' as invalid
    <debug> Removing from DBus bearer at '/org/freedesktop/ModemManager1/Bearer/0'
    <debug> [device /sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.5] unexported modem from path '/org/freedesktop/ModemManager1/Modem/0'
    <debug> Periodic signal checks disabled
    <debug> (ttyACM2) device open count is 0 (close)
    <debug> (ttyACM2) closing serial port...
    <debug> (ttyACM2) serial port closed
    <debug> (ttyACM2) forced to close port
    <debug> Modem (u-blox) '/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.5' completely disposed
2018-06-02 17:54:54 +02:00
Aleksander Morgado 43d0bd0f91 base-modem: improve broken modem detection logic
If the serial port timeout detection logic is enabled, warn whenever
more than one consecutive command timeout happens, not just when the
limit is reached.
2018-04-30 18:23:39 +02:00
Aleksander Morgado 33583ca4de kerneldevice: allow getting interface class/subclass/protocol 2017-12-05 10:58:29 +01:00
Aleksander Morgado 58e6f652a1 base-modem: plug memleaks when building port lists
The mm_base_modem_find_ports() method builds a list of full
references, so we need to unref them in the peek() methods.

    ==10047== 14,959 (24 direct, 14,935 indirect) bytes in 1 blocks are definitely lost in loss record 5,470 of 5,473
    ==10047==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==10047==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==10047==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==10047==    by 0x66D9A33: g_list_append (in /usr/lib/libglib-2.0.so.0.5200.3)
    ==10047==    by 0x15F6A7: mm_base_modem_find_ports (mm-base-modem.c:845)
    ==10047==    by 0x15E9F3: mm_base_modem_peek_port_qmi_for_data (mm-base-modem.c:579)
    ==10047==    by 0x15E8FC: mm_base_modem_get_port_qmi_for_data (mm-base-modem.c:555)
    ==10047==    by 0x1BB99F: _connect (mm-bearer-qmi.c:1391)
    ==10047==    by 0x1540B4: mm_base_bearer_connect (mm-base-bearer.c:841)
    ==10047==    by 0x181F4F: connection_step (mm-iface-modem-simple.c:597)
    ==10047==    by 0x181321: create_bearer_ready (mm-iface-modem-simple.c:258)
    ==10047==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
2017-10-07 14:10:12 +02:00
Ben Chan 38c53ed814 base-modem: minor coding style fixes 2017-07-17 13:46:22 -05:00
Ben Chan 8ad785925a core: use g_list_copy_deep for deep copying a GList 2017-06-23 22:32:07 +02:00
Ben Chan 6ced121ce1 base-modem: port mm_base_modem_authorize to use GTask 2017-04-06 20:26:17 +02:00
Aleksander Morgado 11a26f1066 serial: allow specifying baudrate to use via udev tags
A new 'ID_MM_TTY_BAUDRATE' per-port udev tag is introduced, which
allows specifying the baudrate that will be used when opening a
specific serial port.

E.g.:

    ACTION!="add|change|move", GOTO="mm_my_modem_end"
    DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/*", ENV{ID_MM_TTY_BAUDRATE}="115200"
    LABEL="mm_my_modem_end"

https://bugs.freedesktop.org/show_bug.cgi?id=100158
2017-03-22 09:40:14 +01:00
Aleksander Morgado ef50c085f9 base-modem,cinterion: no need for a peek_current_data_port() method
We already get the data port given as input parameter in
disconnect_3gpp(), so there is no point in trying to find out which the
data port is.
2017-01-04 14:11:17 +01:00
Matthew Stanger 1ffcb16349 cinterion: implement support for the new SWWAN interface 2017-01-04 14:11:17 +01:00
Aleksander Morgado ae9ede926a core: use the kernel device object in the port object and the plugin interface
The mm_base_modem_grab_port() now receives a MMKernelDevice directly from the
plugin, which is then stored in the MMPort corresponding to the port.

This means that we have direct access to e.g. all properties set by udev rules
everywhere, and we don't need additional GUdevClient objects (e.g. like the one
used in the Huawei plugin to detect NDISDUP support during runtime).

For virtual ports (e.g. generated during unit tests), we have a new 'generic'
kernel device object which just provides the values from the kernel device
properties given during its creation.
2016-09-29 15:43:05 +02:00
Aleksander Morgado dd98454a7d base-modem: add missing 'reprobe' property setup
The sim hotswap logic likely just uses the getter/setter methods, but we should
anyway fix the property definition bits.
2016-09-22 19:59:10 +02:00
Aleksander Morgado 048667ffc2 core: minor coding style changes 2016-08-10 09:49:40 +02:00
Carlo Lobrano 60f4f9e57d modem: support SIM hot swap
BaseModem
  added reprobe property.

MMDevice
  added logic to recreate the modem if it is set invalid and "to reprobe"

MMBroadbandModem
 * added initialization step for SIM hot swap:
    1. keep dedicated ports open to listen to modem's unsolicited
    2. dedicated error management in case of initialization failure due to SIM missing
 * added function to be called in order to act upon SIM insertion/removal:
    1. close dedicated ports
    2. set the modem to be reprobed
    3. disable modem
 * added SIM HOT SWAP boolean property

MMIfaceModem
 * added initialization step for SIM hot swap, if supported by the plugin
 * dedicated error management in case of initialization failure due to SIM missing
2016-08-10 09:39:27 +02:00
Aleksander Morgado 6ba37aa041 base-modem: remove unused 'mm_base_modem_get_port()' method 2016-03-27 18:52:39 +02:00