This is the documentation site for ModemManager and its accompanying libraries (libmbim, libqmi and libqrtr-glib).
This the multi-page printable view of this section. Click here to print.
Welcome to ModemManager
- 1: libmbim
- 1.1: API reference
- 1.2: Dependencies
- 1.3: Building
- 2: libqrtr-glib
- 2.1: API reference
- 2.2: Dependencies
- 2.3: Building
- 3: libqmi
- 3.1: API reference
- 3.2: Dependencies
- 3.3: Building
- 4: ModemManager
- 4.1: Dependencies
- 4.2: Building
- 4.2.1: Building ModemManager 1.18 or later with Meson
- 4.2.2: Building ModemManager 1.18 or earlier using GNU autotools
- 4.3: Debugging
- 4.4: FCC unlock procedure
- 5: Contribution Guidelines
- 5.1: Using gitlab
- 5.1.1: Basic setup
- 5.1.2: Developer setup
- 5.2: Coding style
- 5.3: git commit style
- 5.4: Merge requests
- 5.5: Project communication
- 6: Frequently Asked Questions
1 - libmbim
This section provides information about the libmbim
library.
1.1 - API reference
The libmbim-glib
API reference provides a detailed list of operations that may be performed with MBIM devices.
Most of the documentation pages are automatically generated from the database of messages that the project maintains, and therefore it won’t give information about the purpose of the operations, or the exact format of the retrieved fields. The documentation is anyway extremely helpful when writing software using the library, as it provides a quick way to browse the interfaces and the expected fields in each message.
In order to know the exact purpose of each message or the format of the retrieved fields, please refer to the generic MBIM services references from the USB-IF or to the vendor-specific service references. Most of these documents are publicly available and don’t require any NDA.
Online references
The most up to date API reference of the libmbim-glib
library is kept in the following location:
The full list of API references published is kept for future reference:
- 1.26.0
- 1.24.0
- 1.22.0
- 1.20.0
- 1.18.0
- 1.16.0
- 1.14.0
- 1.12.0
- 1.10.2, 1.10.0
- 1.8.0
- 1.6.0
- 1.4.0
- 1.2.0
- 1.0.0
There is no API reference published for stable release updates that didn’t have any API change.
Local reference
The API reference is usually installed along with the libmbim-glib
library (sometimes as a separate distribution package) under /usr/share/gtk-doc/html/libmbim-glib/
and can be browsed locally via the Devhelp tool. The version of the installed reference will be the one applying to the libmbim-glib
library installed in the system.
1.2 - Dependencies
Common dependencies
Before you can compile the libmbim library, you will need at least the following tools:
- A compliant C toolchain: e.g.
glibc
ormusl libc
,gcc
orclang/llvm
. - pkg-config, a tool for tracking the compilation flags needed for libraries.
- The glib2 library.
- For libmbim >= 1.26, glib2 >= 2.56.
- For libmbim >= 1.24, glib2 >= 2.48.
- For libmbim >= 1.16 and < 1.24, glib2 >= 2.36
- For libmbim >= 1.0 and < 1.16, glib2 >= 2.32
In addition to the previous mandatory requirements, the project also has several optional dependencies that would be needed when enabling additional project features:
- gtk-doc tools, in order to regenerate the documentation.
- gobject-introspection, in order to generate the introspection support.
Dependencies when building libmbim 1.26 or later with meson
When building with meson, the following additional dependencies are required:
The following optional dependencies are available when building with meson:
- bash-completion, in order to add completion support for the command line tools.
Dependencies when building libmbim 1.26 or earlier with GNU autotools
When building with the GNU autotools, the following additional dependencies are required:
There are two main ways to build the library using GNU autotools: from a git repository checkout and from a source release tarball. When building from a git checkout instead of from a source tarball, the following additional dependencies are required:
- GNU autotools (autoconf/automake/libtool).
- Autoconf archive, in the 1.22 and 1.24 series exclusively.
1.3 - Building
This section provides information about how to build and install the libmbim
library.
1.3.1 - Building libmbim 1.26 or later with Meson
The first stable series with support for building with the meson suite is 1.26. All the older stable series before 1.26 exclusively used the GNU autotools build system.
Building from a git checkout
When using meson, the builds are always triggered from git checkouts, there is no source release tarball involved. The basic build steps would be as follows:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
$ cd libmbim
$ meson setup build --prefix=/usr
$ ninja -C build
Optional switches
Additional optional switches that may be given to the meson
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - The gtk-doc documentation is disabled by default. In order to enable it, the additional
-Dgtk_doc=true
switch should be given. - The GObject introspection support is enabled by default. In order to disable it, the additional
-Dintrospection=false
switch should be given. - The bash-completion support is enabled by default. In order to disable it, the additional
-Dbash_completion=false
switch should be given. - The default build type in meson if none explicitly specified is
debug
, which means debug symbols are included and optimization is fully disabled. The--buildtype=release
switch can be used to remove debug symbols and to enable optimization level to the maximum.
An example project build using all the above optional switches could be:
$ meson setup build \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--buildtype=release \
-Dgtk_doc=true \
-Dintrospection=false \
-Dbash_completion=false
$ ninja -C build
Installing
The installation on the prefix selected during meson setup
can be done with the following command:
$ sudo ninja -C build install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libmbim library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo ninja -C build uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
1.3.2 - Building libmbim 1.26 or earlier with GNU autotools
The last stable series with support for building with the GNU autotools suite is 1.26. All the new stable series after 1.26 will exclusively use the meson build system.
Building from a release source tarball
The basic build and installation of the project can be done from an official release source tarball, in the following way:
$ wget https://www.freedesktop.org/software/libmbim/libmbim-1.26.0.tar.xz
$ tar -Jxvf libmbim-1.26.0.tar.xz
$ cd libmbim-1.26.0
$ ./configure --prefix=/usr
$ make
Optional switches
Additional optional switches that may be given to the configure
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - If the documentation should be rebuilt, the additional
--enable-gtk-doc
switch should be given. Omitting this switch will imply auto-detecting whether the documentation can be rebuilt with the already installed dependencies. - If the introspection support should be included in the build, the additional
--enable-introspection
switch should be given. Omitting this switch will imply auto-detecting whether the introspection can be built with the already installed dependencies. - When developing changes to the library or debugging issues, it is recommended to build with debug symbols so that running the program under
gdb
produces useful backtrace information. This can be achieved by providing user compiler flags like these:CFLAGS="-ggdb -O0"
An example project build using all the above optional switches could be:
$ ./configure \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--enable-gtk-doc \
--enable-introspection \
CFLAGS="-ggdb -O0"
$ make
Running ./configure --help
will show all the possible switches that are supported.
Building from a git checkout
When building from a git checkout, there is one single additional step required to build the project: running the included autogen.sh
in order to setup the GNU autotools project and generate a configure
script:
$ git clone --depth 1 --branch 1.26.0 https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
$ cd libmbim
$ NOCONFIGURE=1 ./autogen.sh
$ ./configure --prefix=/usr
$ make
The same optional switches may be given to the configure
script when building from a git checkout.
Installing
The installation on the prefix selected during configure
can be done with the following command:
$ sudo make install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libmbim library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo make uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
2 - libqrtr-glib
This section provides information about the libqrtr-glib
library.
2.1 - API reference
The libqrtr-glib
API reference provides a detailed list of operations that may be performed with QRTR nodes.
Online references
The most up to date API reference of the libqrtr-glib
library is kept in the following location:
The full list of API references published is kept for future reference:
There is no API reference published for stable release updates that didn’t have any API change.
Local reference
The API reference is usually installed along with the libqrtr-glib
library (sometimes as a separate distribution package) under /usr/share/gtk-doc/html/libqrtr-glib/
and can be browsed locally via the Devhelp tool. The version of the installed reference will be the one applying to the libqrtr-glib
library installed in the system.
2.2 - Dependencies
Common dependencies
Before you can compile the libqrtr-glib library, you will need at least the following tools:
- A compliant C toolchain: e.g.
glibc
ormusl libc
,gcc
orclang/llvm
. - pkg-config, a tool for tracking the compilation flags needed for libraries.
- The glib2 library.
- For libqrtr-glib >= 1.2, glib2 >= 2.56.
- For libqrtr-glib >= 1.0, glib2 >= 2.48
In addition to the previous mandatory requirements, the project also has several optional dependencies that would be needed when enabling additional project features:
- gtk-doc tools, in order to regenerate the documentation.
- gobject-introspection, in order to generate the introspection support.
When building from a git checkout instead of from a source tarball, the following additional dependencies are required:
- GNU autotools (autoconf/automake/libtool).
- Autoconf archive
Dependencies when building libqrtr-glib 1.2 or later with meson
When building with meson, the following additional dependencies are required:
Dependencies when building libqrtr-glib 1.0 with GNU autotools
When building with the GNU autotools, the following additional dependencies are required:
There are two main ways to build the library using GNU autotools: from a git repository checkout and from a source release tarball. When building from a git checkout instead of from a source tarball, the following additional dependencies are required:
- GNU autotools (autoconf/automake/libtool).
- Autoconf archive.
2.3 - Building
This section provides information about how to build and install the libqrtr-glib
library.
2.3.1 - Building libqrtr-glib 1.2 or later with Meson
The first stable series with support for building with the meson suite is 1.2. All the older stable series before 1.2 exclusively used the GNU autotools build system.
Building from a git checkout
When using meson, the builds are always triggered from git checkouts, there is no source release tarball involved. The basic build steps would be as follows:
$ git clone --depth 1 https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib.git
$ cd libqrtr-glib
$ meson setup build --prefix=/usr
$ ninja -C build
Optional switches
Additional optional switches that may be given to the meson
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - The gtk-doc documentation is disabled by default. In order to enable it, the additional
-Dgtk_doc=true
switch should be given. - The GObject introspection support is enabled by default. In order to disable it, the additional
-Dintrospection=false
switch should be given. - The default build type in meson if none explicitly specified is
debug
, which means debug symbols are included and optimization is fully disabled. The--buildtype=release
switch can be used to remove debug symbols and to enable optimization level to the maximum.
An example project build using all the above optional switches could be:
$ meson setup build \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--buildtype=release \
-Dgtk_doc=true \
-Dintrospection=false
$ ninja -C build
Installing
The installation on the prefix selected during meson setup
can be done with the following command:
$ sudo ninja -C build install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libqrtr-glib library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo ninja -C build uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
2.3.2 - Building libqrtr-glib 1.0 using GNU autotools
The last stable series with support for building with the GNU autotools suite is 1.0. All the new stable series after 1.0 will exclusively use the meson build system.
Building from a release source tarball
The basic build and installation of the project can be done from an official release source tarball, in the following way:
$ wget https://www.freedesktop.org/software/libqrtr-glib/libqrtr-glib-1.0.0.tar.xz
$ tar -Jxvf libqrtr-glib-1.0.0.tar.xz
$ cd libqrtr-glib-1.0.0
$ ./configure --prefix=/usr
$ make
Optional switches
Additional optional switches that may be given to the configure
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - If the documentation should be rebuilt, the additional
--enable-gtk-doc
switch should be given. Omitting this switch will imply auto-detecting whether the documentation can be rebuilt with the already installed dependencies. - If the introspection support should be included in the build, the additional
--enable-introspection
switch should be given. Omitting this switch will imply auto-detecting whether the introspection can be built with the already installed dependencies. - When developing changes to the library or debugging issues, it is recommended to build with debug symbols so that running the program under
gdb
produces useful backtrace information. This can be achieved by providing user compiler flags like these:CFLAGS="-ggdb -O0"
An example project build using all the above optional switches could be:
$ ./configure \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--enable-gtk-doc \
--enable-introspection \
CFLAGS="-ggdb -O0"
$ make
Running ./configure --help
will show all the possible switches that are supported.
Building from a git checkout
When building from a git checkout, there is one single additional step required to build the project: running the included autogen.sh
in order to setup the GNU autotools project and generate a configure
script:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib.git
$ cd libqrtr-glib
$ NOCONFIGURE=1 ./autogen.sh
$ ./configure --prefix=/usr
$ make
The same optional switches may be given to the configure
script when building from a git checkout.
Installing
The installation on the prefix selected during configure
can be done with the following command:
$ sudo make install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libqrtr-glib library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo make uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
3 - libqmi
This section provides information about the libqmi
library.
3.1 - API reference
The libqmi-glib
API reference provides a detailed list of operations that may be performed with QMI devices.
Most of the documentation pages are automatically generated from the database of messages that the project maintains, and therefore it won’t give information about the purpose of the operations, or the exact format of the retrieved fields. The documentation is anyway extremely helpful when writing software using the library, as it provides a quick way to browse the interfaces and the expected fields in each message.
In order to know the exact purpose of each message or the format of the retrieved fields, please refer to the generic QMI services references from Qualcomm or to the vendor-specific service references. Most of these documents are only provided by Qualcomm under NDAs.
Online references
The most up to date API reference of the libqmi-glib
library is kept in the following location:
The full list of API references published is kept for future reference:
- 1.30.8, 1.30.2, 1.30.0
- 1.28.6, 1.28.0
- 1.26.6, 1.26.2, 1.26.0
- 1.24.10, 1.24.6, 1.24.0
- 1.22.0
- 1.20.0
- 1.18.0
- 1.16.0
- 1.14.2, 1.14.0
- 1.12.0
- 1.10.6, 1.10.4, 1.10.2, 1.10.0
- 1.8.0
- 1.6.0
- 1.4.0
There is no API reference published for stable release updates that didn’t have any API change.
Local reference
The API reference is usually installed along with the libqmi-glib
library (sometimes as a separate distribution package) under /usr/share/gtk-doc/html/libqmi-glib/
and can be browsed locally via the Devhelp tool. The version of the installed reference will be the one applying to the libqmi-glib
library installed in the system.
3.2 - Dependencies
Common dependencies
Before you can compile the libqmi library, you will need at least the following tools:
- A compliant C toolchain: e.g.
glibc
ormusl libc
,gcc
orclang/llvm
. - pkg-config, a tool for tracking the compilation flags needed for libraries.
- The glib2 library.
- For libqmi >= 1.30, glib2 >= 2.56.
- For libqmi >= 1.26, glib2 >= 2.48.
- For libqmi >= 1.18 and < 1.26, glib2 >= 2.36
- For libqmi >= 1.0 and < 1.18, glib2 >= 2.32
In addition to the previous mandatory requirements, the project also has several optional dependencies that would be needed when enabling additional project features:
- libmbim, in order to use the QMI-over-MBIM feature.
- For libqmi >= 1.22, libmbim >= 1.18.
- For libqmi >= 1.16 and < 1.22, libmbim >= 1.14.
- libqrtr-glib, in order to use the QMI-over-QRTR feature.
- For libqmi >= 1.28, libqrtr-glib >= 1.0.
- The libgudev library, in order to extend the
qmi-firmware-update
options and behavior.- For libqmi >= 1.30, libgudev >= 232.
- For libqmi >= 1.18, libgudev >= 147.
- gtk-doc tools, in order to regenerate the documentation.
- gobject-introspection, in order to generate the introspection support.
Dependencies when building libqmi 1.30 or later with meson
When building with meson, the following additional dependencies are required:
The following optional dependencies are available when building with meson:
- bash-completion, in order to add completion support for the command line tools.
Dependencies when building libmbim 1.30 or earlier with GNU autotools
When building with the GNU autotools, the following additional dependencies are required:
There are two main ways to build the library using GNU autotools: from a git repository checkout and from a source release tarball. When building from a git checkout instead of from a source tarball, the following additional dependencies are required:
- GNU autotools (autoconf/automake/libtool).
- Autoconf archive, in the 1.26 and 1.28 series exclusively.
3.3 - Building
This section provides information about how to build and install the libqmi
library.
3.3.1 - Building libqmi 1.30 or later with Meson
The first stable series with support for building with the meson suite is 1.30. All the older stable series before 1.30 exclusively used the GNU autotools build system.
Building from a git checkout
When using meson, the builds are always triggered from git checkouts, there is no source release tarball involved. The basic build steps would be as follows:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
$ cd libqmi
$ meson setup build --prefix=/usr
$ ninja -C build
Optional switches
Additional optional switches that may be given to the meson
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - The QMI-over-MBIM feature is enabled by default. In order to disable it, the additional
-Dmbim_qmux=false
switch should be given. - The QMI-over-QRTR feature is enabled by default. In order to disable it, the additional
-Dqrtr=false
switch should be given. - If the project should build support for only a certain subset of QMI commands, the user can select which collection of commands should be used with the
-Dcollection
switch:-Dcollection=minimal
will select the minimum number of QMI commands required to have a data connection up.-Dcollection=basic
will select the minimum number of QMI commands required by ModemManager.-Dcollection=full
, or omitting the switch, will select all the available QMI commands.-Dcollection=XXXX
will select the QMI commands listed in the user-provideddata/qmi-collection-XXXX.json
file in the project sources.
- The gtk-doc documentation is disabled by default. In order to enable it, the additional
-Dgtk_doc=true
switch should be given. - The GObject introspection support is enabled by default. In order to disable it, the additional
-Dintrospection=false
switch should be given. - The bash-completion support is enabled by default. In order to disable it, the additional
-Dbash_completion=false
switch should be given. - The default build type in meson if none explicitly specified is
debug
, which means debug symbols are included and optimization is fully disabled. The--buildtype=release
switch can be used to remove debug symbols and to enable optimization level to the maximum.
An example project build using all the above optional switches could be:
$ meson setup build \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--buildtype=release \
-Dcollection=basic \
-Dmbim_qmux=false \
-Dqrtr=false \
-Dgtk_doc=true \
-Dintrospection=false \
-Dbash_completion=false
$ ninja -C build
Installing
The installation on the prefix selected during meson setup
can be done with the following command:
$ sudo ninja -C build install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libqmi library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo ninja -C build uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
3.3.2 - Building libqmi 1.30 or earlier using GNU autotools
The last stable series with support for building with the GNU autotools suite is 1.30. All the new stable series after 1.30 will exclusively use the meson build system.
Building from a release source tarball
The basic build and installation of the project can be done from an official release source tarball, in the following way:
$ wget https://www.freedesktop.org/software/libqmi/libqmi-1.30.0.tar.xz
$ tar -Jxvf libqmi-1.30.0.tar.xz
$ cd libqmi-1.30.0
$ ./configure --prefix=/usr
$ make
Optional switches
Additional optional switches that may be given to the configure
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - If the QMI-over-MBIM feature is required, the additional
--enable-mbim-qmux
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the QMI-over-QRTR feature is required, the additional
--enable-qrtr
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the project should build support for only a certain subset of QMI commands, the user can select which collection of commands should be used with the
--enable-collection
switch:--enable-collection=minimal
will select the minimum number of QMI commands required to have a data connection up.--enable-collection=basic
will select the minimum number of QMI commands required by ModemManager.--enable-collection=full
, or omitting the switch, will select all the available QMI commands.--enable-collection=XXXX
will select the QMI commands listed in the user-provideddata/qmi-collection-XXXX.json
file in the project sources.
- If the documentation should be rebuilt, the additional
--enable-gtk-doc
switch should be given. Omitting this switch will imply auto-detecting whether the documentation can be rebuilt with the already installed dependencies. - If the introspection support should be included in the build, the additional
--enable-introspection
switch should be given. Omitting this switch will imply auto-detecting whether the introspection can be built with the already installed dependencies. - When developing changes to the library or debugging issues, it is recommended to build with debug symbols so that running the program under
gdb
produces useful backtrace information. This can be achieved by providing user compiler flags like these:CFLAGS="-ggdb -O0"
An example project build using all the above optional switches could be:
$ ./configure \
--prefix=/usr \
--libdir=/usr/lib/x86_64-linux-gnu \
--enable-mbim-qmux \
--enable-qrtr \
--enable-collection=basic \
--enable-gtk-doc \
--enable-introspection \
CFLAGS="-ggdb -O0"
$ make
Running ./configure --help
will show all the possible switches that are supported.
Building from a git checkout
When building from a git checkout, there is one single additional step required to build the project: running the included autogen.sh
in order to setup the GNU autotools project and generate a configure
script:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
$ cd libqmi
$ NOCONFIGURE=1 ./autogen.sh
$ ./configure --prefix=/usr
$ make
The same optional switches may be given to the configure
script when building from a git checkout.
Installing
The installation on the prefix selected during configure
can be done with the following command:
$ sudo make install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libqmi library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo make uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
4 - ModemManager
This section provides information about the ModemManager
daemon, the libmm-glib
library, and the mmcli
command line tool.
4.1 - Dependencies
Common dependencies
Before you can compile the ModemManager project, you will need at least the following tools:
- A compliant C toolchain: e.g.
glibc
ormusl libc
,gcc
orclang/llvm
. - pkg-config, a tool for tracking the compilation flags needed for libraries.
- The glib2 library.
- For ModemManager >= 1.18, glib2 >= 2.56.
- For ModemManager >= 1.14, glib2 >= 2.48
- For ModemManager >= 1.6 and < 1.14, glib2 >= 2.36
- For ModemManager >= 1.0 and < 1.6, glib2 >= 2.32
- The libgudev library.
- For ModemManager >= 1.18, libgudev >= 232.
- For ModemManager >= 1.0 and < 1.18, libgudev >= 147.
- The gettext tools.
- For ModemManager >= 1.8, gettext >= 0.19.8.
- For ModemManager >= 1.6 and < 1.8, gettext >= 0.19.3.
- For ModemManager >= 1.0 and < 1.6, gettext >= 0.17.
In addition to the previous mandatory requirements, the project also has several optional dependencies that would be needed when enabling additional project features:
- libmbim, in order to use the MBIM protocol.
- For ModemManager >= 1.18, libmbim >= 1.26.
- For ModemManager >= 1.14, libmbim >= 1.24.
- For ModemManager >= 1.8 and < 1.14, libmbim >= 1.18.
- For ModemManager >= 1.6 and < 1.8, libmbim >= 1.14.
- For ModemManager >= 1.0 and < 1.6, libmbim >= 1.4.
- libqmi, in order to use the QMI protocol.
- For ModemManager >= 1.18, libqmi >= 1.30.
- For ModemManager >= 1.16, libqmi >= 1.28.
- For ModemManager >= 1.14 and < 1.16, libqmi >= 1.26.
- For ModemManager >= 1.12 and < 1.14, libqmi >= 1.24.
- For ModemManager >= 1.10 and < 1.12, libqmi >= 1.22.
- For ModemManager >= 1.8 and < 1.10, libqmi >= 1.20.
- For ModemManager >= 1.6 and < 1.8, libqmi >= 1.16.
- For ModemManager >= 1.2 and < 1.6, libqmi >= 1.6.
- For ModemManager >= 1.0 and < 1.2, libqmi >= 1.4.
- libqrtr-glib, in order to use Qualcomm SoCs with the QRTR bus.
- For ModemManager >= 1.18, libqrtr-glib >= 1.0.
- libpolkit-gobject >= 0.97, in order to allow access control on the DBus methods.
- systemd support libraries (libsystemd >= 209 or libsystemd-login >= 183), for the optional suspend and resume support.
- gtk-doc tools, in order to regenerate the documentation.
- gobject-introspection, in order to generate the introspection support.
Dependencies when building ModemManager 1.18 or later with meson
When building with meson, the following additional dependencies are required:
The following optional dependencies are available when building with meson:
- bash-completion, in order to add completion support for the command line tools.
Dependencies when building ModemManager 1.18 or earlier with GNU autotools
When building with the GNU autotools, the following additional dependencies are required:
There are two main ways to build the library using GNU autotools: from a git repository checkout and from a source release tarball. When building from a git checkout instead of from a source tarball, the following additional dependencies are required:
- GNU autotools (autoconf/automake/libtool).
- Autoconf archive, in the 1.16 series exclusively.
4.2 - Building
This section provides information about how to build and install the ModemManager
daemon and its libraries and utilities.
4.2.1 - Building ModemManager 1.18 or later with Meson
The first stable series with support for building with the meson suite is 1.18. All the older stable series before 1.18 exclusively used the GNU autotools build system.
Building from a git checkout
When using meson, the builds are always triggered from git checkouts, there is no source release tarball involved. The basic build steps would be as follows:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
$ cd libqmi
$ meson setup build --prefix=/usr --sysconfdir=/etc
$ ninja -C build
Optional switches
Additional optional switches that may be given to the meson
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - If the MBIM protocol support is required, the additional
-Dmbim=true
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the QMI protocol support is required, the additional
-Dqmi=true
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the QRTR protocol support is required, the additional
-Dqrtr=true
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - The suspend/resume handling is enabled by default. In order to disable it, the additional
-Dsystemd_suspend_resume=false
should be given. - The gtk-doc documentation is disabled by default. In order to enable it, the additional
-Dgtk_doc=true
switch should be given. - The GObject introspection support for the
libmm-glib
library is enabled by default. In order to disable it, the additional-Dintrospection=false
switch should be given. - The bash-completion support is enabled by default. In order to disable it, the additional
-Dbash_completion=false
switch should be given. - The default build type in meson if none explicitly specified is
debug
, which means debug symbols are included and optimization is fully disabled. The--buildtype=release
switch can be used to remove debug symbols and to enable optimization level to the maximum.
An example project build using all the above optional switches could be:
$ meson setup build \
--prefix=/usr \
--sysconfdir=/etc \
--libdir=/usr/lib/x86_64-linux-gnu \
--buildtype=release \
-Dqmi=true \
-Dmbim=true \
-Dqrtr=true \
-Dsystemd_suspend_resume=false \
-Dgtk_doc=true \
-Dintrospection=false \
-Dbash_completion=false
$ ninja -C build
Installing
The installation on the prefix selected during meson setup
can be done with the following command:
$ sudo ninja -C build install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libmm-glib library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo ninja -C build uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
4.2.2 - Building ModemManager 1.18 or earlier using GNU autotools
The last stable series with support for building with the GNU autotools suite is 1.18. All the new stable series after 1.18 will exclusively use the meson build system.
Building from a release source tarball
The basic build and installation of the project can be done from an official release source tarball, in the following way:
$ wget https://www.freedesktop.org/software/ModemManager/ModemManager-1.18.0.tar.xz
$ tar -Jxvf ModemManager-1.18.0.tar.xz
$ cd ModemManager-1.18.0
$ ./configure --prefix=/usr --sysconfdir=/etc
$ make
Optional switches
Additional optional switches that may be given to the configure
command above would be:
- In Debian/Ubuntu systems the default location for libraries depends on the architecture of the build, so instead of the default
/usr/lib
path that would be in effect due to--prefix=/usr
, the user should also give an explicit--libdir
path pointing to the correct location. E.g. on a 64bit Ubuntu/Debian build, the user would use--prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
. - If the MBIM protocol support is required, the additional
--with-mbim
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the QMI protocol support is required, the additional
--with-qmi
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the QRTR protocol support is required, the additional
--with-qrtr
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the suspend/resume handling is required, the additional
--with-suspend-resume=systemd
should be given. Omitting this switch will imply auto-detecting whether the feature can be built with the already installed dependencies. - If the documentation should be rebuilt, the additional
--enable-gtk-doc
switch should be given. Omitting this switch will imply auto-detecting whether the documentation can be rebuilt with the already installed dependencies. - If the introspection support for the
libmm-glib
library should be included in the build, the additional--enable-introspection
switch should be given. Omitting this switch will imply auto-detecting whether the introspection can be built with the already installed dependencies. - When developing changes to the project or debugging issues, it is recommended to build with debug symbols so that running the program under
gdb
produces useful backtrace information. This can be achieved by providing user compiler flags like these:CFLAGS="-ggdb -O0"
An example project build using all the above optional switches could be:
$ ./configure \
--prefix=/usr \
--sysconfdir=/etc \
--libdir=/usr/lib/x86_64-linux-gnu \
--with-qmi \
--with-mbim \
--with-suspend-resume=systemd \
--enable-gtk-doc \
--enable-introspection \
CFLAGS="-ggdb -O0"
$ make
Running ./configure --help
will show all the possible switches that are supported.
Building from a git checkout
When building from a git checkout, there is one single additional step required to build the project: running the included autogen.sh
in order to setup the GNU autotools project and generate a configure
script:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
$ cd ModemManager
$ NOCONFIGURE=1 ./autogen.sh
$ ./configure --prefix=/usr --sysconfdir=/etc
$ make
The same optional switches may be given to the configure
script when building from a git checkout.
Installing
The installation on the prefix selected during configure
can be done with the following command:
$ sudo make install
Please note that the command above will install the library in the system default path for libraries, possibly overwriting any previous libmm-glib library that may already exist from a package manager installed package. See the FAQ section for comments on how to install in /usr/local
instead.
Location of the DBus service files
By default the DBus service files provided by ModemManager are installed under <prefix>/share/dbus-1/system.d/
. If the user uses the default /usr/local
prefix instead of the suggested /usr
prefix, the DBus service files would be installed in a path that is completely ignored by DBus. If the service files haven’t changed with respect to the one provided by the package manager, this issue can probably be ignored.
Location of the udev rules
By default the udev rules provided by ModemManager are installed under /lib/udev/rules.d/
, out of the prefix provided by the user. If the user uses the default /usr/local
prefix instead of the suggested /usr
prefix, the udev rules would not change location. Changing the location of where the udev rules are installed so that the package manager provided ones are not overwritten can be done e.g. with --with-udev-base-dir=/usr/local/lib/udev/rules.d
, but note that these rules will not be actively used by udev as they are not installed in a standard path.
Location of the systemd init files
By default the systemd init files provided by ModemManager are installed under the path specified by the systemd library pkg-config
file in the systemdsystemunitdir
variable, e.g. /lib/systemd/system/
. This path is completely independent to the prefix provided by the user. Changing the location of where the systemd init files are installed so that the package manager provided ones are not overwritten can be done e.g. with --with-systemdsystemunitdir=/usr/local/lib/systemd/system
, but note that the init file will not be actively used by systemd as it is not installed in a standard path.
Uninstalling
If you have manually installed the project with the steps above, it can be uninstalled in the same way:
$ sudo make uninstall
If the manual install overwrote the package manager installed files, it is suggested to force a re-install of the corresponding packages at this point, so that the system is not left with missing files.
4.3 - Debugging
Daemon debug logs
Gathering debug logs of both NetworkManager
and ModemManager
daemons involves several steps. Although these daemons allow to configure the log level manually while running, some of the issues to debug may require a full reboot of both processes, so the steps below try to cover the most generic case.
Note that the debug logs may contain sensitive information (e.g. PIN number, APN settings, SMS contents). Feel free to remove that information when providing logs to the developers, specifying which was the information removed.
The NetworkManager
daemon debug logs would only be required to analyze connectivity related problems. If the issue is unrelated to data connectivity, just the ModemManager
daemon debug log should be enough.
When using systemd
Mask and stop the services:
$> sudo systemctl disable NetworkManager ModemManager
$> sudo systemctl stop NetworkManager ModemManager
Manually run with debug enabled:
$> sudo /usr/sbin/ModemManager --debug
$> sudo /usr/sbin/NetworkManager --debug --log-level=DEBUG
Now, reproduce your issue, and gather debug logs. Use Ctrl+C to stop both processes.
Then, unmask the services and start them:
$> sudo systemctl enable NetworkManager ModemManager
$> sudo systemctl start NetworkManager ModemManager
When not using systemd
If you are not using systemd, you can avoid getting the processes automatically launched (e.g. by DBus activation) by moving the program files to another path:
$> sudo mv /usr/sbin/NetworkManager /
$> sudo mv /usr/sbin/ModemManager /
$> sudo killall -TERM NetworkManager
$> sudo killall -TERM ModemManager
Manually run with debug enabled (using the new path):
$> sudo /ModemManager --debug
$> sudo /NetworkManager --debug --log-level=DEBUG
Now, reproduce your issue, and gather debug logs. Use Ctrl+C to stop both processes.
Finally, recover the original places for the program files:
$> sudo mv /ModemManager /usr/sbin/
$> sudo mv /NetworkManager /usr/sbin/
qmi-proxy or mbim-proxy debug logs
Sometimes debugging problems in ModemManager requires not only the daemon’s own debug log, but also the verbose logs of the qmi-proxy
or mbim-proxy
processes, which are the ones synchronizing the access to the QMI or MBIM control ports. In order to gather these additional logs, explicitly kill the processes and manually launch them in a separate terminal BEFORE running ModemManager --debug
:
$> sudo killall mbim-proxy
$> sudo /usr/libexec/mbim-proxy --no-exit --verbose
$> sudo killall qmi-proxy
$> sudo /usr/libexec/qmi-proxy --no-exit --verbose
Usually only one of these proxies is used, there is no need to debug both at the same time.
4.4 - FCC unlock procedure
Short summary
Since ModemManager 1.18.4, the following applies:
- The FCC unlock procedure is no longer enabled by default.
- Laptop vendors may provide custom packages to enable their own FCC unlock scripts in
${libdir}/ModemManager/fcc-unlock.d
. - Users may manually enable the ModemManager-provided FCC unlock scripts in
${sysconfdir}/ModemManager/fcc-unlock.d
. - Distribution packages should install the ModemManager-provided FCC unlock scripts in
${datadir}/ModemManager/fcc-unlock.available.d/
- Distribution packages should not enable the ModemManager-provided FCC unlock scripts in either
${sysconfdir}/ModemManager/fcc-unlock.d
or${libdir}/ModemManager/fcc-unlock.d
.
The procedure for users to manually enable all ModemManager-provided FCC unlock scripts in a system where ${datadir}
is /usr/share
and ${sysconfdir}
is /etc
would be:
$ sudo ln -sft /etc/ModemManager/fcc-unlock.d /usr/share/ModemManager/fcc-unlock.available.d/*
What is the FCC lock?
The FCC lock is a software lock integrated in WWAN modules shipped by several different laptop manufacturers like Lenovo, Dell, or HP. This locks prevents the WWAN module from being put online until some specific unlock procedure (usually a magic command sent to the module) is done.
If the specific unlock procedure is not done, any attempt to enable the radio with any kind of protocol will fail:
AT+CFUN=1
will fail, likely with just anERROR
response.QMI DMS Set Operating Mode (ONLINE)
will fail, likely with anInvalid transition
error.MBIM Radio State (ON)
will fail, likely with anOperation not allowed
error.
The purpose of this lock is, according to the manufacturers, to have a way to bind the WWAN module to a specific laptop, so that the whole bundle of laptop+module can go through the FCC certification process for radio-enabled devices in the USA. This lock has no other known purpose out of the US regulation.
The FCC lock is also part of a mutual authentication attempt between module and laptop:
- The laptop BIOS comes with an allowlist of modules that can be installed in the laptop.
- The WWAN module comes with a FCC lock that should be unlocked by approved laptops only.
Laptop manufacturers should in theory provide a custom FCC unlock tool so that users can use the modules, but the reality is sometimes far from ideal:
- The unlock tools may be provided only for Windows, if the laptops were not FCC certified to be used in GNU/Linux distributions.
- The unlock tools are usually provided as proprietary binary programs that are non-auditable and still need to be run as root in the system.
- The unlock tools will perform system checks to detect which kind of laptop the module is installed in, and if it is not one of the laptops certified by the vendor for use under GNU/Linux, the tool may not unlock the modem, even if the same setup can be used in Windows.
- The unlock tools sometimes fail to be available for Linux users by the time the laptops are ready to be sold.
FCC unlock procedures in ModemManager < 1.18.4
When the first FCC unlocked modems were shipped in Dell laptops sometime around 2015, users of GNU/Linux distributions started to complain about not being able to use their WWAN modules. These modems were rebranded Sierra Wireless devices, and surprisingly, using the Sierra Wireless provided kernel drivers the modules were unlocked successfully. This lead to finding the QMIDMSSWISetFCCAuth()
operation (DMS 0x555F
) in the Sierra SDK, which was successfully reverse engineered into libqmi 1.12.4.
The FCC unlock logic done for these modules was added into ModemManager 1.4.4 for all QMI capable devices, just attempting to run it any time we found the attempt to put the module online failed.
In 2018, Dell included newer FCC locked modems, like the Foxconn rebranded DW5821e, in their laptops. Dell also provided a Windows unlock tool (DW5821e and DW5829e Click Cust Kit), and likely some built-in unlock tool hidden in the Ubuntu-based preinstallations they shipped in the laptops when sold with GNU/Linux. During this time, there were some attempts to reverse engineer the unlock procedure using a USB monitoring capture from Windows when running the Cust Kit tool, but none of them seemed to be usable for some reason.
Fast forward to 2021, when Lenovo shipped the newest X1 Nano and Carbon Gen9 laptops with new FCC locked modules, and users started to complain again. These laptops were released with 3 different approved modules: Foxconn SDX55, Quectel EM120, and Fibocom L860. By the time the first SDX55 modules were available there was still no unlock tool provided by Lenovo, so there was not much anyone could do. But the SDX55 was a Foxconn module, same as the DW5821e for which the Dell Cust Kit tool was reverse engineered, and so users tried that same procedure that never worked with the DW5821e, just to find that it worked fine with the SDX55. This unlock procedure was included in libqmi 1.28.6, and integrated for automatic unlocking in ModemManager 1.16.6.
Not much later, users started to complain about the Quectel EM120 module being locked. A user of this module was able reverse engineer the Lenovo-provided lenovo-wwan-dpr
tool and discover the magic MBIM command that was being sent in this case. This procedure has not been integrated for automatic unlock in any ModemManager version.
Whether to automatically unlock or not the modules in ModemManager
When the first FCC unlock procedure was reverse engineered for the rebranded Sierra Wireless modules, there was not much discussion on whether the procedure should be run or not by ModemManager. It was obviously defeating the purpose of the laptop manufacturer, but so was the Sierra Wireless driver source provided by Sierra Wireless themselves. If they were doing it, why should ModemManager not do it?
The picture with the new WWAN modules in Lenovo laptops is completely different, though. The FCC unlock procedure for the EM120 was reverse engineered from the Lenovo-provided lenovo-wwan-dpr
tool, which performs not only the FCC unlock, but also dynamic power reduction based on sensors in the laptop. This means that the actual magic command used to unlock the module may be somehow related to some SAR level defaults configured in the WWAN module, and as we don’t have the full picture of what it does or doesn’t, it can be considered a bit risky to perform the automatic unlock unconditionally. The same reasoning would apply for the Foxconn SDX55, for which not even a Lenovo provided tool was used to reverse engineer the unlock procedure. The sad truth is that only the laptop vendors and modem manufacturers know what those commands are really doing, and they may be doing more than FCC unlocking the modules. If the procedures are related in any way to SAR levels and dynamic power reduction, ModemManager should better not automatically unlock these modules.
This discussion went on for several months, both publicly in gitlab issues and mailing list, and privately via emails and calls with the laptop vendors, modem manufacturers and other key members of the community. After much thought a clear way forward was decided, that would hopefully meet halfway of both sides: ModemManager will keep on providing support for the known FCC unlock procedures, but no longer automatically: the user must install and select the FCC unlock procedure needed in the specific laptop being used.
FCC unlock procedures in ModemManager >= 1.18.4
Since release 1.18.4, the ModemManager daemon no longer automatically performs the FCC unlock procedure by default. The user must, under their own responsibility, enable the automatic FCC unlock as shipped by ModemManager.
ModemManager ships several scripts installed under ${datadir}/ModemManager/fcc-unlock.available.d
, and named as vid:pid
with either the PCI or USB vendor and product IDs. E.g. in a system where ${datadir}
is /usr/share
:
- For the HP 820 G1 (EM7355):
/usr/share/ModemManager/fcc-unlock.available.d/03f0:4e1d
- For the Dell DW5570 (MC8805):
/usr/share/ModemManager/fcc-unlock.available.d/413c:81a3
- For the Dell DW5808 (MC7355):
/usr/share/ModemManager/fcc-unlock.available.d/413c:81a8
- For the Lenovo-shipped EM7455:
/usr/share/ModemManager/fcc-unlock.available.d/1199:9079
- For the Foxconn SDX55:
/usr/share/ModemManager/fcc-unlock.available.d/105b:e0ab
- For the Quectel EM120:
/usr/share/ModemManager/fcc-unlock.available.d/1eac:1001
These scripts in ${datadir}
are not automatically used by ModemManager. In order for ModemManager to automatically attempt a specific FCC unlock procedure, the user must create a link to the script from ${datadir}/ModemManager/fcc-unlock.available.d
into the ${sysconfdir}/ModemManager/fcc-unlock.d
directory. E.g. in a system where ${datadir}
is /usr/share
and ${sysconfdir}
is /etc
:
$ sudo ln -sft /etc/ModemManager/fcc-unlock.d /usr/share/ModemManager/fcc-unlock.available.d/<vid>:<pid>
ModemManager will only use the unlock script required for the specific vid:pid
the module exposes, so users may also choose to link all the files from ${datadir}/ModemManager/fcc-unlock.available.d
into ${sysconfdir}/ModemManager/fcc-unlock.d
. E.g. in a system where ${datadir}
is /usr/share
and ${sysconfdir}
is /etc
:
$ sudo ln -sft /etc/ModemManager/fcc-unlock.d /usr/share/ModemManager/fcc-unlock.available.d/*
It is suggested that GNU/Linux distributions do not ship these FCC unlock scripts enabled in the ${sysconfdir}/ModemManager/fcc-unlock.d
directory themselves, for the same reasons that ModemManager does not to perform the automatic unlock unconditionally.
The ${sysconfdir}/ModemManager/fcc-unlock.d
path should be exclusively used for links or programs manually installed by the user.
The scripts shipped by ModemManager use either mbimcli
or qmicli
to perform the raw FCC unlock procedure. The user should make sure those tools are installed in the system, as they are not direct dependencies of ModemManager in any way. E.g. in Debian/Ubuntu systems, these tools are provided by the libmbim-utils
and libqmi-utils
packages.
Integration with third party FCC unlock tools
Laptop vendors and modem manufacturers may also provide their own FCC unlock tools, e.g. running their own proprietary binary programs to perform the unlock in the safest way they know. These tools may be packaged for each distribution, and should be installed in ${libdir}/ModemManager/fcc-unlock.d
.
The third party FCC unlock tools will allow an easy integration of the procedure with ModemManager, so that the unlock is performed only when required to do so (when attempting to go online) and not at random times (which would make the state of the modem cached by ModemManager inconsistent).
Third party FCC unlock scripts or programs should consider the same limitations as imposed to the ModemManager shipped ones:
- Must be owned by the root user.
- Must be readable and executable by the owner exclusively and not setuid.
- Will receive the full modem DBus path as first argument, followed by the control port names (without
/dev
prefix) of the modem to unlock. - Must not launch processes on background; i.e. these are not service management scripts.
- Must run in less than 5 seconds, or otherwise they will be killed by ModemManager.
- Must return 0 on success.
Once the tool is run by ModemManager, the daemon will attempt again to bring the modem into online power state using the protocol specific messages. If this operation fails again, the FCC unlock procedure will not be automatically tried any more.
The ${libdir}/ModemManager/fcc-unlock.d
path should be exclusively used for links or programs installed by third party packages.
5 - Contribution Guidelines
This section provides information about how users can contribute to the project, either by reporting issues, suggesting new features or developing fixes.
5.1 - Using gitlab
The Mobile Broadband group in the gitlab instance maintained by the freedesktop.org community contains the following projects:
- ModemManager: https://gitlab.freedesktop.org/mobile-broadband/ModemManager
- libqmi: https://gitlab.freedesktop.org/mobile-broadband/libqmi
- libmbim: https://gitlab.freedesktop.org/mobile-broadband/libmbim
- libqrtr-glib: https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib
The following sections provide a quick overview of what the basic functionality is and how to set it up by users or first-time developers. This Community Edition gitlab instance is no different to others, so users that have used gitlab in the past should see no problem in using this site. For detailed help on all the features supported, the gitlab instance also publishes its own help.
5.1.1 - Basic setup
Cloning the upstream repository
If the user only wants to build and install the latest development versions (without suggesting any changes to them), the upstream source repositories can be checked out using git
and the HTTPS paths for each of them. These paths are given in the dialog displayed after clicking the Clone button.
The git clone commands for each of these repositories would be:
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
$ git clone https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
$ git clone https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
Creating a new user account
In order to access the basic functionality of the gitlab instance, like reporting new issues or commenting on already existing ones, a new user account should be registered in the gitlab instance.
Reporting new issues
The user can browse existing issues or report new ones in the project specific Issues page:
- ModemManager: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues
- libqmi: https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/issues
- libmbim: https://gitlab.freedesktop.org/mobile-broadband/libmbim/-/issues
- libqrtr-glib: https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib/-/issues
Once the issue is reported, the maintainers may request to add additional explanations, or provide debug logs with detailed protocol information.
5.1.2 - Developer setup
Adding SSH keys to the user account
If the user is prepared to suggest changes to the upstream repositories, the first step is to setup at least one SSH key. You can create a public/private key pair locally in your PC as follows:
$ ssh-keygen -t rsa
The previous command will generate a public key (~/.ssh/id_rsa.pub
) and a private key (~/.ssh/id_rsa
). The user should then navigate in the gitlab site to the “SSH keys” section in the “User Settings” of the new user profile in order to register the SSH key. The user should copy and paste the public key that was generated (i.e. ~/.ssh/id_rsa.pub
).
Fork and checkout the project
Once the user is logged in the new account, a new Fork button will be shown at the top-right corner in each of the upstream project pages.
The user should only fork the project that needs to modify. There is really no need to create user forks if the user isn’t going to suggest any modification to the upstream repositories. E.g. if the user is planning to fix a bug in ModemManager, there would be no need to fork libmbim, libqmi or libqrtr-glib.
Once the project is forked, gitlab will create a whole new project page under the user account. E.g. if all four projects are forked by username
:
- ModemManager: https://gitlab.freedesktop.org/username/ModemManager
- libqmi: https://gitlab.freedesktop.org/username/libqmi
- libmbim: https://gitlab.freedesktop.org/username/libmbim
- libqrtr-glib: https://gitlab.freedesktop.org/username/libqrtr-glib
These forked projects will have their own Clone buttons, and when they are clicked, the user-specific clone paths will be shown.
The user should use the paths listed under Clone with SSH, and the clone operations will succeed if the SSH keys were configured properly in an earlier step.
$ git clone git@gitlab.freedesktop.org:username/libqrtr-glib.git
$ git clone git@gitlab.freedesktop.org:username/libmbim.git
$ git clone git@gitlab.freedesktop.org:username/libqmi.git
$ git clone git@gitlab.freedesktop.org:username/ModemManager.git
Setup upstream remote
As soon as the new user-specific git repositories are cloned, they will have the origin
remote configured to point to them. These git repositories will not be automatically kept in sync with the original upstream repositories, it is up to the user to do that.
In order to make sure the user can sync with the upstream repositories periodically, a new additional remote can be setup as follows:
$ cd libqrtr-glib
$ git remote add upstream https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib
$ cd libmbim
$ git remote add upstream https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
$ cd libqmi
$ git remote add upstream https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
$ cd ModemManager
$ git remote add upstream https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
Once the upstream
remotes are setup, the user can now sync the main
branch between both. E.g.:
$ cd libqrtr-glib
$ git checkout main // change to the main branch
$ git fetch upstream // fetch updates from upstream remote
$ git merge upstream/main // merge changes from upstream main branch
$ git push origin main // update main branch in origin remote
$ cd libmbim
$ git checkout main
$ git fetch upstream
$ git merge upstream/main
$ git push origin main
$ cd libqmi
$ git checkout main
$ git fetch upstream
$ git merge upstream/main
$ git push origin main
$ cd ModemManager
$ git checkout main
$ git fetch upstream
$ git merge upstream/main
$ git push origin main
During development, it’s suggested to keep separate per-feature or per-fix branches, and keep the main
branch always in sync with the upstream repository.
5.2 - Coding style
Quoting the C coding style guidelines from the GNOME project:
The Single Most Important Rule when writing code is this: check the surrounding code and try to imitate it. As a maintainer it is dismaying to receive a patch that is obviously in a different coding style to the surrounding code. This is disrespectful, like someone tromping into a spotlessly-clean house with muddy shoes. So, whatever this document recommends, if there is already written code and you are patching it, keep its current style consistent even if it is not your favorite style.
So, the best way to learn and get used to the coding style used in this projects is really to read the already existing code, as that will help solve most of the doubts one may have when writing new code. If reading the code is not enough, the following coding style guidelines should help as well.
Basic formatting
Line length
There is no strict requirement on the length of the source code lines, especially since there are very long type and function names in e.g. libqmi or libmbim. It is up to the developer how to split lines if appropriate.
Comments
Code comments are always written between /*
and */
, and multiline comments will have a *
prefix in all lines except for the first one.
{
/* a very long multiline comment to explain something
* with a lot of detail; see how all the lines after the
* first one have the asterisk prefix.
*/
/* single line comments also in the same way, never with // */
}
Always place a whitespace after `/*` and before `*/`.
Indentation and alignment
The sources use 4 spaces to indent, there should be no tabs or longer indentations. In the same way, the alignment is exclusively done with spaces, never with tabs.
{
/* indented 4 spaces */
if (something) {
/* indented 4 more spaces */
do_something (variable1,
variable2,
variable3,
variable4);
/* aligned --^-- here */
}
}
Spacing
Both method calls and conditionals (e.g. if
, for
, while
…) should always have a whitespace before the (
character.
{
/* v-------- whitespace before ( */
if (something) {
/* v-------- whitespace before ( */
do_something (variable1,
variable2,
variable3,
variable4);
}
}
There should be no whitespace after (
or before )
.
Braces
Each function has its opening brace at the next line on the same indentation level as its header.
The blocks inside a function, however, have their opening braces at the same line as their respective control statements; closing braces remain in a line of their own, unless followed by a keyword else
or while
.
If the contents of the statement are one single command, the braces may be optionally skipped.
static void
a_nice_function (void)
{ /* <--------- open brace of function in next line */
if (something) { /* <--------- open brace of statement in same line */
...
do_something ();
} else if (something_else) { /* <--------- closing brace followed by else-if */
...
do_something_else ();
} else /* <--------- braces skipped for one-command contents */
do_something_completely_different ();
}
Variables
Variables are always named in lowercase, and separating words with underscores.
The name of the variable should clearly define the purpose of the variable. Using generic names are only allowed for certain very specific cases, e.g. a short name like i
is allowed for loop iterators and such.
Variables are defined always at the beginning of the code block where they’re scoped. If a variable is scoped inside an inner scope, it’s also better to define it inside the inner block itself.
If possible, the names of the variables given in the same block should also be vertically aligned. Depending on the length of the type names in the same variable block, more than one vertically aligned groups may be given.
After the definition of all variables, there should be a whiteline before the first method call.
{
/* all variables defined together at the beginning of the block */
GError *inner_error = NULL;
gint i;
/* <---- whiteline here! */
for (i = 0; i < SOME_MAX; i++) {
/* inside an inner block, variables that apply to the block;
* in this case with some variable types that are very long
* so they're aligned vertically in different groups */
SomeVeryLongTypeNameWeFindHere input_message;
AnotherDifferentVeryLongTypeNameWeGot output_message;
const gchar *name;
gint weight;
/* <---- whiteline here! */
...
name = do_something (i);
if (name)
break;
}
}
Pointers
When defining variables that are pointers, the asterisk must always go next to the variable name, never next to the type.
This is so that there is no confusion on what types are being declared if e.g. more than one variable is defined in the same line.
{
/* These are two pointers to guint variables. With the asterisk next to the
* variable name, it's clear they are both pointers. */
guint *val1, *val2;
/* If the asterisk was placed next to the type, it would get confusing.
* This is a pointer to a guint (val3) and a guint (val4), not two
* pointers. */
guint* val3, val4;
...
}
Methods
Methods are always named in lowercase, and separating words with underscores.
The name of the method should clearly define the purpose of the method.
If possible, the names of the method arguments given in the method declaration and definitions should also be vertically aligned. Depending on the length of the type names, more than one vertically aligned groups may be given.
When a method is defined, it should provide the return type of the method in a separate line, before the name of the method. When a method is declared, the return type should be given in the same line as the name of the method.
Definition of module private methods
Methods that are going to be used exclusively in the same source file where they are defined (private methods) should be made static
, and not declared in any header. The name of this kind of methods doesn’t need to have any explicit prefix.
/* return type and method name in separate lines */
static gboolean
do_something (gint max,
gint min,
const gchar *text,
GError **error)
{
/* definition here */
}
Declaration and definition of module public methods
Methods that are meant to be used out of the source file where they are defined (public methods) should have a clear declaration in a header file and the definition inside the source file with the same file name. All the public methods in the same module should have the same string prefix, clearly stating the module they come from.
E.g. in the header file some-module.h
:
/* return type and method name in the same line */
gboolean some_module_do_something (const gchar *text,
GError **error);
And in source file some-module.c
:
/* return type and method name in separate lines */
gboolean
some_module_do_something (const gchar *text,
GError **error)
{
/* definition here */
}
Symbols
Symbols are always named in uppercase, and separating words with underscores.
The name of the symbol should clearly define the purpose of the symbol.
Symbols are usually defined at the beginning of the header or source file, with an explanation of what they are for given in a comment.
In the same way as methods, if the symbols are defined in the header file of a module, the name of the symbol should have the common prefix used in the module.
/* Maximum time to wait for the operation to complete, in seconds */
#define SOME_MODULE_MAX_TIMEOUT_SECS 10
5.3 - git commit style
Having a proper style in the git commits suggested for inclusion in the projects is also a very important thing. This section provides some hints of what is expected from the git commits suggested by contributors.
As with the source code coding style, the best way to see what kind of git commit format is expected is to look at other commits from other developers in the same project.
Authorship
The author of the git commit should preferably a real person name (Firstname Lastname), as the author of the email is implicitly the one who holds the copyright of the changes done in the commit, unless explicitly stated e.g. with additional copyright lines in the source code.
Basic message formatting
The message of a git commit must be composed of:
- An initial first line with a short description of the change, prefixed by a “module: " string. The module could be some specific object in the code, or some protocol, or some other similar thing. If unsure, the best thing to get a feeling of what you should use as module would be to run
git log <FILE>
(beingthe main file being modified in the commit) and read what other developers have used as module when modifying that same file. - Then an empty whiteline.
- Then the body of the commit, including an optional longer description. This would be optional only for trivial changes for which the first description line is enough. For any change that is a bit more complex, the longer description can be considered mandatory. The body of the message may be composed by multiple paragraphs, and may also include additional information like real program logs, crash backtraces reported by gdb, or even valgrind memcheck log snippets (e.g. when fixing memory leaks).
For text content in the commit message (either first line or body) it is suggested to keep the maximum line length at 70 characteres maximum. This is not a strict rule for the first line though, sometimes just a few more characters are needed, and that would be acceptable.
For log snippets or backtraces included in the commit message, it is suggested to indent them a few characters. Also, there is no line length limitation in this case, but it is suggested to pretty-format them so that the information included is all valuable. E.g. when inserting program logs in the commit message, the developer may first clean them up to remove unrelated log lines, or even remove information that isn’t necessary (e.g. maybe the timestamps are irrelevant for the purpose of the included information, so they can be removed).
Commits may have a Signed-off-by:
line (e.g. as per git commit -s
) but this is not strictly necessary.
When fixing issues reported in the project gitlab, a Fixes <Bug URL>
line is suggested. When this commit is merged to the project git main, gitlab will automatically close the referred issue.
Examples
This is a properly formatted commit message:
base-modem: plug leaks when organizing ports
The GLists maintained in the logic need to be explicitly freed (just
the lists, not the list contents) if we exit early on error or if we
end up deciding that the specific ports are available but unsupported
by the plugin (e.g. if a plugin that doesn't support net ports finds
net ports in the modem).
==225333== 24 bytes in 1 blocks are definitely lost in loss record 2,024 of 5,525
==225333== at 0x483E77F: malloc (vg_replace_malloc.c:307)
==225333== by 0x506C539: g_malloc (in /usr/lib/libglib-2.0.so.0.6600.7)
==225333== by 0x508DC8F: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.6600.7)
==225333== by 0x50636B4: g_list_append (in /usr/lib/libglib-2.0.so.0.6600.7)
==225333== by 0x17E671: mm_base_modem_organize_ports (mm-base-modem.c:1298)
==225333== by 0x1E4409: mm_plugin_create_modem (mm-plugin.c:1094)
==225333== by 0x162C81: mm_device_create_modem (mm-device.c:481)
==225333== by 0x15DE60: device_support_check_ready (mm-base-manager.c:218)
==225333== by 0x4EA8173: ??? (in /usr/lib/libgio-2.0.so.0.6600.7)
==225333== by 0x4EAC6E8: ??? (in /usr/lib/libgio-2.0.so.0.6600.7)
==225333== by 0x16730F: device_context_run_ready (mm-plugin-manager.c:1533)
==225333== by 0x4EA8173: ??? (in /usr/lib/libgio-2.0.so.0.6600.7)
These are NOT a properly formatted commit messages:
Update src/mm-broadband-modem.c, update src/mm-broadband-modem.h, update src/mm-modem-helpers.c, update src/mm-modem-helpers.h, update src/mm-base-modem.h .......
(lacks description of what the commit is doing)
Added dual sim support to Quectel plugin
(no module:
prefix; e.g. should have been quectel: added dual sim support
)
mm-broadband-modem: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut turpis turpis, euismod at gravida at, tincidunt at metus. Maecenas placerat laoreet arcu non luctus. Duis sit amet augue ullamcorper, tincidunt magna ac, porttitor metus.
(first line more than 70 chars)
Contents of the commit
The maintainers of the project will review the commits one by one and therefore, each commit should be self-contained:
- A single commit must only provide one single logical change. It is acceptable to include in the commit additional minor coding style modifications affecting the code being fixed, but that’s it.
- If the changes being suggested in a merge request are a lot, it is therefore expected to have a series of commits implementing the changes. Merge requests that contain one single commit with 5000 line changes across the project will be rejected right away.
- Commits fixing only coding style are also accepted. This is probably an exception to most free/open source software projects, so don’t assume this to be the default elsewhere.
The changes done in a single commit must NEVER break the build, because otherwise git bisect-ing would not be possible.
5.4 - Merge requests
Create a new local branch for the fix or feature
Once a local checkout of the project is available, the user can now create a new local branch for the new feature being developed or for the fix that is going to be suggested. The new branch should be based always on top of upstream/main
.
$ cd ModemManager
$ git fetch upstream
$ git checkout -b my-branch upstream/main
At this point, the user can start modifying files and using git to keep track of the changes, as usual.
Prepare and cleanup the branch
Once the user has developed a series of commits for a given fix or new feature, it is time to suggest the changes for review.
The first thing to do is to make sure the new branch is rebased on top of the latest upstream/main
. E.g. if the branch where the fix was developed was created 2 months ago, it is very likely that new changes have gone to the main
branch in the upstream repository; the user should make sure all those changes don’t conflict with the new ones being suggested.
$ cd ModemManager
$ git fetch upstream
$ git checkout my-branch
$ git rebase upstream/main
If the rebase cannot finish automatically, the user will need to perform an interactive rebase in order to fix any conflict that may have arised.
$ git rebase -i upstream/main
Checklist before pushing the branch for review
Key requirements
- Make sure the gitlab pipelines pass for your branch.
- Make sure git commit style is according to the expected format.
- Make sure coding style is according to the expected format.
The branch must allow git bisecting
In order to allow git bisecting the branch, no single commit should break the build at any point. This can be checked by running a build after each commit in the following way:
$ git rebase -i upstream/main --exec "make -j8"
No new gtk-doc warnings
The developer should make sure the local builds are done with --enable-gtk-doc
, and if there are new warnings introduced by the branch, these must be fixed before suggesting it for review.
E.g. adding a new MBIM service in libmbim could end up triggering the following warnings in the gtk-doc step:
DOC Scanning header files
DOC Introspecting gobjects
DOC Building XML
./libmbim-glib-unused.txt:1: warning: 21 unused declarations. They should be added to libmbim-glib-sections.txt in the appropriate place.
DOC Building HTML
DOC Fixing cross-references
html/libmbim-glib-QDU.html:287: warning: no link for: "MbimQduFileType" -> (<span class="type">MbimQduFileType</span>).
Learning how to fix these type of issues is easy, just investigate how other similar methods or types are documented, and do the same.
Push the branch and create a merge request
In order to create a new merge request against the upstream repository, the user should push the branch to the user-specific repository (origin
remote).
$ cd ModemManager
$ git checkout my-branch
$ git push origin my-branch
Enumerating objects: 57, done.
Counting objects: 100% (57/57), done.
Delta compression using up to 4 threads
Compressing objects: 100% (26/26), done.
Writing objects: 100% (47/47), 8.76 KiB | 2.92 MiB/s, done.
Total 47 (delta 35), reused 32 (delta 21), pack-reused 0
remote:
remote: To create a merge request for my-branch, visit:
remote: https://gitlab.freedesktop.org/username/ModemManager/-/merge_requests/new?merge_request%5Bsource_branch%5D=my-branch
remote:
To gitlab.freedesktop.org:username/ModemManager.git
* [new branch] my-branch -> my-branch
Once the branch is pushed, the git server will provide a link to create a merge request for the newly pushed branch, as seen above.
The user should open the given link, and gitlab will provide a short form to fill before the merge request is finished. Very important things to consider when filling in the form:
- If the merge request contains a series of commits, the user should write a description that explains the purpose of the whole series.
- If the merge request contains one single commit, the description of the merge request can be the commit message.
- The Allow commits from members who can merge to the target branch option in the Contribution section must be enabled. With this option, the project maintainers are allowed to push or rework the changes of the merge request in its original location (the user branch).
Once the Submit merge request button is clicked, the process to create the merge request would be finished, and it would be now time for maintainers to review the changes suggested.
The review process
The review of the merge request is done commit by commit, and therefore each commit should be self-contained, in the sense that it should explain clearly the change being done by itself, even if it is part of a series of commits. If this is not done, e.g. if a huge 1000 line commit changing 100 different files at the same time is suggested, it is very likely that the merge request will be rejected. Not because the change is not good, it may be perfectly good, but because it’s not review-able.
Reworking the branch after review
If the maintainer asks for changes to be done, work on them. Don’t add additional commits on top of the original ones for the changes suggested by the maintainer; instead, fixup the changes in the correct commit. It is very suggested that the user knows how to use git commit --fixup
and git commit --squash
, as these are very powerful tools to have the commits right. A simple usage example of --fixup
can be seen in the following snippet, where a quick fix is added on a given already existing commit in 2 steps: first a new fixup commit is created, then an interactive rebase reorders the commits automatically to apply the fixup commit in the correct place:
$ git log --oneline
91b399cd shared-qmi: acquisition order preference TLV always same items
ef55409b shared-qmi: process all feature checks in SSP response together
1a3c3b9e shared-qmi: if getting TP/SSP fails, assume unsupported
c1dc9339 shared-qmi: add missing feature check flag initialization to UNKNOWN
$ git status
On branch my-branch
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/mm-base-modem.c
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a --fixup 1a3c3b9e
my-branch 9788d020] fixup! shared-qmi: if getting TP/SSP fails, assume unsupported
1 file changed, 3 insertions(+), 1 deletion(-)
$ git log --oneline
9788d020 fixup! shared-qmi: if getting TP/SSP fails, assume unsupported
91b399cd shared-qmi: acquisition order preference TLV always same items
ef55409b shared-qmi: process all feature checks in SSP response together
1a3c3b9e shared-qmi: if getting TP/SSP fails, assume unsupported
c1dc9339 shared-qmi: add missing feature check flag initialization to UNKNOWN
$ git rebase -i --autosquash upstream/main
// inside editor, the fixup commit is reordered and setup to fixup
pick c1dc9339 shared-qmi: add missing feature check flag initialization to UNKNOWN
pick 1a3c3b9e shared-qmi: if getting TP/SSP fails, assume unsupported
fixup 9788d020 fixup! shared-qmi: if getting TP/SSP fails, assume unsupported
pick ef55409b shared-qmi: process all feature checks in SSP response together
pick 91b399cd shared-qmi: acquisition order preference TLV always same items
Successfully rebased and updated refs/heads/aleksander/my-branch.
$ git log --oneline
82ca83ad shared-qmi: acquisition order preference TLV always same items
0a24c403 shared-qmi: process all feature checks in SSP response together
0cdbba14 shared-qmi: if getting TP/SSP fails, assume unsupported
c1dc9339 shared-qmi: add missing feature check flag initialization to UNKNOWN
Once the updated branch is considered ready, the user should re-push the branch to the same place, i.e. the origin
remote and the same branch name as was originally used when creating the merge request. If the branch has been re-created (e.g. after applying fixup/squash commits), the user will need to force push it. There is no need to create a full new merge request after updating the branch.
$ git push --force origin my-branch
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 1.14 KiB | 1.14 MiB/s, done.
Total 5 (delta 4), reused 0 (delta 0), pack-reused 0
remote:
remote: View merge request for my-branch:
remote: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/477
remote:
To gitlab.freedesktop.org:username/ModemManager.git
+ 08c3de0b...9e75a1ff my-branch -> origin/my-branch (forced update)
As seen above, gitlab will provide the link to the already existing merge request that is being updated.
Updating the local branch after a forced push by others
Sometimes the maintainers themselves will do some reworks in the user branch, and ask the user for review of those changes. In that case, the forced push from the previous section may have been done by the maintainers (if the Allows commits from members who can merge to the target branch option has been enabled in the merge request), and the user will need to update the local branch with the latest commits from the remote branch before doing any additional change or in order to locally review the new updates.
The same will be required if the branch is re-created by gitlab itself (e.g. after running Rebase in the merge request page in gitlab).
Synchronizing the remote with the local branch can easily be done with a fetch
operation first (see how the message reports a forced update), and then a hard reset to point the local branch to the new remote one:
$ git fetch origin
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (6/6), 746 bytes | 746.00 KiB/s, done.
From gitlab.freedesktop.org:username/ModemManager.git
+ b0b78e8...693b464 my-branch -> origin/my-branch (forced update)
$ git checkout my-branch
$ git reset --hard origin/my-branch
After the last commit, the local branch will be in sync with the latest contents from the user remote.
Accepting the merge request and merging to main
Once the suggested changes are accepted by the maintainers, one of them will merge the merge request on top of git main. If the changes are bugfixes that apply to older stable releases, the maintainer may also decide to cherry-pick them to the older stable branches. The user should not need to do that at this point.
5.5 - Project communication
Reporting bugs
Bugs should be reported through the FreeDesktop.org gitlab instance:
Suggesting changes or fixes
Changes and fixes should be suggested through the FreeDesktop.org gitlab instance:
- ModemManager merge requests
- libqmi merge requests
- libmbim merge requests
- libqrtr-glib merge requests
Mailing lists
Formal discussion of issues, project features or any general question about the projects should be posted to the corresponding project mailing list. These mailing lists are public and archived for future reference.
Please subscribe to the mailing list before sending new messages, or otherwise each message sent will need to be manually approved by the list administrator.
ModemManager mailing list
Discussions about ModemManager take place on the modemmanager-devel (at) lists.freedesktop.org mailing list:
libqmi mailing list
Discussions about libqmi or libqrtr-glib take place on the libqmi-devel (at) lists.freedesktop.org mailing list:
libmbim mailing list
Discussions about libmbim take place on the libmbim-devel (at) lists.freedesktop.org mailing list:
Matrix and IRC
Informal discussion about the projects can be done in the project Matrix channel at #modemmanager:matrix.org, which is also bridged to the #modemmanager IRC channel in Libera.Chat.
6 - Frequently Asked Questions
This list provides comments and answers to common questions asked in the projects.
Can the projects be installed in /usr/local
instead of /usr
?
Yes, but several things should be considered.
Library lookup with LD_LIBRARY_PATH
All the build examples given for all the projects in this documentation use the --prefix=/usr
switch given to the meson setup
command (or to ./configure
when using GNU autotools) when preparing the build. This prefix is the common one used by distributions when building packages, and so if the user uses the same one, it will end up overwriting the package manager installed files.
In order to avoid overwriting the package manager installed files, the user can avoid giving the explicit --prefix
, and so the default /usr/local
path will be used as prefix. If this approach is taken, the developer can keep the package manager installed libraries in /usr/lib
and the package manager installed command line tools in /usr/bin
, while keeping the custom installed libraries in /usr/local/lib
and the custom installed command line tools in /usr/local/bin
.
Under this scenario, the user can run e.g. the package manager installed mbimcli
in the following way, which will use the package manager installed library from /usr/lib
:
$ /usr/bin/mbimcli
In the same scenario, the user can run the custom installed mbimcli
in the following way, which will use the custom installed library from /usr/local/lib
:
$ LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/mbimcli
But beware because there are distributions like Debian/Ubuntu which add the /usr/local/bin
path to the PATH
environment variable by default, so running the following command would attempt to run the custom installed mbimcli
with the package manager installed library from /usr/lib
(which is obviously a mess and won’t probably work):
$ mbimcli
This complication with the need of the explicit LD_LIBRARY_PATH
is the reason why this guide suggests to overwrite the package manager installed files when installing custom builds.
pkg-config lookup with PKG_CONFIG_PATH
Building a project using as build dependency another project which was installed in /usr/local
will need an explicit PKG_CONFIG_PATH
specifying where the .pc
files are available, e.g.:
$ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig meson setup ...
Additional system files
If the project installs additional system files (e.g. systemd service setup, polkit settings, DBus service files) in /usr/local
instead of /usr
, they will be fully ignored. If the changes being installed require updates in these files, it is advised to avoid installing anywhere else than in /usr
.
How long does it take for a merge request or issue review to happen?
There is no maintainer paid to support these projects, so new issues and merge requests are reviewed once the current maintainer finds free time.
If you would like your issue or merge request to be prioritized, please consider contracting the maintainer (if you’re a company) or sponsoring (if you’re an individual).