Merge remote-tracking branch 'cros/upstream' into 'cros/master'

Contains the following commits:
67974c8 build: version bump to flag existence of new API (USSD) (Aleksander Morgado)
80afb61 collection,basic: add USSD support (Aleksander Morgado)
eb53c31 voice: add support for registering to explicit indications (Aleksander Morgado)
da824be voice: finish USSD request/response/indication support (Aleksander Morgado)
2f71086 voice: add initial USSD definitions (Alexander Couzens)
ac92c32 build: fix default gtk-doc generation (Aleksander Morgado)
401fdec ci: add tests for minimal and basic collections (Aleksander Morgado)
bb5c88b libqmi-glib: allow selecting 'collections' of messages to build (Aleksander Morgado)
05159e1 libqmi-glib,utils: consider CR and LF as valid string characters (Aleksander Morgado)
1638367 libqmi-glib,proxy: fix loss of last requests on client hangup (Teijo Kinnunen)
c8967af build: enable qrtr explicitly in distcheck (Aleksander Morgado)
9625ba6 ci: default test runs distcheck (Aleksander Morgado)
95150ad ci: default test builds gtk-doc (Aleksander Morgado)
444110a ci: install in /usr explicitly (Aleksander Morgado)
df5c537 ci: renamed tests (Aleksander Morgado)
86ca463 libqmi-glib,message: fixed sized strings may be suffixed with 0xFF (Aleksander Morgado)
d1d7284 libqmi-glib,test: stricter "get serving system" testing (Aleksander Morgado)
3203901 libqmi-glib,wds: new verbose call end reasons in 1.24.10 already (Aleksander Morgado)
8bad275 qmi-endpoint-qrtr: use g_autoptr in qrtr_message_cb (Eric Caruso)
da296b7 build: version bump to 1.25.4 to flag existence of new API (5GNR RAT mode preference) (Aleksander Morgado)
d2e403b libqmi-glib,nas: add 5GNR RAT mode preference (Aleksander Morgado)
5f039d4 qmi-firmware-update: add ':' to the section titles (Aleksander Morgado)
703f96d qmicli: remove empty whiteline in --version (Aleksander Morgado)
1822ac0 qmicli: add ':' to the section titles (Aleksander Morgado)
89e1406 qmicli,pdc: add successful messages for activate/deactivate/delete (Aleksander Morgado)
39d876b qmicli,pdc: if device goes away, don't attempt to release CIDs (Aleksander Morgado)
3728863 qmicli,helpers: allow ':' digit in input binary string (Aleksander Morgado)
0e65eb6 qmicli,pdc: success if device removed while activating config (Aleksander Morgado)
37694d2 qmicli,pdc: connect to activate-config indication signal only when needed (Aleksander Morgado)
73619cf qmicli,pdc: no need to select config before deactivating (Aleksander Morgado)
dc9b266 qmicli,pdc: reorder sources (Aleksander Morgado)
8cd6bce qmicli,pdc: use correct input string for --deactivate-config (Aleksander Morgado)
2712401 libqmi-glib,wds: add new 'ipv6' verbose call end reasons (Aleksander Morgado)
ca926b1 libqmi-glib,wds: add new 'ppp' verbose call end reasons (Aleksander Morgado)
7ffa069 libqmi-glib,wds: add new '3gpp' verbose call end reasons (Aleksander Morgado)
60d9fff libqmi-glib,wds: add new 'cm' verbose call end reasons (Aleksander Morgado)
b96ee9a libqmi-glib,wds: rename CM_CONFIGURATION_FAILED to CM_CONFERENCE_FAILED (Aleksander Morgado)
2c2ae6a libqmi-glib,compat: new QmiDeprecatedProtocolError helper (Aleksander Morgado)
ea78050 libqmi-glib,wds: add new 'internal' verbose call end reasons (Aleksander Morgado)
e85dae5 libqmi-glib,test-message: plug memleak (Aleksander Morgado)
d8a40bb libqmi-glib,test: add test for NAS Get Serving System with GSM7 PLMN (Aleksander Morgado)
b5c46e1 libqmi-glib,utils: assume non-printable UTF-8 is not expected (Aleksander Morgado)
aea0894 libqmi-glib,test: reorder sources (Aleksander Morgado)
59ce5fd libqmi-glib,message: fix GSM7 fallback and memleak (Aleksander Morgado)
3701c46 qmi-service-uim: remove duplicate service entries (Eric Caruso)
65a769f qmicli-uim: use argument strings in power on/off input (Eric Caruso)
88bf16b docs: add index for 1.24.6 (Aleksander Morgado)
8e205bf libqmi-glib,nas: 3GPP2 home network TLV rename already in 1.24.6 (Aleksander Morgado)
d43b571 libqmi-glib,nas: helper to decode 3GPP2 network descriptions already in 1.24.6 (Aleksander Morgado)
55556ff libqmi-glib,nas: NITZ information compat method already in 1.24.6 (Aleksander Morgado)
4281543 compat: method for WDA Get Data Format TLV 0x15 already in 1.24.6 (Aleksander Morgado)
e46aad5 libqmi-glib: helper to read strings in GSM7/UCS2 already in 1.24.6 (Aleksander Morgado)
2f0fe6f libqmi-glib,message: UTF-8 validation is already available in 1.24.6 (Aleksander Morgado)

Change-Id: Id2ab20446bec99dd174e401264b379485ab89a07
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0cd2524..b58c3da 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,48 +5,73 @@
 
 before_script:
   - apt update && apt -y install autoconf automake libtool libgudev-1.0-dev autoconf-archive
-  - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
 
-test:
+test-no-mbim-no-qrtr:
   stage: test
   script:
-    - ./autogen.sh --disable-mbim-qmux --disable-qrtr
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --disable-mbim-qmux --disable-qrtr
     - make
     - make check
     - make install
 
-test-qrtr:
+test-no-mbim:
   stage: test
   script:
-    - ./autogen.sh --disable-mbim-qmux --enable-qrtr
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --disable-mbim-qmux --enable-qrtr
     - make
     - make check
     - make install
 
-test-mbim-qmux:
+test-no-qrtr:
   stage: test
   script:
     - git clone --depth 1 https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
     - pushd libmbim
-    - ./autogen.sh
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr
     - make
     - make install
     - popd
-    - ./autogen.sh --enable-mbim-qmux --disable-qrtr
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --enable-mbim-qmux --disable-qrtr
     - make
     - make check
     - make install
 
-test-mbim-qmux-qrtr:
+test-collection-minimal:
   stage: test
   script:
-    - git clone --depth 1 https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
-    - pushd libmbim
-    - ./autogen.sh
-    - make
-    - make install
-    - popd
-    - ./autogen.sh --enable-mbim-qmux --enable-qrtr
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --disable-mbim-qmux --disable-qrtr --disable-firmware-update --enable-collection=minimal
     - make
     - make check
     - make install
+
+test-collection-basic:
+  stage: test
+  script:
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --disable-mbim-qmux --disable-qrtr --enable-collection=basic
+    - make
+    - make check
+    - make install
+
+test-default:
+  stage: test
+  script:
+    - apt -y install gtk-doc-tools libglib2.0-doc
+    - git clone --depth 1 https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
+    - pushd libmbim
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr
+    - make
+    - make install
+    - popd
+    - NOCONFIGURE=1 ./autogen.sh
+    - ./configure --prefix=/usr --enable-gtk-doc --enable-mbim-qmux --enable-qrtr
+    - make
+    - make check
+    - make install
+    - make distcheck
diff --git a/Makefile.am b/Makefile.am
index bde0a2a..0e91bc5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@
 	--with-udev-base-dir="$$dc_install_base" \
 	--enable-gtk-doc \
 	--enable-mbim-qmux \
+	--enable-qrtr \
 	$(NULL)
 
 ChangeLog:
diff --git a/build-aux/qmi-codegen/Client.py b/build-aux/qmi-codegen/Client.py
index 8948d5b..379b9d6 100644
--- a/build-aux/qmi-codegen/Client.py
+++ b/build-aux/qmi-codegen/Client.py
@@ -51,17 +51,21 @@
             raise ValueError('Missing Service field')
 
     """
+    Emits the symbol specifying if the service is supported
+    """
+    def __emit_supported(self, f, supported):
+        translations = { 'service' : self.service.upper() }
+        template = '\n'
+        if supported:
+            template += '#define HAVE_QMI_SERVICE_${service}\n'
+        else:
+            template += '/* HAVE_QMI_SERVICE_${service} */\n'
+        f.write(string.Template(template).substitute(translations))
+
+    """
     Emits the generic GObject class implementation
     """
     def __emit_class(self, hfile, cfile, message_list):
-
-        # Check if we'll have indications
-        has_indications = False
-        for message in message_list.list:
-            if message.type == 'Indication':
-                has_indications = True
-                break
-
         translations = { 'underscore'                 : utils.build_underscore_name(self.name),
                          'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(),
                          'camelcase'                  : utils.build_camelcase_name(self.name),
@@ -121,16 +125,15 @@
         template += (
             'G_DEFINE_TYPE (${camelcase}, ${underscore}, QMI_TYPE_CLIENT)\n')
 
-        if has_indications:
+        if len(message_list.indication_list) > 0:
             template += (
                 '\n'
                 'enum {\n')
-            for message in message_list.list:
-                if message.type == 'Indication':
-                    translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
-                    inner_template = (
-                        '    SIGNAL_${signal_id},\n')
-                    template += string.Template(inner_template).substitute(translations)
+            for message in message_list.indication_list:
+                translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
+                inner_template = (
+                    '    SIGNAL_${signal_id},\n')
+                template += string.Template(inner_template).substitute(translations)
             template += (
                 '    SIGNAL_LAST\n'
                 '};\n'
@@ -145,45 +148,44 @@
             '{\n'
             '    switch (qmi_message_get_message_id (message)) {\n')
 
-        for message in message_list.list:
-            if message.type == 'Indication':
-                translations['enum_name'] = message.id_enum_name
-                translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname)
-                translations['message_name'] = message.name
-                translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
-                inner_template = ''
-                if message.output is not None and message.output.fields is not None:
-                    # At least one field in the indication
-                    translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
-                    translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
-                    translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
-                    inner_template += (
-                        '        case ${enum_name}: {\n'
-                        '            ${output_camelcase} *output;\n'
-                        '            GError *error = NULL;\n'
-                        '\n'
-                        '            /* Parse indication */\n'
-                        '            output = __${message_fullname_underscore}_indication_parse (message, &error);\n'
-                        '            if (!output) {\n'
-                        '                g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n'
-                        '                           error ? error->message : "Unknown error");\n'
-                        '                if (error)\n'
-                        '                    g_error_free (error);\n'
-                        '            } else {\n'
-                        '                g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n'
-                        '                ${output_underscore}_unref (output);\n'
-                        '            }\n'
-                        '            break;\n'
-                        '        }\n')
-                else:
-                    # No output field in the indication
-                    inner_template += (
-                        '        case ${enum_name}: {\n'
-                        '            g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n'
-                        '            break;\n'
-                        '        }\n')
+        for message in message_list.indication_list:
+            translations['enum_name'] = message.id_enum_name
+            translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname)
+            translations['message_name'] = message.name
+            translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
+            inner_template = ''
+            if message.output is not None and message.output.fields is not None:
+                # At least one field in the indication
+                translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
+                translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
+                translations['output_underscore'] = utils.build_underscore_name(message.output.fullname)
+                inner_template += (
+                    '        case ${enum_name}: {\n'
+                    '            ${output_camelcase} *output;\n'
+                    '            GError *error = NULL;\n'
+                    '\n'
+                    '            /* Parse indication */\n'
+                    '            output = __${message_fullname_underscore}_indication_parse (message, &error);\n'
+                    '            if (!output) {\n'
+                    '                g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n'
+                    '                           error ? error->message : "Unknown error");\n'
+                    '                if (error)\n'
+                    '                    g_error_free (error);\n'
+                    '            } else {\n'
+                    '                g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n'
+                    '                ${output_underscore}_unref (output);\n'
+                    '            }\n'
+                    '            break;\n'
+                    '        }\n')
+            else:
+                # No output field in the indication
+                inner_template += (
+                    '        case ${enum_name}: {\n'
+                    '            g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n'
+                    '            break;\n'
+                    '        }\n')
 
-                template += string.Template(inner_template).substitute(translations)
+            template += string.Template(inner_template).substitute(translations)
 
         template += (
             '        default:\n'
@@ -203,64 +205,63 @@
             '\n'
             '    client_class->process_indication = process_indication;\n')
 
-        for message in message_list.list:
-            if message.type == 'Indication':
-                translations['signal_name'] = utils.build_dashed_name(message.name)
-                translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
-                translations['message_name'] = message.name
-                translations['since'] = message.since
-                inner_template = ''
-                if message.output is not None and message.output.fields is not None:
-                    # At least one field in the indication
-                    translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
-                    translations['bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(message.output.fullname), 'QMI_')
-                    translations['service'] = self.service.upper()
-                    translations['message_name_dashed'] = message.name.replace(' ', '-')
-                    inner_template += (
-                        '\n'
-                        '    /**\n'
-                        '     * ${camelcase}::${signal_name}:\n'
-                        '     * @object: A #${camelcase}.\n'
-                        '     * @output: A #${output_camelcase}.\n'
-                        '     *\n'
-                        '     * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}-indication.top_of_page\">${message_name}</link>\' indication is received.\n'
-                        '     *\n'
-                        '     * Since: ${since}\n'
-                        '     */\n'
-                        '    signals[SIGNAL_${signal_id}] =\n'
-                        '        g_signal_new ("${signal_name}",\n'
-                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
-                        '                      G_SIGNAL_RUN_LAST,\n'
-                        '                      0,\n'
-                        '                      NULL,\n'
-                        '                      NULL,\n'
-                        '                      NULL,\n'
-                        '                      G_TYPE_NONE,\n'
-                        '                      1,\n'
-                        '                      ${bundle_type});\n')
-                else:
-                    # No output field in the indication
-                    inner_template += (
-                        '\n'
-                        '    /**\n'
-                        '     * ${camelcase}::${signal_name}:\n'
-                        '     * @object: A #${camelcase}.\n'
-                        '     *\n'
-                        '     * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n'
-                        '     *\n'
-                        '     * Since: ${since}\n'
-                        '     */\n'
-                        '    signals[SIGNAL_${signal_id}] =\n'
-                        '        g_signal_new ("${signal_name}",\n'
-                        '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
-                        '                      G_SIGNAL_RUN_LAST,\n'
-                        '                      0,\n'
-                        '                      NULL,\n'
-                        '                      NULL,\n'
-                        '                      NULL,\n'
-                        '                      G_TYPE_NONE,\n'
-                        '                      0);\n')
-                template += string.Template(inner_template).substitute(translations)
+        for message in message_list.indication_list:
+            translations['signal_name'] = utils.build_dashed_name(message.name)
+            translations['signal_id'] = utils.build_underscore_uppercase_name(message.name)
+            translations['message_name'] = message.name
+            translations['since'] = message.since
+            inner_template = ''
+            if message.output is not None and message.output.fields is not None:
+                # At least one field in the indication
+                translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname)
+                translations['bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(message.output.fullname), 'QMI_')
+                translations['service'] = self.service.upper()
+                translations['message_name_dashed'] = message.name.replace(' ', '-')
+                inner_template += (
+                    '\n'
+                    '    /**\n'
+                    '     * ${camelcase}::${signal_name}:\n'
+                    '     * @object: A #${camelcase}.\n'
+                    '     * @output: A #${output_camelcase}.\n'
+                    '     *\n'
+                    '     * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}-indication.top_of_page\">${message_name}</link>\' indication is received.\n'
+                    '     *\n'
+                    '     * Since: ${since}\n'
+                    '     */\n'
+                    '    signals[SIGNAL_${signal_id}] =\n'
+                    '        g_signal_new ("${signal_name}",\n'
+                    '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
+                    '                      G_SIGNAL_RUN_LAST,\n'
+                    '                      0,\n'
+                    '                      NULL,\n'
+                    '                      NULL,\n'
+                    '                      NULL,\n'
+                    '                      G_TYPE_NONE,\n'
+                    '                      1,\n'
+                    '                      ${bundle_type});\n')
+            else:
+                # No output field in the indication
+                inner_template += (
+                    '\n'
+                    '    /**\n'
+                    '     * ${camelcase}::${signal_name}:\n'
+                    '     * @object: A #${camelcase}.\n'
+                    '     *\n'
+                    '     * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n'
+                    '     *\n'
+                    '     * Since: ${since}\n'
+                    '     */\n'
+                    '    signals[SIGNAL_${signal_id}] =\n'
+                    '        g_signal_new ("${signal_name}",\n'
+                    '                      G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n'
+                    '                      G_SIGNAL_RUN_LAST,\n'
+                    '                      0,\n'
+                    '                      NULL,\n'
+                    '                      NULL,\n'
+                    '                      NULL,\n'
+                    '                      G_TYPE_NONE,\n'
+                    '                      0);\n')
+            template += string.Template(inner_template).substitute(translations)
 
         template += (
             '}\n'
@@ -278,11 +279,7 @@
                          'service_uppercase' : self.service.upper(),
                          'service_camelcase' : string.capwords(self.service) }
 
-        for message in message_list.list:
-
-            if message.type == 'Indication':
-                continue
-
+        for message in message_list.request_list:
             if message.static:
                 continue
 
@@ -375,6 +372,8 @@
             if message.abort:
                 template += (
                     '\n'
+                    '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n'
+                    '\n'
                     'static QmiMessage *\n'
                     '__${message_fullname_underscore}_abortable_build_request (\n'
                     '    QmiDevice   *self,\n'
@@ -415,7 +414,10 @@
                     '               abort_response,\n'
                     '               error);\n'
                     '    return !!output;\n'
-                    '}\n')
+                    '}\n'
+                    '\n'
+                    '#endif /* HAVE_QMI_MESSAGE_${service_uppercase}_ABORT */\n'
+                    '\n')
 
             template += (
                 '\n'
@@ -530,10 +532,17 @@
 
             if message.abort:
                 template += (
+                    '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n'
                     '                             (QmiDeviceCommandAbortableBuildRequestFn)  __${message_fullname_underscore}_abortable_build_request,\n'
                     '                             (QmiDeviceCommandAbortableParseResponseFn) __${message_fullname_underscore}_abortable_parse_response,\n'
                     '                             g_object_ref (self),\n'
-                    '                             g_object_unref,\n')
+                    '                             g_object_unref,\n'
+                    '#else\n'
+                    '                             NULL,\n'
+                    '                             NULL,\n'
+                    '                             NULL,\n'
+                    '                             NULL,\n'
+                    '#endif\n')
 
             template += (
                 '                             cancellable,\n'
@@ -550,6 +559,13 @@
     Emit the service-specific client implementation
     """
     def emit(self, hfile, cfile, message_list):
+        # Do nothing if no supported messages
+        if len(message_list.indication_list) == 0 and len(message_list.request_list) == 0:
+            self.__emit_supported(hfile, False)
+            return
+
+        self.__emit_supported(hfile, True)
+
         # First, emit common class code
         utils.add_separator(hfile, 'CLIENT', self.name);
         utils.add_separator(cfile, 'CLIENT', self.name);
@@ -560,7 +576,11 @@
     """
     Emit the sections
     """
-    def emit_sections(self, sfile):
+    def emit_sections(self, sfile, message_list):
+        # Do nothing if no supported messages
+        if len(message_list.indication_list) == 0 and len(message_list.request_list) == 0:
+            return
+
         translations = { 'underscore'                 : utils.build_underscore_name(self.name),
                          'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(),
                          'camelcase'                  : utils.build_camelcase_name (self.name),
diff --git a/build-aux/qmi-codegen/Message.py b/build-aux/qmi-codegen/Message.py
index 792bf9b..e4c93ce 100644
--- a/build-aux/qmi-codegen/Message.py
+++ b/build-aux/qmi-codegen/Message.py
@@ -68,6 +68,9 @@
         # Create the ID enumeration name
         self.id_enum_name = utils.build_underscore_name(self.fullname).upper()
 
+        # Create the build symbol name
+        self.build_symbol = 'HAVE_' + self.id_enum_name
+
         # Build output container.
         # Every defined message will have its own output container, which
         # will generate a new Output type and public getters for each output
@@ -419,6 +422,7 @@
                          'camelcase'           : utils.build_camelcase_name (self.fullname),
                          'service'             : utils.build_underscore_name (self.service),
                          'name_underscore'     : utils.build_underscore_name (self.name),
+                         'build_symbol'        : self.build_symbol,
                          'fullname'            : self.service + ' ' + self.name,
                          'type'                : 'response' if self.type == 'Message' else 'indication' }
 
@@ -453,6 +457,7 @@
             '${public_types}'
             '${public_methods}'
             '<SUBSECTION Private>\n'
+            '${build_symbol}\n'
             '${private}'
             '<SUBSECTION Standard>\n'
             '${standard}'
diff --git a/build-aux/qmi-codegen/MessageList.py b/build-aux/qmi-codegen/MessageList.py
index 632b288..81f480b 100644
--- a/build-aux/qmi-codegen/MessageList.py
+++ b/build-aux/qmi-codegen/MessageList.py
@@ -32,8 +32,10 @@
     """
     Constructor
     """
-    def __init__(self, objects_dictionary, common_objects_dictionary):
-        self.list = []
+    def __init__(self, collection, objects_dictionary, common_objects_dictionary):
+        self.request_list = []
+        self.indication_list = []
+        self.unsupported_list = []
         self.message_id_enum_name = None
         self.indication_id_enum_name = None
         self.service = None
@@ -44,7 +46,13 @@
             if object_dictionary['type'] == 'Message' or \
                object_dictionary['type'] == 'Indication':
                 message = Message(object_dictionary, common_objects_dictionary)
-                self.list.append(message)
+                if collection is None or message.id_enum_name in collection:
+                    if message.type == 'Message':
+                        self.request_list.append(message)
+                    else:
+                        self.indication_list.append(message)
+                else:
+                    self.unsupported_list.append(message)
             elif object_dictionary['type'] == 'Message-ID-Enum':
                 self.message_id_enum_name = object_dictionary['name']
             elif object_dictionary['type'] == 'Indication-ID-Enum':
@@ -61,26 +69,48 @@
             raise ValueError('Missing Service field')
 
 
+    def __emit_message_build_symbols(self, f):
+        template = ''
+        for message in self.request_list:
+            translations = { 'build_symbol' : message.build_symbol }
+            message_template = '#define ${build_symbol}\n'
+            template += string.Template(message_template).substitute(translations)
+        for message in self.indication_list:
+            translations = { 'build_symbol' : message.build_symbol }
+            message_template = '#define ${build_symbol}\n'
+            template += string.Template(message_template).substitute(translations)
+        if len(self.unsupported_list) > 0:
+            template += (
+                '\n'
+                '/* messages unsupported in collection */\n')
+            for message in self.unsupported_list:
+                translations = { 'build_symbol' : message.build_symbol }
+                message_template = '/* ${build_symbol} */\n'
+                template += string.Template(message_template).substitute(translations)
+        f.write(string.Template(template).substitute(translations))
+
     """
     Emit the enumeration of the messages found in the specific service
     """
-    def emit_message_ids_enum(self, f):
+    def __emit_message_ids_enum(self, f):
+        # do nothing if nothing in the supported messages list
+        if len(self.request_list) == 0:
+            return
         translations = { 'enum_type' : utils.build_camelcase_name (self.message_id_enum_name) }
         template = (
             '\n'
             'typedef enum {\n')
-        for message in self.list:
-            if message.type == 'Message':
-                translations['enum_name'] = message.id_enum_name
-                translations['enum_value'] = message.id
-                if message.vendor is None:
-                    enum_template = (
-                        '    ${enum_name} = ${enum_value},\n')
-                else:
-                    translations['vendor'] = message.vendor
-                    enum_template = (
-                        '    ${enum_name} = ${enum_value}, /* vendor ${vendor} */\n')
-                template += string.Template(enum_template).substitute(translations)
+        for message in self.request_list:
+            translations['enum_name'] = message.id_enum_name
+            translations['enum_value'] = message.id
+            if message.vendor is None:
+                enum_template = (
+                    '    ${enum_name} = ${enum_value},\n')
+            else:
+                translations['vendor'] = message.vendor
+                enum_template = (
+                    '    ${enum_name} = ${enum_value}, /* vendor ${vendor} */\n')
+            template += string.Template(enum_template).substitute(translations)
 
         template += (
             '} ${enum_type};\n'
@@ -90,18 +120,20 @@
     """
     Emit the enumeration of the indications found in the specific service
     """
-    def emit_indication_ids_enum(self, f):
+    def __emit_indication_ids_enum(self, f):
+        # do nothing if nothing in the supported indications list
+        if len(self.indication_list) == 0:
+            return
         translations = { 'enum_type' : utils.build_camelcase_name (self.indication_id_enum_name) }
         template = (
             '\n'
             'typedef enum {\n')
-        for message in self.list:
-            if message.type == 'Indication':
-                translations['enum_name'] = message.id_enum_name
-                translations['enum_value'] = message.id
-                enum_template = (
-                    '    ${enum_name} = ${enum_value},\n')
-                template += string.Template(enum_template).substitute(translations)
+        for message in self.indication_list:
+            translations['enum_name'] = message.id_enum_name
+            translations['enum_value'] = message.id
+            enum_template = (
+                '    ${enum_name} = ${enum_value},\n')
+            template += string.Template(enum_template).substitute(translations)
 
         template += (
             '} ${enum_type};\n'
@@ -141,14 +173,13 @@
             '    if (qmi_message_is_indication (self)) {\n'
             '        switch (qmi_message_get_message_id (self)) {\n')
 
-        for message in self.list:
-            if message.type == 'Indication':
-                translations['enum_name'] = message.id_enum_name
-                translations['message_underscore'] = utils.build_underscore_name (message.name)
-                inner_template = (
-                    '        case ${enum_name}:\n'
-                    '            return indication_${message_underscore}_get_printable (self, line_prefix);\n')
-                template += string.Template(inner_template).substitute(translations)
+        for message in self.indication_list:
+            translations['enum_name'] = message.id_enum_name
+            translations['message_underscore'] = utils.build_underscore_name (message.name)
+            inner_template = (
+                '        case ${enum_name}:\n'
+                '            return indication_${message_underscore}_get_printable (self, line_prefix);\n')
+            template += string.Template(inner_template).substitute(translations)
 
         template += (
             '        default:\n'
@@ -161,8 +192,8 @@
             '        if (vendor_id == QMI_MESSAGE_VENDOR_GENERIC) {\n'
             '            switch (qmi_message_get_message_id (self)) {\n')
 
-        for message in self.list:
-            if message.type == 'Message' and message.vendor is None:
+        for message in self.request_list:
+            if message.vendor is None:
                 translations['enum_name'] = message.id_enum_name
                 translations['message_underscore'] = utils.build_underscore_name (message.name)
                 inner_template = (
@@ -176,8 +207,8 @@
             '            }\n'
             '        } else {\n')
 
-        for message in self.list:
-            if message.type == 'Message' and message.vendor is not None:
+        for message in self.request_list:
+            if message.vendor is not None:
                 translations['enum_name'] = message.id_enum_name
                 translations['message_underscore'] = utils.build_underscore_name (message.name)
                 translations['message_vendor'] = message.vendor
@@ -198,10 +229,9 @@
     Emit the method responsible for checking whether a given message is abortable
     """
     def __emit_is_abortable(self, hfile, cfile):
-
         # do nothing if no abortable messages in service
-        for message in self.list:
-            if message.type == 'Message' and message.abort:
+        for message in self.request_list:
+            if message.abort:
                 break
         else:
             return
@@ -234,15 +264,13 @@
             '    if (vendor_id == QMI_MESSAGE_VENDOR_GENERIC) {\n'
             '        switch (qmi_message_get_message_id (self)) {\n')
 
-        for message in self.list:
-            if message.type == 'Message' and message.vendor is None:
-                # Only add if it's abortable
-                if message.abort:
-                    translations['enum_name'] = message.id_enum_name
-                    inner_template = (
-                        '        case ${enum_name}:\n'
-                        '            return TRUE;\n')
-                    template += string.Template(inner_template).substitute(translations)
+        for message in self.request_list:
+            if message.vendor is None and message.abort:
+                translations['enum_name'] = message.id_enum_name
+                inner_template = (
+                    '        case ${enum_name}:\n'
+                    '            return TRUE;\n')
+                template += string.Template(inner_template).substitute(translations)
 
         template += (
             '        default:\n'
@@ -250,17 +278,15 @@
             '        }\n'
             '    } else {\n')
 
-        for message in self.list:
-            if message.type == 'Message' and message.vendor is not None:
-                # Only add if it's abortable
-                if message.abort:
-                    translations['enum_name'] = message.id_enum_name
-                    translations['message_vendor'] = message.vendor
-                    inner_template = (
-                        '        if (vendor_id == ${message_vendor} && (qmi_message_get_message_id (self) == ${enum_name})) {\n'
-                        '            return TRUE;\n'
-                        '        }\n')
-                    template += string.Template(inner_template).substitute(translations)
+        for message in self.request_list:
+            if message.vendor is not None and message.abort:
+                translations['enum_name'] = message.id_enum_name
+                translations['message_vendor'] = message.vendor
+                inner_template = (
+                    '        if (vendor_id == ${message_vendor} && (qmi_message_get_message_id (self) == ${enum_name})) {\n'
+                    '            return TRUE;\n'
+                    '        }\n')
+                template += string.Template(inner_template).substitute(translations)
 
         template += (
             '        return FALSE;\n'
@@ -273,13 +299,22 @@
     Emit the message list handling implementation
     """
     def emit(self, hfile, cfile):
-        # First, emit the message/indication IDs enum
-        self.emit_message_ids_enum(cfile)
+        # Always write build symbols, even for unsupported messages
+        self.__emit_message_build_symbols(hfile)
+
+        # Do nothing else if nothing in the supported lists
+        if len(self.indication_list) == 0 and len(self.request_list) == 0:
+            return
+
+        # Emit the message/indication IDs enum and the build symbols
+        self.__emit_message_ids_enum(cfile)
         if self.indication_id_enum_name is not None:
-            self.emit_indication_ids_enum(cfile)
+            self.__emit_indication_ids_enum(cfile)
 
         # Then, emit all message handlers
-        for message in self.list:
+        for message in self.indication_list:
+            message.emit(hfile, cfile)
+        for message in self.request_list:
             message.emit(hfile, cfile)
 
         # First, emit common class code
@@ -292,6 +327,11 @@
     Emit the sections
     """
     def emit_sections(self, sfile):
+        # do nothing if nothing in the supported lists
+        if len(self.indication_list) == 0 and len(self.request_list) == 0:
+            return
         # Emit all message sections
-        for message in self.list:
+        for message in self.indication_list:
+            message.emit_sections(sfile)
+        for message in self.request_list:
             message.emit_sections(sfile)
diff --git a/build-aux/qmi-codegen/qmi-codegen b/build-aux/qmi-codegen/qmi-codegen
index 91c7db8..8de61e2 100755
--- a/build-aux/qmi-codegen/qmi-codegen
+++ b/build-aux/qmi-codegen/qmi-codegen
@@ -37,6 +37,8 @@
                           help='Generate C code in OUTFILES.[ch]')
     arg_parser.add_option('', '--include', metavar='JSONFILE', action='append',
                           help='Additional common types in a JSON-formatted database')
+    arg_parser.add_option('', '--collection', metavar='[JSONFILE]',
+                          help='Collection of messages to be included in the build')
     (opts, args) = arg_parser.parse_args();
 
     if opts.input == None:
@@ -51,6 +53,12 @@
     output_file_h = open(opts.output + ".h", 'w')
     output_file_sections = open(opts.output + ".sections", 'w')
 
+    # If a collection given, load it
+    collection_list_json = None
+    if opts.collection != None:
+        collection_contents = utils.read_json_file(opts.collection)
+        collection_list_json = json.loads(collection_contents)
+
     # Load all common types
     common_object_list_json = []
     opts.include.append(opts.input)
@@ -66,7 +74,7 @@
 
     # Build message list
     object_list_json = json.loads(database_file_contents)
-    message_list = MessageList(object_list_json, common_object_list_json)
+    message_list = MessageList(collection_list_json, object_list_json, common_object_list_json)
 
     # Add common stuff to the output files
     utils.add_copyright(output_file_c);
@@ -82,7 +90,7 @@
     client.emit(output_file_h, output_file_c, message_list)
 
     # Emit sections
-    client.emit_sections(output_file_sections)
+    client.emit_sections(output_file_sections, message_list)
     message_list.emit_sections(output_file_sections)
 
     utils.add_header_stop(output_file_h, os.path.basename(opts.output))
diff --git a/configure.ac b/configure.ac
index 79c67b2..c34310f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 dnl The QMI version number
 m4_define([qmi_major_version], [1])
 m4_define([qmi_minor_version], [25])
-m4_define([qmi_micro_version], [3])
+m4_define([qmi_micro_version], [5])
 m4_define([qmi_version],
           [qmi_major_version.qmi_minor_version.qmi_micro_version])
 
@@ -109,12 +109,30 @@
 
 AM_PATH_PYTHON([], [], [PYTHON=python])
 
+dnl message collection (existing file in data/qmi-collection-${COLLECTION}.json)
+dnl custom collections may be added as files in data/
+AC_ARG_ENABLE(collection,
+              AS_HELP_STRING([--enable-collection=[minimal|basic|full]],
+                             [message collection to build [default=full]]),
+              [enable_collection=$enableval],
+              [enable_collection=full])
+QMI_COLLECTION_NAME="$enable_collection"
+AC_SUBST(QMI_COLLECTION_NAME)
+AM_CONDITIONAL([QMI_COLLECTION_USED], test "$enable_collection" != "full")
+
 dnl qmi-firmware-update is optional, enabled by default
 AC_ARG_ENABLE([firmware-update],
               AS_HELP_STRING([--enable-firmware-update],
                              [enable compilation of `qmi-firmware-update' [default=yes]]),
               [build_firmware_update=$enableval],
               [build_firmware_update=yes])
+
+if test "x$build_firmware_update" = "xyes"; then
+    if test "$QMI_COLLECTION_NAME" = "minimal"; then
+        AC_MSG_WARN([Cannot build qmi-firmware-update when 'minimal' collection enabled, use at least the 'basic' collection instead.])
+        build_firmware_update=no
+    fi
+fi
 AM_CONDITIONAL([BUILD_FIRMWARE_UPDATE], [test "x$build_firmware_update" = "xyes"])
 
 dnl udev support is optional, enabled by default
@@ -156,6 +174,13 @@
 
 dnl Documentation
 GTK_DOC_CHECK(1.0)
+if test "x$enable_gtk_doc" = "xyes"; then
+    if test "x$QMI_COLLECTION_NAME" != "xfull"; then
+        AC_MSG_WARN([Cannot build gtk-doc when using an explicit message collection.])
+        enable_gtk_doc=no
+    fi
+fi
+AM_CONDITIONAL([ENABLE_GTK_DOC], [test "x$enable_gtk_doc" = "xyes"])
 
 # QMI username
 QMI_USERNAME="root"
@@ -289,7 +314,7 @@
 
     Built items:
       libqrtr-glib:        ${enable_qrtr}
-      libqmi-glib:         yes
+      libqmi-glib:         yes (${QMI_COLLECTION_NAME})
       qmicli:              yes
       qmi-firmware-update: ${build_firmware_update}
           with udev:             ${with_udev}
diff --git a/data/Makefile.am b/data/Makefile.am
index d62047d..2f33d04 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -18,4 +18,6 @@
 	qmi-service-qos.json \
 	qmi-service-gas.json \
 	qmi-service-dsd.json \
+	qmi-collection-minimal.json \
+	qmi-collection-basic.json \
 	$(NULL)
diff --git a/data/qmi-collection-basic.json b/data/qmi-collection-basic.json
new file mode 100644
index 0000000..56401f8
--- /dev/null
+++ b/data/qmi-collection-basic.json
@@ -0,0 +1,146 @@
+
+// Basic set of QMI messages required to use libqmi alongside
+// the ModemManager daemon, and also including support for the
+// qmi-firmware-update program
+
+[
+    "QMI_MESSAGE_DMS_SET_EVENT_REPORT",
+    "QMI_INDICATION_DMS_EVENT_REPORT",
+    "QMI_MESSAGE_DMS_GET_CAPABILITIES",
+    "QMI_MESSAGE_DMS_GET_MANUFACTURER",
+    "QMI_MESSAGE_DMS_GET_MODEL",
+    "QMI_MESSAGE_DMS_GET_REVISION",
+    "QMI_MESSAGE_DMS_GET_HARDWARE_REVISION",
+    "QMI_MESSAGE_DMS_GET_IDS",
+    "QMI_MESSAGE_DMS_GET_MSISDN",
+    "QMI_MESSAGE_DMS_UIM_VERIFY_PIN",
+    "QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN",
+    "QMI_MESSAGE_DMS_UIM_CHANGE_PIN",
+    "QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS",
+    "QMI_MESSAGE_DMS_UIM_GET_IMSI",
+    "QMI_MESSAGE_DMS_UIM_GET_ICCID",
+    "QMI_MESSAGE_DMS_UIM_SET_PIN_PROTECTION",
+    "QMI_MESSAGE_DMS_UIM_GET_CK_STATUS",
+    "QMI_MESSAGE_DMS_GET_ACTIVATION_STATE",
+    "QMI_MESSAGE_DMS_ACTIVATE_AUTOMATIC",
+    "QMI_MESSAGE_DMS_ACTIVATE_MANUAL",
+    "QMI_MESSAGE_DMS_GET_OPERATING_MODE",
+    "QMI_MESSAGE_DMS_SET_OPERATING_MODE",
+    "QMI_MESSAGE_DMS_GET_BAND_CAPABILITIES",
+    "QMI_MESSAGE_DMS_RESTORE_FACTORY_DEFAULTS",
+    "QMI_MESSAGE_DMS_SET_FIRMWARE_ID",
+    "QMI_MESSAGE_DMS_GET_FIRMWARE_PREFERENCE",
+    "QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE",
+    "QMI_MESSAGE_DMS_LIST_STORED_IMAGES",
+    "QMI_MESSAGE_DMS_GET_STORED_IMAGE_INFO",
+    "QMI_MESSAGE_DMS_SET_BOOT_IMAGE_DOWNLOAD_MODE",
+    "QMI_MESSAGE_DMS_SWI_GET_CURRENT_FIRMWARE",
+    "QMI_MESSAGE_DMS_SET_FCC_AUTHENTICATION",
+
+    "QMI_MESSAGE_NAS_ABORT",
+    "QMI_MESSAGE_NAS_SET_EVENT_REPORT",
+    "QMI_INDICATION_NAS_EVENT_REPORT",
+    "QMI_MESSAGE_NAS_GET_SERVING_SYSTEM",
+    "QMI_INDICATION_NAS_SERVING_SYSTEM",
+    "QMI_MESSAGE_NAS_GET_HOME_NETWORK",
+    "QMI_MESSAGE_NAS_INITIATE_NETWORK_REGISTER",
+    "QMI_MESSAGE_NAS_NETWORK_SCAN",
+    "QMI_MESSAGE_NAS_REGISTER_INDICATIONS",
+    "QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH",
+    "QMI_MESSAGE_NAS_GET_SIGNAL_INFO",
+    "QMI_MESSAGE_NAS_GET_SYSTEM_INFO",
+    "QMI_MESSAGE_NAS_GET_TECHNOLOGY_PREFERENCE",
+    "QMI_MESSAGE_NAS_SET_TECHNOLOGY_PREFERENCE",
+    "QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE",
+    "QMI_MESSAGE_NAS_SET_SYSTEM_SELECTION_PREFERENCE",
+    "QMI_MESSAGE_NAS_GET_RF_BAND_INFORMATION",
+
+    "QMI_MESSAGE_UIM_VERIFY_PIN",
+    "QMI_MESSAGE_UIM_UNBLOCK_PIN",
+    "QMI_MESSAGE_UIM_CHANGE_PIN",
+    "QMI_MESSAGE_UIM_SET_PIN_PROTECTION",
+    "QMI_MESSAGE_UIM_GET_CARD_STATUS",
+    "QMI_MESSAGE_UIM_READ_TRANSPARENT",
+
+    "QMI_MESSAGE_WDS_ABORT",
+    "QMI_MESSAGE_WDS_SET_EVENT_REPORT",
+    "QMI_INDICATION_WDS_EVENT_REPORT",
+    "QMI_MESSAGE_WDS_START_NETWORK",
+    "QMI_MESSAGE_WDS_STOP_NETWORK",
+    "QMI_MESSAGE_WDS_SET_IP_FAMILY",
+    "QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS",
+    "QMI_INDICATION_WDS_PACKET_SERVICE_STATUS",
+    "QMI_MESSAGE_WDS_GET_PACKET_STATISTICS",
+    "QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS",
+    "QMI_MESSAGE_WDS_GET_AUTOCONNECT_SETTINGS",
+    "QMI_MESSAGE_WDS_SET_AUTOCONNECT_SETTINGS",
+
+    "QMI_MESSAGE_WDA_GET_DATA_FORMAT",
+    "QMI_MESSAGE_WDA_SET_DATA_FORMAT",
+
+    "QMI_MESSAGE_PDC_ACTIVATE_CONFIG",
+    "QMI_INDICATION_PDC_ACTIVATE_CONFIG",
+    "QMI_MESSAGE_PDC_SET_SELECTED_CONFIG",
+    "QMI_INDICATION_PDC_SET_SELECTED_CONFIG",
+    "QMI_MESSAGE_PDC_LIST_CONFIGS",
+    "QMI_INDICATION_PDC_LIST_CONFIGS",
+    "QMI_MESSAGE_PDC_GET_SELECTED_CONFIG",
+    "QMI_INDICATION_PDC_GET_SELECTED_CONFIG",
+    "QMI_MESSAGE_PDC_SET_SELECTED_CONFIG",
+    "QMI_INDICATION_PDC_SET_SELECTED_CONFIG",
+    "QMI_MESSAGE_PDC_GET_CONFIG_INFO",
+    "QMI_INDICATION_PDC_GET_CONFIG_INFO",
+
+    "QMI_MESSAGE_PDS_SET_EVENT_REPORT",
+    "QMI_INDICATION_PDS_EVENT_REPORT",
+    "QMI_MESSAGE_PDS_GET_AGPS_CONFIG",
+    "QMI_MESSAGE_PDS_SET_AGPS_CONFIG",
+    "QMI_MESSAGE_PDS_GET_GPS_SERVICE_STATE",
+    "QMI_MESSAGE_PDS_SET_GPS_SERVICE_STATE",
+    "QMI_MESSAGE_PDS_SET_AUTO_TRACKING_STATE",
+    "QMI_MESSAGE_PDS_GET_DEFAULT_TRACKING_SESSION",
+    "QMI_MESSAGE_PDS_SET_DEFAULT_TRACKING_SESSION",
+
+    "QMI_MESSAGE_LOC_START",
+    "QMI_MESSAGE_LOC_STOP",
+    "QMI_MESSAGE_LOC_REGISTER_EVENTS",
+    "QMI_INDICATION_LOC_NMEA",
+    "QMI_MESSAGE_LOC_GET_SERVER",
+    "QMI_INDICATION_LOC_GET_SERVER",
+    "QMI_MESSAGE_LOC_SET_SERVER",
+    "QMI_INDICATION_LOC_SET_SERVER",
+    "QMI_MESSAGE_LOC_SET_OPERATION_MODE",
+    "QMI_INDICATION_LOC_SET_OPERATION_MODE",
+    "QMI_MESSAGE_LOC_GET_OPERATION_MODE",
+    "QMI_INDICATION_LOC_GET_OPERATION_MODE",
+    "QMI_MESSAGE_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE",
+    "QMI_INDICATION_LOC_GET_PREDICTED_ORBITS_DATA_SOURCE",
+    "QMI_MESSAGE_LOC_INJECT_XTRA_DATA",
+    "QMI_INDICATION_LOC_INJECT_XTRA_DATA",
+    "QMI_MESSAGE_LOC_INJECT_PREDICTED_ORBITS_DATA",
+    "QMI_INDICATION_LOC_INJECT_PREDICTED_ORBITS_DATA",
+
+    "QMI_MESSAGE_WMS_SET_EVENT_REPORT",
+    "QMI_INDICATION_WMS_EVENT_REPORT",
+    "QMI_MESSAGE_WMS_RAW_WRITE",
+    "QMI_MESSAGE_WMS_RAW_SEND",
+    "QMI_MESSAGE_WMS_RAW_READ",
+    "QMI_MESSAGE_WMS_LIST_MESSAGES",
+    "QMI_MESSAGE_WMS_SEND_FROM_MEMORY_STORAGE",
+    "QMI_MESSAGE_WMS_SET_ROUTES",
+    "QMI_MESSAGE_WMS_DELETE",
+
+    "QMI_MESSAGE_OMA_SET_EVENT_REPORT",
+    "QMI_INDICATION_OMA_EVENT_REPORT",
+    "QMI_MESSAGE_OMA_GET_FEATURE_SETTING",
+    "QMI_MESSAGE_OMA_SET_FEATURE_SETTING",
+    "QMI_MESSAGE_OMA_START_SESSION",
+    "QMI_MESSAGE_OMA_CANCEL_SESSION",
+    "QMI_MESSAGE_OMA_SEND_SELECTION",
+
+    "QMI_MESSAGE_VOICE_INDICATION_REGISTER",
+    "QMI_MESSAGE_VOICE_ORIGINATE_USSD",
+    "QMI_MESSAGE_VOICE_ANSWER_USSD",
+    "QMI_MESSAGE_VOICE_CANCEL_USSD",
+    "QMI_INDICATION_VOICE_USSD"
+]
diff --git a/data/qmi-collection-minimal.json b/data/qmi-collection-minimal.json
new file mode 100644
index 0000000..8884208
--- /dev/null
+++ b/data/qmi-collection-minimal.json
@@ -0,0 +1,41 @@
+
+// Minimal set of QMI messages required to setup a basic connection
+// and do basic monitoring of the status. The qmi-network program
+// will work successfully with this message set, unlike the
+// qmi-firmware-update program, which cannot even be built.
+
+[
+    "QMI_MESSAGE_DMS_GET_CAPABILITIES",
+    "QMI_MESSAGE_DMS_GET_MANUFACTURER",
+    "QMI_MESSAGE_DMS_GET_MODEL",
+    "QMI_MESSAGE_DMS_GET_IDS",
+    "QMI_MESSAGE_DMS_UIM_VERIFY_PIN",
+    "QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN",
+    "QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS",
+    "QMI_MESSAGE_DMS_UIM_GET_IMSI",
+    "QMI_MESSAGE_DMS_GET_OPERATING_MODE",
+    "QMI_MESSAGE_DMS_SET_OPERATING_MODE",
+
+    "QMI_MESSAGE_NAS_ABORT",
+    "QMI_MESSAGE_NAS_GET_SERVING_SYSTEM",
+    "QMI_MESSAGE_NAS_GET_HOME_NETWORK",
+    "QMI_MESSAGE_NAS_INITIATE_NETWORK_REGISTER",
+    "QMI_MESSAGE_NAS_NETWORK_SCAN",
+    "QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH",
+    "QMI_MESSAGE_NAS_GET_SIGNAL_INFO",
+    "QMI_MESSAGE_NAS_GET_SYSTEM_INFO",
+
+    "QMI_MESSAGE_UIM_VERIFY_PIN",
+    "QMI_MESSAGE_UIM_UNBLOCK_PIN",
+    "QMI_MESSAGE_UIM_GET_CARD_STATUS",
+
+    "QMI_MESSAGE_WDS_ABORT",
+    "QMI_MESSAGE_WDS_START_NETWORK",
+    "QMI_MESSAGE_WDS_STOP_NETWORK",
+    "QMI_MESSAGE_WDS_SET_IP_FAMILY",
+    "QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS",
+    "QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS",
+
+    "QMI_MESSAGE_WDA_GET_DATA_FORMAT",
+    "QMI_MESSAGE_WDA_SET_DATA_FORMAT"
+]
diff --git a/data/qmi-service-nas.json b/data/qmi-service-nas.json
index e46a419..60d7d28 100644
--- a/data/qmi-service-nas.json
+++ b/data/qmi-service-nas.json
@@ -1197,7 +1197,7 @@
                     { "name"      : "Home Network 3GPP2 Ext",
                       "id"        : "0x11",
                       "type"      : "TLV",
-                      "since"     : "1.26",
+                      "since"     : "1.24.6",
                       "format"    : "sequence",
                       "contents"  : [ { "name"   : "MCC",
                                         "format" : "guint16" },
@@ -1596,7 +1596,7 @@
                       "since"         : "1.18",
                       "prerequisites" : [ { "common-ref" : "Success" } ] },
                     { "common-ref"    : "NAS NITZ Information",
-                      "since"         : "1.26",
+                      "since"         : "1.24.6",
                       "prerequisites" : [ { "common-ref" : "Success" } ] } ] },
 
   {  "name"    : "Operator Name",
@@ -1613,7 +1613,7 @@
                     { "common-ref"    : "NAS Operator String Name",
                       "since"         : "1.18" },
                     { "common-ref"    : "NAS NITZ Information",
-                      "since"         : "1.26" } ] },
+                      "since"         : "1.24.6" } ] },
 
   // *********************************************************************************
   {  "name"    : "Get Cell Location Info",
diff --git a/data/qmi-service-uim.json b/data/qmi-service-uim.json
index 990ea3d..1e9b639 100644
--- a/data/qmi-service-uim.json
+++ b/data/qmi-service-uim.json
@@ -607,7 +607,6 @@
   {  "name"    : "Power On SIM",
      "type"    : "Message",
      "service" : "UIM",
-     "service" : "UIM",
      "id"      : "0x0031",
      "since"   : "1.18",
      "input"   : [ { "name"      : "Slot",
@@ -630,7 +629,6 @@
   {  "name"    : "Change Provisioning Session",
      "type"    : "Message",
      "service" : "UIM",
-     "service" : "UIM",
      "id"      : "0x0038",
      "since"   : "1.24",
      "input"   : [ { "name"      : "Session Change",
diff --git a/data/qmi-service-voice.json b/data/qmi-service-voice.json
index a2f716e..b21a082 100644
--- a/data/qmi-service-voice.json
+++ b/data/qmi-service-voice.json
@@ -17,6 +17,93 @@
     {  "name"    : "QMI Indication Voice",
        "type"    : "Indication-ID-Enum" },
 
+    // *********************************************************************************
+    {  "name"    : "Indication Register",
+       "type"    : "Message",
+       "service" : "VOICE",
+       "id"      : "0x0003",
+       "since"   : "1.26",
+       "input"   : [ { "name"          : "DTMF Events",
+                       "id"            : "0x10",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Voice Privacy Events",
+                       "id"            : "0x11",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Supplementary Service Notification Events",
+                       "id"            : "0x12",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Call Notification Events",
+                       "id"            : "0x13",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Handover Events",
+                       "id"            : "0x14",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Speech Codec Events",
+                       "id"            : "0x15",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "USSD Notification Events",
+                       "id"            : "0x16",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     // TLV 0x17 "Sups Events", reserved for future use
+		     { "name"          : "Modification Events",
+                       "id"            : "0x18",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "UUS Events",
+                       "id"            : "0x19",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "AOC Events",
+                       "id"            : "0x1A",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Conference Events",
+                       "id"            : "0x1B",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "Extended Burst Type International Information Events",
+                       "id"            : "0x1C",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" },
+		     { "name"          : "MT Page Miss Information Events",
+                       "id"            : "0x1D",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "gboolean" } ],
+       "output"  : [ { "common-ref" : "Operation Result" } ] },
+
   // *********************************************************************************
   {  "name"    : "Get Supported Messages",
      "type"    : "Message",
@@ -138,6 +225,147 @@
                                                                  "format" : "string" } ] } } ] },
 
     // *********************************************************************************
+    {  "name"    : "Originate USSD",
+       "type"    : "Message",
+       "service" : "VOICE",
+       "id"      : "0x003A",
+       "since"   : "1.26",
+       "input"   : [ { "name"     : "USS Data",
+                       "id"       : "0x01",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] } ],
+       "output"  : [ { "common-ref" : "Operation Result" },
+		     { "name"          : "Failure Cause",
+                       "id"            : "0x10",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint16",
+                       "public-format" : "QmiVoiceCallEndReason" },
+		     { "name"     : "Alpha Identifier",
+		       "id"       : "0x11",
+		       "type"     : "TLV",
+		       "since"    : "1.26",
+		       "format"   : "sequence",
+		       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceAlphaDataCodingScheme" },
+                                      { "name"               : "Alpha",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] },
+		     { "name"     : "USS Data",
+                       "id"       : "0x12",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] },
+		     { "name"          : "Call Control Result Type",
+                       "id"            : "0x13",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "QmiVoiceCallControlResultType" },
+		     { "name"   : "Call ID",
+                       "id"     : "0x14",
+                       "type"   : "TLV",
+                       "since"  : "1.26",
+                       "format" : "guint8" },
+		     { "name"          : "Call Control Supplementary Service Type",
+                       "id"            : "0x15",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "QmiVoiceCallControlSupplementaryServiceType" },
+		     { "name"               : "USS Data UTF16",
+                       "id"                 : "0x16",
+                       "type"               : "TLV",
+                       "since"              : "1.26",
+                       "format"             : "array",
+                       "size-prefix-format" : "guint8",
+                       "array-element"      : { "format" : "guint16" } } ] },
+
+    // *********************************************************************************
+    {  "name"    : "Answer USSD",
+       "type"    : "Message",
+       "service" : "VOICE",
+       "id"      : "0x003B",
+       "since"   : "1.26",
+       "input"   : [ { "name"     : "USS Data",
+                       "id"       : "0x01",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] } ],
+       "output"  : [ { "common-ref" : "Operation Result" } ] },
+
+    // *********************************************************************************
+    {  "name"    : "Cancel USSD",
+       "type"    : "Message",
+       "service" : "VOICE",
+       "id"      : "0x003C",
+       "since"   : "1.26",
+       "output"  : [ { "common-ref" : "Operation Result" } ] },
+
+    // *********************************************************************************
+    {  "name"    : "Release USSD",
+       "type"    : "Indication",
+       "service" : "VOICE",
+       "id"      : "0x003D",
+       "since"   : "1.26" },
+
+    // *********************************************************************************
+    {  "name"    : "USSD",
+       "type"    : "Indication",
+       "service" : "VOICE",
+       "id"      : "0x003E",
+       "since"   : "1.26",
+       "output"  : [ { "name"          : "User Action",
+                       "id"            : "0x01",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint8",
+                       "public-format" : "QmiVoiceUserAction" },
+		     { "name"     : "USS Data",
+                       "id"       : "0x10",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] },
+		     { "name"               : "USS Data UTF16",
+                       "id"                 : "0x11",
+                       "type"               : "TLV",
+                       "since"              : "1.26",
+                       "format"             : "array",
+                       "size-prefix-format" : "guint8",
+                       "array-element"      : { "format" : "guint16" } } ] },
+
+    // *********************************************************************************
     {  "name"    : "Get Config",
        "type"    : "Message",
        "service" : "VOICE",
@@ -269,6 +497,73 @@
                        "type"          : "TLV",
                        "since"         : "1.14",
                        "format"        : "guint8",
-                       "public-format" : "QmiVoiceDomain" } ] }
+                       "public-format" : "QmiVoiceDomain" } ] },
 
+    // *********************************************************************************
+    {  "name"    : "Originate USSD No Wait",
+       "type"    : "Message",
+       "service" : "VOICE",
+       "id"      : "0x0043",
+       "since"   : "1.26",
+       "input"   : [ { "name"     : "USS Data",
+                       "id"       : "0x01",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] } ],
+       "output"  : [ { "common-ref" : "Operation Result" } ] },
+
+    {  "name"    : "Originate USSD No Wait",
+       "type"    : "Indication",
+       "service" : "VOICE",
+       "id"      : "0x0043",
+       "since"   : "1.26",
+       "output"  : [ { "name"       : "Error Code",
+                       "id"         : "0x10",
+                       "since"      : "1.26",
+                       "type"       : "TLV",
+                       "format"     : "guint16" },
+		     { "name"          : "Failure Cause",
+                       "id"            : "0x11",
+                       "type"          : "TLV",
+                       "since"         : "1.26",
+                       "format"        : "guint16",
+                       "public-format" : "QmiVoiceCallEndReason" },
+		     { "name"     : "USS Data",
+                       "id"       : "0x12",
+                       "type"     : "TLV",
+                       "since"    : "1.26",
+                       "format"   : "sequence",
+                       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceUssDataCodingScheme" },
+                                      { "name"               : "Data",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] },
+		     { "name"     : "Alpha Identifier",
+		       "id"       : "0x13",
+		       "type"     : "TLV",
+		       "since"    : "1.26",
+		       "format"   : "sequence",
+		       "contents" : [ { "name"          : "Data Coding Scheme",
+                                        "format"        : "guint8",
+                                        "public-format" : "QmiVoiceAlphaDataCodingScheme" },
+                                      { "name"               : "Alpha",
+                                        "format"             : "array",
+                                        "size-prefix-format" : "guint8",
+                                        "array-element"      : { "format" : "guint8" } } ] },
+		     { "name"               : "USS Data UTF16",
+                       "id"                 : "0x14",
+                       "type"               : "TLV",
+                       "since"              : "1.26",
+                       "format"             : "array",
+                       "size-prefix-format" : "guint8",
+                       "array-element"      : { "format" : "guint16" } } ] }
 ]
diff --git a/data/qmi-service-wda.json b/data/qmi-service-wda.json
index 93b06cc..bbbbbb3 100644
--- a/data/qmi-service-wda.json
+++ b/data/qmi-service-wda.json
@@ -187,7 +187,7 @@
                    { "name"          : "Downlink Data Aggregation Max Datagrams",
                      "id"            : "0x15",
                      "type"          : "TLV",
-                     "since"         : "1.26",
+                     "since"         : "1.24.6",
                      "format"        : "guint32",
                      "prerequisites" : [ { "common-ref" : "Success" } ] },
                    { "name"          : "Downlink Data Aggregation Max Size",
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
index deb2675..f3697b7 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
+++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
@@ -1114,6 +1114,12 @@
 QmiVoiceServiceOption
 QmiVoiceTtyMode
 QmiVoiceWcdmaAmrStatus
+QmiVoiceUserAction
+QmiVoiceUssDataCodingScheme
+QmiVoiceAlphaDataCodingScheme
+QmiVoiceCallEndReason
+QmiVoiceCallControlResultType
+QmiVoiceCallControlSupplementaryServiceType
 <SUBSECTION Methods>
 qmi_voice_call_state_get_string
 qmi_voice_call_type_get_string
@@ -1126,6 +1132,12 @@
 qmi_voice_service_option_get_string
 qmi_voice_tty_mode_get_string
 qmi_voice_wcdma_amr_status_build_string_from_mask
+qmi_voice_user_action_get_string
+qmi_voice_uss_data_coding_scheme_get_string
+qmi_voice_alpha_data_coding_scheme_get_string
+qmi_voice_call_end_reason_get_string
+qmi_voice_call_control_result_type_get_string
+qmi_voice_call_control_supplementary_service_type_get_string
 <SUBSECTION Private>
 qmi_voice_call_state_build_string_from_mask
 qmi_voice_call_type_build_string_from_mask
@@ -1138,6 +1150,12 @@
 qmi_voice_service_option_build_string_from_mask
 qmi_voice_tty_mode_build_string_from_mask
 qmi_voice_wcdma_amr_status_get_string
+qmi_voice_user_action_build_string_from_mask
+qmi_voice_uss_data_coding_scheme_build_string_from_mask
+qmi_voice_alpha_data_coding_scheme_build_string_from_mask
+qmi_voice_call_end_reason_build_string_from_mask
+qmi_voice_call_control_result_type_build_string_from_mask
+qmi_voice_call_control_supplementary_service_type_build_string_from_mask
 <SUBSECTION Standard>
 QMI_TYPE_VOICE_CALL_STATE
 QMI_TYPE_VOICE_CALL_TYPE
@@ -1150,6 +1168,12 @@
 QMI_TYPE_VOICE_SERVICE_OPTION
 QMI_TYPE_VOICE_TTY_MODE
 QMI_TYPE_VOICE_WCDMA_AMR_STATUS
+QMI_TYPE_VOICE_USER_ACTION
+QMI_TYPE_VOICE_USS_DATA_CODING_SCHEME
+QMI_TYPE_VOICE_ALPHA_DATA_CODING_SCHEME
+QMI_TYPE_VOICE_CALL_END_REASON
+QMI_TYPE_VOICE_CALL_CONTROL_RESULT_TYPE
+QMI_TYPE_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE
 qmi_voice_call_state_get_type
 qmi_voice_call_type_get_type
 qmi_voice_call_direction_get_type
@@ -1161,6 +1185,12 @@
 qmi_voice_service_option_get_type
 qmi_voice_tty_mode_get_type
 qmi_voice_wcdma_amr_status_get_type
+qmi_voice_user_action_get_type
+qmi_voice_uss_data_coding_scheme_get_type
+qmi_voice_alpha_data_coding_scheme_get_type
+qmi_voice_call_end_reason_get_type
+qmi_voice_call_control_result_type_get_type
+qmi_voice_call_control_supplementary_service_type_get_type
 </SECTION>
 
 <SECTION>
@@ -1516,6 +1546,7 @@
 QMI_WDS_CDMA_CAUSE_CODE_GENERAL_USER_DATA_SIZE_ERROR
 QMI_WDS_CDMA_CAUSE_CODE_GENERAL_OTHER
 QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE
+QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED
 <SUBSECTION DellFirmwareVersion>
 QmiDmsDellFirmwareVersionType
 qmi_dms_dell_firmware_version_type_get_string
@@ -1550,6 +1581,8 @@
 <SUBSECTION Private>
 QmiDeprecatedNasSimRejectState
 QmiDeprecatedWdsCdmaCauseCode
+QmiDeprecatedProtocolError
+QmiDeprecatedWdsVerboseCallEndReasonCm
 QMI_TYPE_DMS_DELL_FIRMWARE_VERSION_TYPE
 QMI_TYPE_MESSAGE_DMS_DELL_GET_FIRMWARE_VERSION_INPUT
 QMI_TYPE_MESSAGE_DMS_DELL_GET_FIRMWARE_VERSION_OUTPUT
diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
index 26c083c..d3f78bf 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml
+++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
@@ -377,6 +377,9 @@
     <section>
       <title>Voice Indications</title>
       <xi:include href="xml/qmi-indication-voice-all-call-status.xml"/>
+      <xi:include href="xml/qmi-indication-voice-release-ussd.xml"/>
+      <xi:include href="xml/qmi-indication-voice-ussd.xml"/>
+      <xi:include href="xml/qmi-indication-voice-originate-ussd-no-wait.xml"/>
     </section>
     <section>
       <title>Voice Requests</title>
@@ -385,6 +388,10 @@
       <xi:include href="xml/qmi-message-voice-answer-call.xml"/>
       <xi:include href="xml/qmi-message-voice-get-config.xml"/>
       <xi:include href="xml/qmi-message-voice-get-supported-messages.xml"/>
+      <xi:include href="xml/qmi-message-voice-originate-ussd.xml"/>
+      <xi:include href="xml/qmi-message-voice-answer-ussd.xml"/>
+      <xi:include href="xml/qmi-message-voice-cancel-ussd.xml"/>
+      <xi:include href="xml/qmi-message-voice-originate-ussd-no-wait.xml"/>
     </section>
   </chapter>
 
@@ -533,6 +540,10 @@
     <title>Index of new symbols in 1.24</title>
     <xi:include href="xml/api-index-1.24.xml"></xi:include>
   </chapter>
+  <chapter id="api-index-1-24-6" role="1.24.6">
+    <title>Index of new core symbols in 1.24.6</title>
+    <xi:include href="xml/api-index-1.24.6.xml"></xi:include>
+  </chapter>
   <chapter id="api-index-1-26" role="1.26">
     <title>Index of new symbols in 1.26</title>
     <xi:include href="xml/api-index-1.26.xml"></xi:include>
diff --git a/src/libqmi-glib/generated/Makefile.am b/src/libqmi-glib/generated/Makefile.am
index 8e207ab..78671e0 100644
--- a/src/libqmi-glib/generated/Makefile.am
+++ b/src/libqmi-glib/generated/Makefile.am
@@ -154,7 +154,7 @@
 		--template $(top_srcdir)/build-aux/templates/qmi-flags64-types-template.c \
 		$(FLAGS64) > $@
 
-# CTL service
+# CTL service (always available, regardless of collection)
 qmi-ctl.h qmi-ctl.c qmi-ctl.sections: $(top_srcdir)/data/qmi-service-ctl.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
 	$(AM_V_GEN)  \
 		rm -f qmi-ctl.h && \
@@ -164,154 +164,174 @@
 			--include $(top_srcdir)/data/qmi-common.json \
 			--output qmi-ctl
 
+if QMI_COLLECTION_USED
+COLLECTION_PATH=$(top_srcdir)/data/qmi-collection-@QMI_COLLECTION_NAME@.json
+COLLECTION_OPT=--collection $(COLLECTION_PATH)
+endif
+
 # DMS service
-qmi-dms.h qmi-dms.c qmi-dms.sections: $(top_srcdir)/data/qmi-service-dms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-dms.h qmi-dms.c qmi-dms.sections: $(top_srcdir)/data/qmi-service-dms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-dms.h && \
 		rm -f qmi-dms.c && \
 		 $(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-dms.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-dms
 
 # WDS service
-qmi-wds.h qmi-wds.c qmi-wds.sections: $(top_srcdir)/data/qmi-service-wds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-wds.h qmi-wds.c qmi-wds.sections: $(top_srcdir)/data/qmi-service-wds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-wds.h && \
 		rm -f qmi-wds.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-wds.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-wds
 
 # NAS service
-qmi-nas.h qmi-nas.c qmi-nas.sections: $(top_srcdir)/data/qmi-service-nas.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-nas.h qmi-nas.c qmi-nas.sections: $(top_srcdir)/data/qmi-service-nas.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-nas.h && \
 		rm -f qmi-nas.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-nas.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-nas
 
 # WMS service
-qmi-wms.h qmi-wms.c qmi-wms.sections: $(top_srcdir)/data/qmi-service-wms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-wms.h qmi-wms.c qmi-wms.sections: $(top_srcdir)/data/qmi-service-wms.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-wms.h && \
 		rm -f qmi-wms.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-wms.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-wms
 
 # PDS service
-qmi-pds.h qmi-pds.c qmi-pds.sections: $(top_srcdir)/data/qmi-service-pds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-pds.h qmi-pds.c qmi-pds.sections: $(top_srcdir)/data/qmi-service-pds.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-pds.h && \
 		rm -f qmi-pds.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-pds.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-pds
 
 # PDC service
-qmi-pdc.h qmi-pdc.c qmi-pdc.sections: $(top_srcdir)/data/qmi-service-pdc.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-pdc.h qmi-pdc.c qmi-pdc.sections: $(top_srcdir)/data/qmi-service-pdc.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-pdc.h && \
 		rm -f qmi-pdc.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-pdc.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-pdc
 
 # PBM service
-qmi-pbm.h qmi-pbm.c qmi-pbm.sections: $(top_srcdir)/data/qmi-service-pbm.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-pbm.h qmi-pbm.c qmi-pbm.sections: $(top_srcdir)/data/qmi-service-pbm.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-pbm.h && \
 		rm -f qmi-pbm.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-pbm.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-pbm
 
 # UIM service
-qmi-uim.h qmi-uim.c qmi-uim.sections: $(top_srcdir)/data/qmi-service-uim.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-uim.h qmi-uim.c qmi-uim.sections: $(top_srcdir)/data/qmi-service-uim.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN)  \
 		rm -f qmi-uim.h && \
 		rm -f qmi-uim.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-uim.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-uim
 
 # OMA service
-qmi-oma.h qmi-oma.c qmi-oma.sections: $(top_srcdir)/data/qmi-service-oma.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-oma.h qmi-oma.c qmi-oma.sections: $(top_srcdir)/data/qmi-service-oma.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-oma.h && \
 		rm -f qmi-oma.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-oma.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-oma
 
 # GAS service
-qmi-gas.h qmi-gas.c qmi-gas.sections: $(top_srcdir)/data/qmi-service-gas.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-gas.h qmi-gas.c qmi-gas.sections: $(top_srcdir)/data/qmi-service-gas.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-gas.h && \
 		rm -f qmi-gas.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-gas.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-gas
 
 # WDA service
-qmi-wda.h qmi-wda.c qmi-wda.sections: $(top_srcdir)/data/qmi-service-wda.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-wda.h qmi-wda.c qmi-wda.sections: $(top_srcdir)/data/qmi-service-wda.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-wda.h && \
 		rm -f qmi-wda.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-wda.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-wda
 
 # VOICE service
-qmi-voice.h qmi-voice.c qmi-voice.sections: $(top_srcdir)/data/qmi-service-voice.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-voice.h qmi-voice.c qmi-voice.sections: $(top_srcdir)/data/qmi-service-voice.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-voice.h && \
 		rm -f qmi-voice.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-voice.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-voice
 
 # LOC service
-qmi-loc.h qmi-loc.c qmi-loc.sections: $(top_srcdir)/data/qmi-service-loc.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-loc.h qmi-loc.c qmi-loc.sections: $(top_srcdir)/data/qmi-service-loc.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-loc.h && \
 		rm -f qmi-loc.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-loc.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-loc
 
 # QoS service
-qmi-qos.h qmi-qos.c qmi-qos.sections: $(top_srcdir)/data/qmi-service-qos.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-qos.h qmi-qos.c qmi-qos.sections: $(top_srcdir)/data/qmi-service-qos.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-qos.h && \
 		rm -f qmi-qos.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-qos.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-qos
 
 # DSD service
-qmi-dsd.h qmi-dsd.c qmi-dsd.sections: $(top_srcdir)/data/qmi-service-dsd.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen
+qmi-dsd.h qmi-dsd.c qmi-dsd.sections: $(top_srcdir)/data/qmi-service-dsd.json $(top_srcdir)/build-aux/qmi-codegen/*.py $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen $(COLLECTION_PATH)
 	$(AM_V_GEN) \
 		rm -f qmi-dsd.h && \
 		rm -f qmi-dsd.c && \
 		$(PYTHON) $(top_srcdir)/build-aux/qmi-codegen/qmi-codegen \
 			--input $(top_srcdir)/data/qmi-service-dsd.json \
 			--include $(top_srcdir)/data/qmi-common.json \
+			$(COLLECTION_OPT) \
 			--output qmi-dsd
 
 BUILT_SOURCES = $(GENERATED_H) $(GENERATED_C)
diff --git a/src/libqmi-glib/qmi-compat.c b/src/libqmi-glib/qmi-compat.c
index cec8697..7c7a494 100644
--- a/src/libqmi-glib/qmi-compat.c
+++ b/src/libqmi-glib/qmi-compat.c
@@ -626,6 +626,8 @@
     *buffer_size = (*buffer_size) - fixed_size;
 }
 
+#if defined HAVE_QMI_MESSAGE_DMS_SET_SERVICE_PROGRAMMING_CODE
+
 gboolean
 qmi_message_dms_set_service_programming_code_input_get_new (
     QmiMessageDmsSetServiceProgrammingCodeInput *self,
@@ -662,6 +664,8 @@
   return qmi_message_dms_set_service_programming_code_input_set_current_code (self, arg_current, error);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_SERVICE_PROGRAMMING_CODE */
+
 gchar *
 qmi_message_get_printable (QmiMessage  *self,
                            const gchar *line_prefix)
@@ -733,13 +737,29 @@
         return ret;                                                                                        \
     }
 
-SESSION_INFORMATION_DEPRECATED_METHOD (ReadTransparent,   read_transparent)
-SESSION_INFORMATION_DEPRECATED_METHOD (ReadRecord,        read_record)
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
+SESSION_INFORMATION_DEPRECATED_METHOD (ReadTransparent, read_transparent)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_READ_RECORD
+SESSION_INFORMATION_DEPRECATED_METHOD (ReadRecord, read_record)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
 SESSION_INFORMATION_DEPRECATED_METHOD (GetFileAttributes, get_file_attributes)
-SESSION_INFORMATION_DEPRECATED_METHOD (SetPinProtection,  set_pin_protection)
-SESSION_INFORMATION_DEPRECATED_METHOD (VerifyPin,         verify_pin)
-SESSION_INFORMATION_DEPRECATED_METHOD (UnblockPin,        unblock_pin)
-SESSION_INFORMATION_DEPRECATED_METHOD (ChangePin,         change_pin)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION
+SESSION_INFORMATION_DEPRECATED_METHOD (SetPinProtection, set_pin_protection)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_VERIFY_PIN
+SESSION_INFORMATION_DEPRECATED_METHOD (VerifyPin, verify_pin)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN
+SESSION_INFORMATION_DEPRECATED_METHOD (UnblockPin, unblock_pin)
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PIN
+SESSION_INFORMATION_DEPRECATED_METHOD (ChangePin, change_pin)
+#endif
+
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
 
 gboolean
 qmi_message_wda_get_data_format_output_get_uplink_data_aggregation_max_size (
@@ -750,6 +770,8 @@
     return qmi_message_wda_get_data_format_output_get_downlink_data_aggregation_max_datagrams (self, value_uplink_data_aggregation_max_size, error);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT */
+
 gboolean
 qmi_device_close (QmiDevice *self,
                   GError **error)
@@ -771,6 +793,8 @@
     return qmi_dms_foxconn_firmware_version_type_get_string ((QmiDmsFoxconnFirmwareVersionType) val);
 }
 
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
+
 GType
 qmi_message_dms_dell_get_firmware_version_output_get_type (void)
 {
@@ -869,6 +893,8 @@
     return qmi_client_dms_foxconn_get_firmware_version_finish (self, res, error);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION */
+
 GType
 qmi_dms_dell_device_mode_get_type (void)
 {
@@ -881,6 +907,8 @@
     return qmi_dms_foxconn_device_mode_get_string ((QmiDmsFoxconnDeviceMode) val);
 }
 
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
+
 GType
 qmi_message_dms_dell_change_device_mode_input_get_type (void)
 {
@@ -970,6 +998,10 @@
     return qmi_client_dms_foxconn_change_device_mode_finish (self, res, error);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME
+
 gboolean
 qmi_message_nas_get_operator_name_output_get_operator_nitz_information (
     QmiMessageNasGetOperatorNameOutput *self,
@@ -1002,6 +1034,10 @@
     return TRUE;
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME */
+
+#if defined HAVE_QMI_INDICATION_NAS_OPERATOR_NAME
+
 gboolean
 qmi_indication_nas_operator_name_output_get_operator_nitz_information (
     QmiIndicationNasOperatorNameOutput *self,
@@ -1034,6 +1070,10 @@
     return TRUE;
 }
 
+#endif /* HAVE_QMI_INDICATION_NAS_OPERATOR_NAME */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK
+
 gboolean
 qmi_message_nas_get_home_network_output_get_home_network_3gpp2 (
     QmiMessageNasGetHomeNetworkOutput *self,
@@ -1062,4 +1102,6 @@
     return TRUE;
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK */
+
 #endif /* QMI_DISABLE_DEPRECATED */
diff --git a/src/libqmi-glib/qmi-compat.h b/src/libqmi-glib/qmi-compat.h
index 4ffb539..06bb2aa 100644
--- a/src/libqmi-glib/qmi-compat.h
+++ b/src/libqmi-glib/qmi-compat.h
@@ -611,6 +611,8 @@
                                                    guint16       fixed_size,
                                                    const gchar  *in);
 
+#if defined HAVE_QMI_MESSAGE_DMS_SET_SERVICE_PROGRAMMING_CODE
+
 /**
  * qmi_message_dms_set_service_programming_code_input_get_new:
  * @self: a #QmiMessageDmsSetServiceProgrammingCodeInput.
@@ -687,6 +689,8 @@
     const gchar *arg_current,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_SERVICE_PROGRAMMING_CODE */
+
 /* The following type exists just so that we can get deprecation warnings */
 G_DEPRECATED
 typedef int QmiDeprecatedNasSimRejectState;
@@ -1076,6 +1080,10 @@
  */
 #define QMI_WDS_CDMA_CAUSE_CODE_GENERAL_OTHER (QmiDeprecatedWdsCdmaCauseCode) QMI_WMS_CDMA_CAUSE_CODE_GENERAL_OTHER
 
+/* The following type exists just so that we can get deprecation warnings */
+G_DEPRECATED
+typedef int QmiDeprecatedProtocolError;
+
 /**
  * QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE:
  *
@@ -1084,7 +1092,21 @@
  * Since: 1.0
  * Deprecated: 1.22.0: Use the #QMI_PROTOCOL_ERROR_REQUESTED_NUMBER_UNSUPPORTED instead.
  */
-#define QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE (QmiProtocolError) QMI_PROTOCOL_ERROR_REQUESTED_NUMBER_UNSUPPORTED
+#define QMI_PROTOCOL_ERROR_QOS_UNAVAILABLE (QmiDeprecatedProtocolError) QMI_PROTOCOL_ERROR_REQUESTED_NUMBER_UNSUPPORTED
+
+/* The following type exists just so that we can get deprecation warnings */
+G_DEPRECATED
+typedef int QmiDeprecatedWdsVerboseCallEndReasonCm;
+
+/**
+ * QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED:
+ *
+ * Conference (not configuration) failed.
+ *
+ * Since: 1.0
+ * Deprecated: 1.24.10: Use the correct #QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFERENCE_FAILED name instead.
+ */
+#define QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED (QmiDeprecatedWdsVerboseCallEndReasonCm) QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFERENCE_FAILED
 
 /**
  * qmi_message_tlv_read_gfloat:
@@ -1116,6 +1138,8 @@
                                       gfloat      *out,
                                       GError     **error);
 
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
+
 /**
  * qmi_message_uim_read_transparent_input_get_session_information:
  * @self: a #QmiMessageUimReadTransparentInput.
@@ -1158,6 +1182,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT */
+
+#if defined HAVE_QMI_MESSAGE_UIM_READ_RECORD
+
 /**
  * qmi_message_uim_read_record_input_get_session_information:
  * @self: a #QmiMessageUimReadRecordInput.
@@ -1200,6 +1228,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_RECORD */
+
+#if defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
+
 /**
  * qmi_message_uim_get_file_attributes_input_get_session_information:
  * @self: a #QmiMessageUimGetFileAttributesInput.
@@ -1242,6 +1274,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES */
+
+#if defined HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION
+
 /**
  * qmi_message_uim_set_pin_protection_input_get_session_information:
  * @self: a #QmiMessageUimSetPinProtectionInput.
@@ -1284,6 +1320,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION */
+
+#if defined HAVE_QMI_MESSAGE_UIM_VERIFY_PIN
+
 /**
  * qmi_message_uim_verify_pin_input_get_session_information:
  * @self: a #QmiMessageUimVerifyPinInput.
@@ -1326,6 +1366,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_VERIFY_PIN */
+
+#if defined HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN
+
 /**
  * qmi_message_uim_unblock_pin_input_get_session_information:
  * @self: a #QmiMessageUimUnblockPinInput.
@@ -1368,6 +1412,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN */
+
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PIN
+
 /**
  * qmi_message_uim_change_pin_input_get_session_information:
  * @self: a #QmiMessageUimChangePinInput.
@@ -1410,6 +1458,10 @@
     const gchar *value_session_information_application_identifier,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_UIM_CHANGE_PIN */
+
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
+
 /**
  * qmi_message_wda_get_data_format_output_get_uplink_data_aggregation_max_size:
  * @self: a #QmiMessageWdaGetDataFormatOutput.
@@ -1421,7 +1473,7 @@
  * Returns: %TRUE if the field is found, %FALSE otherwise.
  *
  * Since: 1.10
- * Deprecated: 1.26: Use qmi_message_wda_get_data_format_output_get_downlink_data_aggregation_max_datagrams() instead.
+ * Deprecated: 1.24.6: Use qmi_message_wda_get_data_format_output_get_downlink_data_aggregation_max_datagrams() instead.
  */
 G_DEPRECATED_FOR (qmi_message_wda_get_data_format_output_get_downlink_data_aggregation_max_datagrams)
 gboolean qmi_message_wda_get_data_format_output_get_uplink_data_aggregation_max_size
@@ -1429,6 +1481,8 @@
      guint32 *value_uplink_data_aggregation_max_size,
      GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT */
+
 /**
  * QmiDmsDellFirmwareVersionType:
  * @QMI_DMS_DELL_FIRMWARE_VERSION_TYPE_FIRMWARE_MCFG: E.g. T77W968.F0.0.0.2.3.GC.004.
@@ -1464,6 +1518,8 @@
  */
 const gchar *qmi_dms_dell_firmware_version_type_get_string (QmiDmsDellFirmwareVersionType val);
 
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
+
 /**
  * QmiMessageDmsDellGetFirmwareVersionInput:
  *
@@ -1685,6 +1741,8 @@
     GAsyncResult *res,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION */
+
 /*****************************************************************************/
 /* Helper enums for the 'QMI DMS Dell Change Device Mode' message */
 
@@ -1724,6 +1782,8 @@
 G_DEPRECATED_FOR (qmi_dms_foxconn_device_mode_get_string)
 const gchar *qmi_dms_dell_device_mode_get_string (QmiDmsDellDeviceMode val);
 
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
+
 /**
  * QmiMessageDmsDellChangeDeviceModeInput:
  *
@@ -1924,6 +1984,10 @@
     GAsyncResult *res,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME
+
 /**
  * qmi_message_nas_get_operator_name_output_get_operator_nitz_information:
  * @self: a #QmiMessageNasGetOperatorNameOutput.
@@ -1940,7 +2004,7 @@
  * Returns: %TRUE if the field is found, %FALSE otherwise.
  *
  * Since: 1.18
- * Deprecated: 1.26: Use qmi_message_nas_get_operator_name_output_get_nitz_information() instead.
+ * Deprecated: 1.24.6: Use qmi_message_nas_get_operator_name_output_get_nitz_information() instead.
  */
 G_DEPRECATED_FOR (qmi_message_nas_get_operator_name_output_get_nitz_information)
 gboolean qmi_message_nas_get_operator_name_output_get_operator_nitz_information (
@@ -1953,6 +2017,10 @@
     const gchar **value_operator_nitz_information_short_name,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME */
+
+#if defined HAVE_QMI_INDICATION_NAS_OPERATOR_NAME
+
 /**
  * qmi_indication_nas_operator_name_output_get_operator_nitz_information:
  * @self: a #QmiIndicationNasOperatorNameOutput.
@@ -1969,7 +2037,7 @@
  * Returns: %TRUE if the field is found, %FALSE otherwise.
  *
  * Since: 1.18
- * Deprecated: 1.26: Use qmi_indication_nas_operator_name_output_get_nitz_information() instead.
+ * Deprecated: 1.24.6: Use qmi_indication_nas_operator_name_output_get_nitz_information() instead.
  */
 G_DEPRECATED_FOR (qmi_indication_nas_operator_name_output_get_nitz_information)
 gboolean qmi_indication_nas_operator_name_output_get_operator_nitz_information (
@@ -1982,6 +2050,10 @@
     const gchar **value_operator_nitz_information_short_name,
     GError **error);
 
+#endif /* HAVE_QMI_INDICATION_NAS_OPERATOR_NAME */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK
+
 /**
  * qmi_message_nas_get_home_network_output_get_home_network_3gpp2:
  * @self: a #QmiMessageNasGetHomeNetworkOutput.
@@ -1997,7 +2069,7 @@
  * Returns: %TRUE if the field is found, %FALSE otherwise.
  *
  * Since: 1.0
- * Deprecated: 1.26: Use qmi_message_nas_get_home_network_output_get_home_network_3gpp2_ext() instead.
+ * Deprecated: 1.24.6: Use qmi_message_nas_get_home_network_output_get_home_network_3gpp2_ext() instead.
  */
 G_DEPRECATED_FOR (qmi_message_nas_get_home_network_output_get_home_network_3gpp2_ext)
 gboolean qmi_message_nas_get_home_network_output_get_home_network_3gpp2 (
@@ -2009,6 +2081,8 @@
     const gchar **value_home_network_3gpp2_description,
     GError **error);
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK */
+
 #endif /* QMI_DISABLE_DEPRECATED */
 
 #endif /* _LIBQMI_GLIB_QMI_COMPAT_H_ */
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
index 4a436fa..62e0ee1 100644
--- a/src/libqmi-glib/qmi-device.c
+++ b/src/libqmi-glib/qmi-device.c
@@ -1097,6 +1097,7 @@
 
     ctx = g_slice_new0 (AllocateClientContext);
     ctx->service = service;
+    ctx->client_type = G_TYPE_INVALID;
 
     task = g_task_new (self, cancellable, callback, user_data);
     g_task_set_task_data (task,
@@ -1123,49 +1124,79 @@
         g_object_unref (task);
         return;
     case QMI_SERVICE_DMS:
+#if defined HAVE_QMI_SERVICE_DMS
         ctx->client_type = QMI_TYPE_CLIENT_DMS;
+#endif
         break;
     case QMI_SERVICE_WDS:
+#if defined HAVE_QMI_SERVICE_WDS
         ctx->client_type = QMI_TYPE_CLIENT_WDS;
+#endif
         break;
     case QMI_SERVICE_NAS:
+#if defined HAVE_QMI_SERVICE_NAS
         ctx->client_type = QMI_TYPE_CLIENT_NAS;
+#endif
         break;
     case QMI_SERVICE_WMS:
+#if defined HAVE_QMI_SERVICE_WMS
         ctx->client_type = QMI_TYPE_CLIENT_WMS;
+#endif
         break;
     case QMI_SERVICE_PDS:
+#if defined HAVE_QMI_SERVICE_PDS
         ctx->client_type = QMI_TYPE_CLIENT_PDS;
+#endif
         break;
     case QMI_SERVICE_PDC:
+#if defined HAVE_QMI_SERVICE_PDC
         ctx->client_type = QMI_TYPE_CLIENT_PDC;
+#endif
         break;
     case QMI_SERVICE_PBM:
+#if defined HAVE_QMI_SERVICE_PBM
         ctx->client_type = QMI_TYPE_CLIENT_PBM;
+#endif
         break;
     case QMI_SERVICE_UIM:
+#if defined HAVE_QMI_SERVICE_UIM
         ctx->client_type = QMI_TYPE_CLIENT_UIM;
+#endif
         break;
     case QMI_SERVICE_OMA:
+#if defined HAVE_QMI_SERVICE_OMA
         ctx->client_type = QMI_TYPE_CLIENT_OMA;
+#endif
         break;
     case QMI_SERVICE_GAS:
+#if defined HAVE_QMI_SERVICE_GAS
         ctx->client_type = QMI_TYPE_CLIENT_GAS;
+#endif
         break;
     case QMI_SERVICE_WDA:
+#if defined HAVE_QMI_SERVICE_WDA
         ctx->client_type = QMI_TYPE_CLIENT_WDA;
+#endif
         break;
     case QMI_SERVICE_VOICE:
+#if defined HAVE_QMI_SERVICE_VOICE
         ctx->client_type = QMI_TYPE_CLIENT_VOICE;
+#endif
         break;
     case QMI_SERVICE_LOC:
+#if defined HAVE_QMI_SERVICE_LOC
         ctx->client_type = QMI_TYPE_CLIENT_LOC;
+#endif
         break;
     case QMI_SERVICE_QOS:
+#if defined HAVE_QMI_SERVICE_QOS
         ctx->client_type = QMI_TYPE_CLIENT_QOS;
+#endif
         break;
     case QMI_SERVICE_DSD:
+#if defined HAVE_QMI_SERVICE_DSD
         ctx->client_type = QMI_TYPE_CLIENT_DSD;
+#endif
         break;
 
     case QMI_SERVICE_UNKNOWN:
@@ -1204,10 +1235,12 @@
     case QMI_SERVICE_FOTA:
     case QMI_SERVICE_GMS:
     default:
-        g_task_return_new_error (task,
-                                 QMI_CORE_ERROR,
-                                 QMI_CORE_ERROR_INVALID_ARGS,
-                                 "Clients for service '%s' not yet supported",
+        break;
+    }
+
+    if (ctx->client_type == G_TYPE_INVALID) {
+        g_task_return_new_error (task, QMI_CORE_ERROR, QMI_CORE_ERROR_INVALID_ARGS,
+                                 "Clients for service '%s' not supported",
                                  qmi_service_get_string (service));
         g_object_unref (task);
         return;
diff --git a/src/libqmi-glib/qmi-endpoint-qrtr.c b/src/libqmi-glib/qmi-endpoint-qrtr.c
index 09db8f9..e5f9640 100644
--- a/src/libqmi-glib/qmi-endpoint-qrtr.c
+++ b/src/libqmi-glib/qmi-endpoint-qrtr.c
@@ -96,10 +96,10 @@
                  GIOCondition cond,
                  QmiEndpointQrtr *self)
 {
-    GError *error = NULL;
-    GSocketAddress *addr;
+    g_autoptr(GError) error = NULL;
+    g_autoptr(GSocketAddress) addr = NULL;
     struct sockaddr_qrtr sq;
-    GByteArray *buf;
+    g_autoptr(GByteArray) buf = NULL;
     gssize next_datagram_size;
     gssize bytes_received;
     ClientInfo *info;
diff --git a/src/libqmi-glib/qmi-enums-nas.h b/src/libqmi-glib/qmi-enums-nas.h
index 03a4aca..3fd41f4 100644
--- a/src/libqmi-glib/qmi-enums-nas.h
+++ b/src/libqmi-glib/qmi-enums-nas.h
@@ -778,7 +778,7 @@
  * Returns: the UTF-8 encoded string, or %NULL if an error happened during the conversion.
  * The returned value should be freed with g_free().
  *
- * Since: 1.26
+ * Since: 1.24.6
  */
 gchar *qmi_nas_read_string_from_network_description_encoded_array (QmiNasNetworkDescriptionEncoding  encoding,
                                                                    const GArray                     *array);
@@ -858,6 +858,7 @@
  * @QMI_NAS_RAT_MODE_PREFERENCE_UMTS: UMTS.
  * @QMI_NAS_RAT_MODE_PREFERENCE_LTE: LTE.
  * @QMI_NAS_RAT_MODE_PREFERENCE_TD_SCDMA: TD-SCDMA.
+ * @QMI_NAS_RAT_MODE_PREFERENCE_5GNR: 5GNR. Since 1.26.
  *
  * Flags specifying radio access technology mode preference.
  *
@@ -869,7 +870,8 @@
     QMI_NAS_RAT_MODE_PREFERENCE_GSM         = 1 << 2,
     QMI_NAS_RAT_MODE_PREFERENCE_UMTS        = 1 << 3,
     QMI_NAS_RAT_MODE_PREFERENCE_LTE         = 1 << 4,
-    QMI_NAS_RAT_MODE_PREFERENCE_TD_SCDMA    = 1 << 5
+    QMI_NAS_RAT_MODE_PREFERENCE_TD_SCDMA    = 1 << 5,
+    QMI_NAS_RAT_MODE_PREFERENCE_5GNR        = 1 << 6,
 } QmiNasRatModePreference;
 
 /**
@@ -1450,7 +1452,7 @@
  * Returns: the UTF-8 encoded string, or %NULL if an error happened during the conversion.
  * The returned value should be freed with g_free().
  *
- * Since: 1.26
+ * Since: 1.24.6
  */
 gchar *qmi_nas_read_string_from_plmn_encoded_array (QmiNasPlmnEncodingScheme  encoding,
                                                     const GArray             *array);
diff --git a/src/libqmi-glib/qmi-enums-voice.h b/src/libqmi-glib/qmi-enums-voice.h
index da05919..37aa228 100644
--- a/src/libqmi-glib/qmi-enums-voice.h
+++ b/src/libqmi-glib/qmi-enums-voice.h
@@ -17,7 +17,8 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2014-2017 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2014-2020 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2019-2020 Alexander Couzens <lynxis@fe80.eu>
  */
 
 #ifndef _LIBQMI_GLIB_QMI_ENUMS_VOICE_H_
@@ -329,4 +330,531 @@
  * Since: 1.14
  */
 
+/**
+ * QmiVoiceUserAction:
+ * @QMI_VOICE_USER_ACTION_UNKNOWN: Unknown user action.
+ * @QMI_VOICE_USER_ACTION_NOT_REQUIRED: User is not required to respond to the USSD code.
+ * @QMI_VOICE_USER_ACTION_REQUIRED: User is required to respond to the USSD code.
+ *
+ * User action type.
+ */
+typedef enum {
+    QMI_VOICE_USER_ACTION_UNKNOWN      = 0x00,
+    QMI_VOICE_USER_ACTION_NOT_REQUIRED = 0x01,
+    QMI_VOICE_USER_ACTION_REQUIRED     = 0x02,
+} QmiVoiceUserAction;
+
+/**
+ * qmi_voice_user_action_get_string:
+ *
+ * Since: 1.26
+ */
+
+/**
+ * QmiVoiceUssDataCodingScheme:
+ * @QMI_VOICE_USS_DATA_CODING_SCHEME_UNKNOWN: Unknown.
+ * @QMI_VOICE_USS_DATA_CODING_SCHEME_ASCII: ASCII coding scheme.
+ * @QMI_VOICE_USS_DATA_CODING_SCHEME_8BIT: 8-bit coding scheme.
+ * @QMI_VOICE_USS_DATA_CODING_SCHEME_UCS2: UCS2.
+ *
+ * Data Coding Scheme used in USSD operations.
+ *
+ * Since: 1.26
+ */
+typedef enum {
+    QMI_VOICE_USS_DATA_CODING_SCHEME_UNKNOWN = 0x00,
+    QMI_VOICE_USS_DATA_CODING_SCHEME_ASCII   = 0x01,
+    QMI_VOICE_USS_DATA_CODING_SCHEME_8BIT    = 0x02,
+    QMI_VOICE_USS_DATA_CODING_SCHEME_UCS2    = 0x03,
+} QmiVoiceUssDataCodingScheme;
+
+/**
+ * qmi_voice_uss_data_coding_scheme_get_string:
+ *
+ * Since: 1.26
+ */
+
+/**
+ * QmiVoiceAlphaDataCodingScheme:
+ * @QMI_VOICE_ALPHA_DATA_CODING_SCHEME_GSM: SMS default 7-bit coded alphabet.
+ * @QMI_VOICE_ALPHA_DATA_CODING_SCHEME_UCS2: UCS2.
+ *
+ * Alpha Coding Scheme.
+ *
+ * Since: 1.26
+ */
+typedef enum {
+    QMI_VOICE_ALPHA_DATA_CODING_SCHEME_GSM  = 0x01,
+    QMI_VOICE_ALPHA_DATA_CODING_SCHEME_UCS2 = 0x02,
+} QmiVoiceAlphaDataCodingScheme;
+
+/**
+ * qmi_voice_alpha_data_coding_scheme_get_string:
+ *
+ * Since: 1.26
+ */
+
+/**
+ * QmiVoiceCallEndReason:
+ * @QMI_VOICE_CALL_END_REASON_OFFLINE: Device is offline.
+ * @QMI_VOICE_CALL_END_REASON_CDMA_LOCK: (CDMA) Phone is CDMA locked.
+ * @QMI_VOICE_CALL_END_REASON_NO_SERVICE: Device has no service.
+ * @QMI_VOICE_CALL_END_REASON_FADE: Fade.
+ * @QMI_VOICE_CALL_END_REASON_INTERCEPT: (CDMA) Received intercept from the BS.
+ * @QMI_VOICE_CALL_END_REASON_REORDER: (CDMA) Received reorder from the BS.
+ * @QMI_VOICE_CALL_END_REASON_RELEASE_NORMAL: Received release from the BS.
+ * @QMI_VOICE_CALL_END_REASON_RELEASE_SO_REJECT: (CDMA) Received release from the BS.
+ * @QMI_VOICE_CALL_END_REASON_INCOMING_CALL: (CDMA) Received incoming call from the BS.
+ * @QMI_VOICE_CALL_END_REASON_ALERT_STOP: (CDMA) Received alert stop from the BS.
+ * @QMI_VOICE_CALL_END_REASON_CLIENT_END: Client ended the call.
+ * @QMI_VOICE_CALL_END_REASON_ACTIVATION: (CDMA) Received end activation.
+ * @QMI_VOICE_CALL_END_REASON_MC_ABORT: (CDMA) MC aborted the origination/conversation.
+ * @QMI_VOICE_CALL_END_REASON_MAX_ACCESS_PROBE: (CDMA) Maximum access probes transmitted.
+ * @QMI_VOICE_CALL_END_REASON_PSIST_N: (CDMA) Persistence test failure.
+ * @QMI_VOICE_CALL_END_REASON_UIM_NOT_PRESENT: R-UIM not present.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_ATTEMPT_IN_PROGRESS: Access attempt in progress.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE: Access failure.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_RETRY_ORDER: (CDMA) Retry order.
+ * @QMI_VOICE_CALL_END_REASON_CCS_NOT_SUPPORTED_BY_BS: (CDMA) Concurrent service not supported by the BS.
+ * @QMI_VOICE_CALL_END_REASON_NO_RESPONSE_FROM_BS: (CDMA) No response received from the BS.
+ * @QMI_VOICE_CALL_END_REASON_REJECTED_BY_BS: (CDMA) Rejected by the BS.
+ * @QMI_VOICE_CALL_END_REASON_INCOMPATIBLE: (CDMA) Concurrent services requested are incompatible.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_BLOCK: (CDMA) Access blocked by the BS.
+ * @QMI_VOICE_CALL_END_REASON_ALREADY_IN_TC: Already in TC.
+ * @QMI_VOICE_CALL_END_REASON_EMERGENCY_FLASHED: (CDMA) Emergency call is flashed over this call.
+ * @QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_GPS: Call originated during GPS.
+ * @QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_SMS: Call originated during SMS.
+ * @QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_DATA: Call originated during data.
+ * @QMI_VOICE_CALL_END_REASON_REDIRECTION_OR_HANDOFF: Redirection or handoff.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_BLOCK_ALL: Access blocked by BS for all.
+ * @QMI_VOICE_CALL_END_REASON_OTASP_SPC_ERR: OTASP SPC error indication.
+ * @QMI_VOICE_CALL_END_REASON_IS707B_MAX_ACCESS_PROBES: Maximum access probes for IS-707B call.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE_REJECT_ORDER: Base station reject order.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE_RETRY_ORDER: Base station retry order.
+ * @QMI_VOICE_CALL_END_REASON_TIMEOUT_T42: Timer T42 expired.
+ * @QMI_VOICE_CALL_END_REASON_TIMEOUT_T40: Timer T40 expired.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_INIT_FAILURE: Service initialization failure.
+ * @QMI_VOICE_CALL_END_REASON_TIMEOUT_T50: Timer T50 expired.
+ * @QMI_VOICE_CALL_END_REASON_TIMEOUT_T51: Timer T51 expired.
+ * @QMI_VOICE_CALL_END_REASON_RL_ACK_TIMEOUT: Acknowledgement timeout due to 12 retransmissions.
+ * @QMI_VOICE_CALL_END_REASON_BAD_FORWARD_LINK: Bad forward link or timer T5M expired.
+ * @QMI_VOICE_CALL_END_REASON_TRM_REQUEST_FAILED: Transceiver Resource Manager request failed.
+ * @QMI_VOICE_CALL_END_REASON_TIMEOUT_T41: Timer T41 expired.
+ * @QMI_VOICE_CALL_END_REASON_INCOMING_REJECTED: (GSM/WCDMA) Client rejected incoming call.
+ * @QMI_VOICE_CALL_END_REASON_SETUP_REJECTED: (GSM/WCDMA) Client rejected a setup indication.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_END: (GSM/WCDMA) Network ended the call.
+ * @QMI_VOICE_CALL_END_REASON_NO_FUNDS: (GSM/WCDMA) No funds.
+ * @QMI_VOICE_CALL_END_REASON_NO_GW_SERVICE: (GSM/WCDMA) Device has no service.
+ * @QMI_VOICE_CALL_END_REASON_NO_CDMA_SERVICE: (CDMA) Device has no service.
+ * @QMI_VOICE_CALL_END_REASON_NO_FULL_SERVICE: Full service is unavailable.
+ * @QMI_VOICE_CALL_END_REASON_MAX_PS_CALLS: No resources available to handle a new MO/MT PS call.
+ * @QMI_VOICE_CALL_END_REASON_UNKNOWN_SUBSCRIBER: Unknown subscriber.
+ * @QMI_VOICE_CALL_END_REASON_ILLEGAL_SUBSCRIBER: Illegal subscriber.
+ * @QMI_VOICE_CALL_END_REASON_BEARER_SERVICE_NOT_PROVISIONED: Bearer service not provisioned.
+ * @QMI_VOICE_CALL_END_REASON_TELE_SERVICE_NOT_PROVISIONED: Tele service not provisioned.
+ * @QMI_VOICE_CALL_END_REASON_ILLEGAL_EQUIPMENT: Illegal equipment.
+ * @QMI_VOICE_CALL_END_REASON_CALL_BARRED: Call barred.
+ * @QMI_VOICE_CALL_END_REASON_ILLEGAL_SS_OPERATION: Illegal SS operation.
+ * @QMI_VOICE_CALL_END_REASON_SS_ERROR_STATUS: Supplementary service error status.
+ * @QMI_VOICE_CALL_END_REASON_SS_NOT_AVAILABLE: Supplementary service not available.
+ * @QMI_VOICE_CALL_END_REASON_SS_SUBSCRIPTION_VIOLATION: Supplementary service subscription violation.
+ * @QMI_VOICE_CALL_END_REASON_SS_INCOMPATIBILITY: Supplementary service incompatibility.
+ * @QMI_VOICE_CALL_END_REASON_FACILITY_NOT_SUPPORTED: Facility not supported.
+ * @QMI_VOICE_CALL_END_REASON_ABSENT_SUBSCRIBER: Absent subscriber.
+ * @QMI_VOICE_CALL_END_REASON_SHORT_TERM_DENIAL: Short term denial.
+ * @QMI_VOICE_CALL_END_REASON_LONG_TERM_DENIAL: Long term denial.
+ * @QMI_VOICE_CALL_END_REASON_SYSTEM_FAILURE: System failure.
+ * @QMI_VOICE_CALL_END_REASON_DATA_MISSING: Data missing.
+ * @QMI_VOICE_CALL_END_REASON_UNEXPECTED_DATA_VALUE: Unexpected data value.
+ * @QMI_VOICE_CALL_END_REASON_PASSWORD_REGISTRATION_FAILURE: Password registration failure.
+ * @QMI_VOICE_CALL_END_REASON_NEGATIVE_PASSWORD_CHECK: Negative password check.
+ * @QMI_VOICE_CALL_END_REASON_NUM_OF_PASSWORD_ATTEMPTS_VIOLATION: Number of password attempts violation.
+ * @QMI_VOICE_CALL_END_REASON_POSITION_METHOD_FAILURE: Position method failure.
+ * @QMI_VOICE_CALL_END_REASON_UNKNOWN_ALPHABET: Unknown alphabet.
+ * @QMI_VOICE_CALL_END_REASON_USSD_BUSY: USSD busy.
+ * @QMI_VOICE_CALL_END_REASON_REJECTED_BY_USER: Rejected by user.
+ * @QMI_VOICE_CALL_END_REASON_REJECTED_BY_NETWORK: Rejected by network.
+ * @QMI_VOICE_CALL_END_REASON_DEFLECTION_TO_SERVED_SUBSCRIBER: Deflection to served subscriber.
+ * @QMI_VOICE_CALL_END_REASON_SPECIAL_SERVICE_CODE: Special service codde.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_DEFLECTED_TO_NUMBER: Invalid deflected to number.
+ * @QMI_VOICE_CALL_END_REASON_MULTIPARTY_PARTICIPANTS_EXCEEDED: Multiparty participants exceeded.
+ * @QMI_VOICE_CALL_END_REASON_RESOURCES_NOT_AVAILABLE: Resources not available.
+ * @QMI_VOICE_CALL_END_REASON_UNASSIGNED_NUMBER: Unassigned number.
+ * @QMI_VOICE_CALL_END_REASON_NO_ROUTE_TO_DESTINATION: No route to destination.
+ * @QMI_VOICE_CALL_END_REASON_CHANNEL_UNACCEPTABLE: Channel unacceptable.
+ * @QMI_VOICE_CALL_END_REASON_OPERATOR_DETERMINED_BARRING: Operator determined barring.
+ * @QMI_VOICE_CALL_END_REASON_NORMAL_CALL_CLEARING: Normal call clearing.
+ * @QMI_VOICE_CALL_END_REASON_USER_BUSY: User busy.
+ * @QMI_VOICE_CALL_END_REASON_NO_USER_RESPONDING: No user responding.
+ * @QMI_VOICE_CALL_END_REASON_USER_ALERTING_NO_ANSWER: User alerting no answer.
+ * @QMI_VOICE_CALL_END_REASON_CALL_REJECTED: Call rejected.
+ * @QMI_VOICE_CALL_END_REASON_NUMBER_CHANGED: Number changed.
+ * @QMI_VOICE_CALL_END_REASON_PREEMPTION: Preemption.
+ * @QMI_VOICE_CALL_END_REASON_DESTINATION_OUT_OF_ORDER: Destination out of order.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_NUMBER_FORMAT: Invalid number format.
+ * @QMI_VOICE_CALL_END_REASON_FACILITY_REJECTED: Facility rejected.
+ * @QMI_VOICE_CALL_END_REASON_RESPONSE_TO_STATUS_ENQUIRY: Response to status enquiry.
+ * @QMI_VOICE_CALL_END_REASON_NORMAL_UNSPECIFIED: Normal unspecified.
+ * @QMI_VOICE_CALL_END_REASON_NO_CIRCUIT_OR_CHANNEL_AVAILABLE: No circuit or channel available.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_OUT_OF_ORDER: Network out of order.
+ * @QMI_VOICE_CALL_END_REASON_TEMPORARY_FAILURE: Temporary failure.
+ * @QMI_VOICE_CALL_END_REASON_SWITCHING_EQUIPMENT_CONGESTION: Switching equipment congestion.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_INFORMATION_DISCARDED: Access information discarded.
+ * @QMI_VOICE_CALL_END_REASON_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE: Requested circuit or channel not available.
+ * @QMI_VOICE_CALL_END_REASON_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED: Resources unavailable or unspecified.
+ * @QMI_VOICE_CALL_END_REASON_QOS_UNAVAILABLE: QoS unavailable.
+ * @QMI_VOICE_CALL_END_REASON_REQUESTED_FACILITY_NOT_SUBSCRIBED: Requested facility not subscribed.
+ * @QMI_VOICE_CALL_END_REASON_INCOMING_CALLS_BARRED_WITHIN_CUG: Incoming calls barred withing closed user group.
+ * @QMI_VOICE_CALL_END_REASON_BEARER_CAPABILITY_NOT_AUTH: Bearer capability not auth.
+ * @QMI_VOICE_CALL_END_REASON_BEARER_CAPABILITY_UNAVAILABLE: Bearer capability unavailable.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_OPTION_NOT_AVAILABLE: Service option not available.
+ * @QMI_VOICE_CALL_END_REASON_ACM_LIMIT_EXCEEDED: ACM limit exceeded.
+ * @QMI_VOICE_CALL_END_REASON_BEARER_SERVICE_NOT_IMPLEMENTED: Bearer service not implemented.
+ * @QMI_VOICE_CALL_END_REASON_REQUESTED_FACILITY_NOT_IMPLEMENTED: Requested facility not implemented.
+ * @QMI_VOICE_CALL_END_REASON_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE: Only digital information bearer available.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_OR_OPTION_NOT_IMPLEMENTED: Service or option not implemented.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_TRANSACTION_IDENTIFIER: Invalid transaction identifier.
+ * @QMI_VOICE_CALL_END_REASON_USER_NOT_MEMBER_OF_CUG: User not member of closed user group.
+ * @QMI_VOICE_CALL_END_REASON_INCOMPATIBLE_DESTINATION: Incompatible destination.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_TRANSIT_NETWORK_SELECTION: Invalid transit network selection.
+ * @QMI_VOICE_CALL_END_REASON_SEMANTICALLY_INCORRECT_MESSAGE: Semantically incorrect message.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_MANDATORY_INFORMATION: Invalid mandatory information.
+ * @QMI_VOICE_CALL_END_REASON_MESSAGE_TYPE_NOT_IMPLEMENTED: Message type not implemented.
+ * @QMI_VOICE_CALL_END_REASON_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message type not compatible with protocol state.
+ * @QMI_VOICE_CALL_END_REASON_INFORMATION_ELEMENT_NON_EXISTENT: Information element non existent.
+ * @QMI_VOICE_CALL_END_REASON_CONDITIONAL_IE_ERROR: IE error.
+ * @QMI_VOICE_CALL_END_REASON_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message not compatible with protocol state.
+ * @QMI_VOICE_CALL_END_REASON_RECOVERY_ON_TIMER_EXPIRED: Recovery on timer expired.
+ * @QMI_VOICE_CALL_END_REASON_PROTOCOL_ERROR_UNSPECIFIED: Protocol error unspecified.
+ * @QMI_VOICE_CALL_END_REASON_INTERWORKING_UNSPECIFIED: Interworking unspecified.
+ * @QMI_VOICE_CALL_END_REASON_OUTGOING_CALLS_BARRED_WITHIN_CUG: Outgoing calls barred within closed user group.
+ * @QMI_VOICE_CALL_END_REASON_NO_CUG_SELECTION: No closed user group selection.
+ * @QMI_VOICE_CALL_END_REASON_UNKNOWN_CUG_INDEX: Unknown closed user group index.
+ * @QMI_VOICE_CALL_END_REASON_CUG_INDEX_INCOMPATIBLE: Closed user group index incompatible.
+ * @QMI_VOICE_CALL_END_REASON_CUG_CALL_FAILURE_UNSPECIFIED: Closed user group call failure unspecified.
+ * @QMI_VOICE_CALL_END_REASON_CLIR_NOT_SUBSCRIBED: Calling line identification restriction not subscribed.
+ * @QMI_VOICE_CALL_END_REASON_CCBS_POSSIBLE: Completion of communications to busy subscriber possible.
+ * @QMI_VOICE_CALL_END_REASON_CCBS_NOT_POSSIBLE: Completion of communications to busy subscriber not possible.
+ * @QMI_VOICE_CALL_END_REASON_IMSI_UNKNOWN_IN_HLR: IMSI unknown in HLR.
+ * @QMI_VOICE_CALL_END_REASON_ILLEGAL_MS: Illegal MS.
+ * @QMI_VOICE_CALL_END_REASON_IMSI_UNKNOWN_IN_VLR: IMSI unknown in VLR.
+ * @QMI_VOICE_CALL_END_REASON_IMEI_NOT_ACCEPTED: IMEI not accepted.
+ * @QMI_VOICE_CALL_END_REASON_ILLEGAL_ME: Illegal ME.
+ * @QMI_VOICE_CALL_END_REASON_PLMN_NOT_ALLOWED: PLMN not allowed.
+ * @QMI_VOICE_CALL_END_REASON_LOCATION_AREA_NOT_ALLOWED: Location area not allowed.
+ * @QMI_VOICE_CALL_END_REASON_ROAMING_NOT_ALLOWED_IN_THIS_LOCATION_AREA: Roaming not allowed in this location area.
+ * @QMI_VOICE_CALL_END_REASON_NO_SUITABLE_CELLS_IN_LOCATION_AREA: No suitable cells in location area.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_FAILURE: Network failure.
+ * @QMI_VOICE_CALL_END_REASON_MAC_FAILURE: MAC failure.
+ * @QMI_VOICE_CALL_END_REASON_SYNCH_FAILURE: Synch failure.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_CONGESTION: Network contestion.
+ * @QMI_VOICE_CALL_END_REASON_GSM_AUTHENTICATION_UNACCEPTABLE: GSM authentication unacceptable.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_NOT_SUBSCRIBED: Service not subscribed.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_TEMPORARILY_OUT_OF_ORDER: Service temporarily out of order.
+ * @QMI_VOICE_CALL_END_REASON_CALL_CANNOT_BE_IDENTIFIED: Call cannot be identified.
+ * @QMI_VOICE_CALL_END_REASON_INCORRECT_SEMANTICS_IN_MESSAGE: Incorrect semantics in message.
+ * @QMI_VOICE_CALL_END_REASON_MANDATORY_INFORMATION_INVALID: Mandatory information invalid.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_FAILURE: Access stratum failure.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_SIM: Invalid SIM.
+ * @QMI_VOICE_CALL_END_REASON_WRONG_STATE: Wrong state.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_CLASS_BLOCKED: Access class blocked.
+ * @QMI_VOICE_CALL_END_REASON_NO_RESOURCES: No resources.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_USER_DATA: Invalid user data.
+ * @QMI_VOICE_CALL_END_REASON_TIMER_T3230_EXPIRED: Timer T3230 expired.
+ * @QMI_VOICE_CALL_END_REASON_NO_CELL_AVAILABLE: No cell available.
+ * @QMI_VOICE_CALL_END_REASON_ABORT_MESSAGE_RECEIVED: Abort message received.
+ * @QMI_VOICE_CALL_END_REASON_RADIO_LINK_LOST: Radio link lost.
+ * @QMI_VOICE_CALL_END_REASON_TIMER_T303_EXPIRED: Timer T303 expired.
+ * @QMI_VOICE_CALL_END_REASON_CNM_MM_RELEASE_PENDING: CNM MM release pending.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RR_RELEASE_INDICATION: Access stratum reject, RR release indication.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RR_RANDOM_ACCESS_FAILURE: Access stratum reject, RR random access failure.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_RELEASE_INDICATION: Access stratum reject, RRC release indication.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_CLOSE_SESSION_INDICATION: Access stratum reject, RRC close session indication.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_OPEN_SESSION_FAILURE: Access stratum reject, RRC open session failure.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_FAILURE: Access stratum reject, low level failure.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_FAILURE_REDIAL_NOT_ALLOWED: Access stratum reject, low level failure redial not allowed.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_IMMEDIATE_RETRY: Access stratum reject, low level immediate retry.
+ * @QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_ABORT_RADIO_UNAVAILABLE: Access stratum reject, abort radio unavailable.
+ * @QMI_VOICE_CALL_END_REASON_SERVICE_OPTION_NOT_SUPPORTED: Service option not supported.
+ * @QMI_VOICE_CALL_END_REASON_BAD_REQUEST_WAIT_INVITE: Bad request wait invite.
+ * @QMI_VOICE_CALL_END_REASON_BAD_REQUEST_WAIT_REINVITE: Bad request wait reinvite.
+ * @QMI_VOICE_CALL_END_REASON_INVALID_REMOTE_URI: Invalid remote URI.
+ * @QMI_VOICE_CALL_END_REASON_REMOTE_UNSUPPORTED_MEDIA_TYPE: Remote unsupported media type.
+ * @QMI_VOICE_CALL_END_REASON_PEER_NOT_REACHABLE: Peer not reachable.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_NO_RESPONSE_TIMEOUT: Network no response, timeout.
+ * @QMI_VOICE_CALL_END_REASON_NETWORK_NO_RESPONSE_HOLD_FAILURE: Network no response, hold failure.
+ * @QMI_VOICE_CALL_END_REASON_DATA_CONNECTION_LOST: Data connection lost.
+ * @QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_REJECTED: Upgrade/downgrade rejected.
+ * @QMI_VOICE_CALL_END_REASON_SIP_403_FORBIDDEN: SIP 403 forbidden.
+ * @QMI_VOICE_CALL_END_REASON_NO_NETWORK_RESPONSE: No network response.
+ * @QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_FAILED: Upgrade/downgrade failed.
+ * @QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_CANCELLED: Upgrade/downgrade cancelled.
+ * @QMI_VOICE_CALL_END_REASON_SSAC_REJECT: Service specific access control reject.
+ * @QMI_VOICE_CALL_END_REASON_THERMAL_EMERGENCY: Thermal emergency.
+ * @QMI_VOICE_CALL_END_REASON_1XCSFB_SOFT_FAILURE: 1xCSFG soft failure.
+ * @QMI_VOICE_CALL_END_REASON_1XCSFB_HARD_FAILURE: 1xCSFG hard failure.
+ *
+ * Possible call end reasons resulting from a voice call or supplementary
+ * service connection being terminated.
+ *
+ * Since: 1.26
+ */
+typedef enum {
+    QMI_VOICE_CALL_END_REASON_OFFLINE                            = 0,
+    QMI_VOICE_CALL_END_REASON_CDMA_LOCK                          = 20,
+    QMI_VOICE_CALL_END_REASON_NO_SERVICE                         = 21,
+    QMI_VOICE_CALL_END_REASON_FADE                               = 22,
+    QMI_VOICE_CALL_END_REASON_INTERCEPT                          = 23,
+    QMI_VOICE_CALL_END_REASON_REORDER                            = 24,
+    QMI_VOICE_CALL_END_REASON_RELEASE_NORMAL                     = 25,
+    QMI_VOICE_CALL_END_REASON_RELEASE_SO_REJECT                  = 26,
+    QMI_VOICE_CALL_END_REASON_INCOMING_CALL                      = 27,
+    QMI_VOICE_CALL_END_REASON_ALERT_STOP                         = 28,
+    QMI_VOICE_CALL_END_REASON_CLIENT_END                         = 29,
+    QMI_VOICE_CALL_END_REASON_ACTIVATION                         = 30,
+    QMI_VOICE_CALL_END_REASON_MC_ABORT                           = 31,
+    QMI_VOICE_CALL_END_REASON_MAX_ACCESS_PROBE                   = 32,
+    QMI_VOICE_CALL_END_REASON_PSIST_N                            = 33,
+    QMI_VOICE_CALL_END_REASON_UIM_NOT_PRESENT                    = 34,
+    QMI_VOICE_CALL_END_REASON_ACCESS_ATTEMPT_IN_PROGRESS         = 35,
+    QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE                     = 36,
+    QMI_VOICE_CALL_END_REASON_ACCESS_RETRY_ORDER                 = 37,
+    QMI_VOICE_CALL_END_REASON_CCS_NOT_SUPPORTED_BY_BS            = 38,
+    QMI_VOICE_CALL_END_REASON_NO_RESPONSE_FROM_BS                = 39,
+    QMI_VOICE_CALL_END_REASON_REJECTED_BY_BS                     = 40,
+    QMI_VOICE_CALL_END_REASON_INCOMPATIBLE                       = 41,
+    QMI_VOICE_CALL_END_REASON_ACCESS_BLOCK                       = 42,
+    QMI_VOICE_CALL_END_REASON_ALREADY_IN_TC                      = 43,
+    QMI_VOICE_CALL_END_REASON_EMERGENCY_FLASHED                  = 44,
+    QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_GPS    = 45,
+    QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_SMS    = 46,
+    QMI_VOICE_CALL_END_REASON_USER_CALL_ORIGINATED_DURING_DATA   = 47,
+    QMI_VOICE_CALL_END_REASON_REDIRECTION_OR_HANDOFF             = 48,
+    QMI_VOICE_CALL_END_REASON_ACCESS_BLOCK_ALL                   = 49,
+    QMI_VOICE_CALL_END_REASON_OTASP_SPC_ERR                      = 50,
+    QMI_VOICE_CALL_END_REASON_IS707B_MAX_ACCESS_PROBES           = 51,
+    QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE_REJECT_ORDER        = 52,
+    QMI_VOICE_CALL_END_REASON_ACCESS_FAILURE_RETRY_ORDER         = 53,
+    QMI_VOICE_CALL_END_REASON_TIMEOUT_T42                        = 54,
+    QMI_VOICE_CALL_END_REASON_TIMEOUT_T40                        = 55,
+    QMI_VOICE_CALL_END_REASON_SERVICE_INIT_FAILURE               = 56,
+    QMI_VOICE_CALL_END_REASON_TIMEOUT_T50                        = 57,
+    QMI_VOICE_CALL_END_REASON_TIMEOUT_T51                        = 58,
+    QMI_VOICE_CALL_END_REASON_RL_ACK_TIMEOUT                     = 59,
+    QMI_VOICE_CALL_END_REASON_BAD_FORWARD_LINK                   = 60,
+    QMI_VOICE_CALL_END_REASON_TRM_REQUEST_FAILED                 = 61,
+    QMI_VOICE_CALL_END_REASON_TIMEOUT_T41                        = 62,
+    QMI_VOICE_CALL_END_REASON_INCOMING_REJECTED                  = 102,
+    QMI_VOICE_CALL_END_REASON_SETUP_REJECTED                     = 103,
+    QMI_VOICE_CALL_END_REASON_NETWORK_END                        = 104,
+    QMI_VOICE_CALL_END_REASON_NO_FUNDS                           = 105,
+    QMI_VOICE_CALL_END_REASON_NO_GW_SERVICE                      = 106,
+    QMI_VOICE_CALL_END_REASON_NO_CDMA_SERVICE                    = 107,
+    QMI_VOICE_CALL_END_REASON_NO_FULL_SERVICE                    = 108,
+    QMI_VOICE_CALL_END_REASON_MAX_PS_CALLS                       = 109,
+    QMI_VOICE_CALL_END_REASON_UNKNOWN_SUBSCRIBER                 = 110,
+    QMI_VOICE_CALL_END_REASON_ILLEGAL_SUBSCRIBER                 = 111,
+    QMI_VOICE_CALL_END_REASON_BEARER_SERVICE_NOT_PROVISIONED     = 112,
+    QMI_VOICE_CALL_END_REASON_TELE_SERVICE_NOT_PROVISIONED       = 113,
+    QMI_VOICE_CALL_END_REASON_ILLEGAL_EQUIPMENT                  = 114,
+    QMI_VOICE_CALL_END_REASON_CALL_BARRED                        = 115,
+    QMI_VOICE_CALL_END_REASON_ILLEGAL_SS_OPERATION               = 116,
+    QMI_VOICE_CALL_END_REASON_SS_ERROR_STATUS                    = 117,
+    QMI_VOICE_CALL_END_REASON_SS_NOT_AVAILABLE                   = 118,
+    QMI_VOICE_CALL_END_REASON_SS_SUBSCRIPTION_VIOLATION          = 119,
+    QMI_VOICE_CALL_END_REASON_SS_INCOMPATIBILITY                 = 120,
+    QMI_VOICE_CALL_END_REASON_FACILITY_NOT_SUPPORTED             = 121,
+    QMI_VOICE_CALL_END_REASON_ABSENT_SUBSCRIBER                  = 122,
+    QMI_VOICE_CALL_END_REASON_SHORT_TERM_DENIAL                  = 123,
+    QMI_VOICE_CALL_END_REASON_LONG_TERM_DENIAL                   = 124,
+    QMI_VOICE_CALL_END_REASON_SYSTEM_FAILURE                     = 125,
+    QMI_VOICE_CALL_END_REASON_DATA_MISSING                       = 126,
+    QMI_VOICE_CALL_END_REASON_UNEXPECTED_DATA_VALUE              = 127,
+    QMI_VOICE_CALL_END_REASON_PASSWORD_REGISTRATION_FAILURE      = 128,
+    QMI_VOICE_CALL_END_REASON_NEGATIVE_PASSWORD_CHECK            = 129,
+    QMI_VOICE_CALL_END_REASON_NUM_OF_PASSWORD_ATTEMPTS_VIOLATION = 130,
+    QMI_VOICE_CALL_END_REASON_POSITION_METHOD_FAILURE            = 131,
+    QMI_VOICE_CALL_END_REASON_UNKNOWN_ALPHABET                   = 132,
+    QMI_VOICE_CALL_END_REASON_USSD_BUSY                          = 133,
+    QMI_VOICE_CALL_END_REASON_REJECTED_BY_USER                   = 134,
+    QMI_VOICE_CALL_END_REASON_REJECTED_BY_NETWORK                = 135,
+    QMI_VOICE_CALL_END_REASON_DEFLECTION_TO_SERVED_SUBSCRIBER    = 136,
+    QMI_VOICE_CALL_END_REASON_SPECIAL_SERVICE_CODE               = 137,
+    QMI_VOICE_CALL_END_REASON_INVALID_DEFLECTED_TO_NUMBER        = 138,
+    QMI_VOICE_CALL_END_REASON_MULTIPARTY_PARTICIPANTS_EXCEEDED   = 139,
+    QMI_VOICE_CALL_END_REASON_RESOURCES_NOT_AVAILABLE            = 140,
+    QMI_VOICE_CALL_END_REASON_UNASSIGNED_NUMBER                  = 141,
+    QMI_VOICE_CALL_END_REASON_NO_ROUTE_TO_DESTINATION            = 142,
+    QMI_VOICE_CALL_END_REASON_CHANNEL_UNACCEPTABLE               = 143,
+    QMI_VOICE_CALL_END_REASON_OPERATOR_DETERMINED_BARRING        = 144,
+    QMI_VOICE_CALL_END_REASON_NORMAL_CALL_CLEARING               = 145,
+    QMI_VOICE_CALL_END_REASON_USER_BUSY                          = 146,
+    QMI_VOICE_CALL_END_REASON_NO_USER_RESPONDING                 = 147,
+    QMI_VOICE_CALL_END_REASON_USER_ALERTING_NO_ANSWER            = 148,
+    QMI_VOICE_CALL_END_REASON_CALL_REJECTED                      = 149,
+    QMI_VOICE_CALL_END_REASON_NUMBER_CHANGED                     = 150,
+    QMI_VOICE_CALL_END_REASON_PREEMPTION                         = 151,
+    QMI_VOICE_CALL_END_REASON_DESTINATION_OUT_OF_ORDER           = 152,
+    QMI_VOICE_CALL_END_REASON_INVALID_NUMBER_FORMAT              = 153,
+    QMI_VOICE_CALL_END_REASON_FACILITY_REJECTED                  = 154,
+    QMI_VOICE_CALL_END_REASON_RESPONSE_TO_STATUS_ENQUIRY         = 155,
+    QMI_VOICE_CALL_END_REASON_NORMAL_UNSPECIFIED                 = 156,
+    QMI_VOICE_CALL_END_REASON_NO_CIRCUIT_OR_CHANNEL_AVAILABLE    = 157,
+    QMI_VOICE_CALL_END_REASON_NETWORK_OUT_OF_ORDER               = 158,
+    QMI_VOICE_CALL_END_REASON_TEMPORARY_FAILURE                  = 159,
+    QMI_VOICE_CALL_END_REASON_SWITCHING_EQUIPMENT_CONGESTION     = 160,
+    QMI_VOICE_CALL_END_REASON_ACCESS_INFORMATION_DISCARDED       = 161,
+    QMI_VOICE_CALL_END_REASON_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE      = 162,
+    QMI_VOICE_CALL_END_REASON_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED            = 163,
+    QMI_VOICE_CALL_END_REASON_QOS_UNAVAILABLE                                 = 164,
+    QMI_VOICE_CALL_END_REASON_REQUESTED_FACILITY_NOT_SUBSCRIBED               = 165,
+    QMI_VOICE_CALL_END_REASON_INCOMING_CALLS_BARRED_WITHIN_CUG                = 166,
+    QMI_VOICE_CALL_END_REASON_BEARER_CAPABILITY_NOT_AUTH                      = 167,
+    QMI_VOICE_CALL_END_REASON_BEARER_CAPABILITY_UNAVAILABLE                   = 168,
+    QMI_VOICE_CALL_END_REASON_SERVICE_OPTION_NOT_AVAILABLE                    = 169,
+    QMI_VOICE_CALL_END_REASON_ACM_LIMIT_EXCEEDED                              = 170,
+    QMI_VOICE_CALL_END_REASON_BEARER_SERVICE_NOT_IMPLEMENTED                  = 171,
+    QMI_VOICE_CALL_END_REASON_REQUESTED_FACILITY_NOT_IMPLEMENTED              = 172,
+    QMI_VOICE_CALL_END_REASON_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE       = 173,
+    QMI_VOICE_CALL_END_REASON_SERVICE_OR_OPTION_NOT_IMPLEMENTED               = 174,
+    QMI_VOICE_CALL_END_REASON_INVALID_TRANSACTION_IDENTIFIER                  = 175,
+    QMI_VOICE_CALL_END_REASON_USER_NOT_MEMBER_OF_CUG                          = 176,
+    QMI_VOICE_CALL_END_REASON_INCOMPATIBLE_DESTINATION                        = 177,
+    QMI_VOICE_CALL_END_REASON_INVALID_TRANSIT_NETWORK_SELECTION               = 178,
+    QMI_VOICE_CALL_END_REASON_SEMANTICALLY_INCORRECT_MESSAGE                  = 179,
+    QMI_VOICE_CALL_END_REASON_INVALID_MANDATORY_INFORMATION                   = 180,
+    QMI_VOICE_CALL_END_REASON_MESSAGE_TYPE_NOT_IMPLEMENTED                    = 181,
+    QMI_VOICE_CALL_END_REASON_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 182,
+    QMI_VOICE_CALL_END_REASON_INFORMATION_ELEMENT_NON_EXISTENT                = 183,
+    QMI_VOICE_CALL_END_REASON_CONDITIONAL_IE_ERROR                            = 184,
+    QMI_VOICE_CALL_END_REASON_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE      = 185,
+    QMI_VOICE_CALL_END_REASON_RECOVERY_ON_TIMER_EXPIRED          = 186,
+    QMI_VOICE_CALL_END_REASON_PROTOCOL_ERROR_UNSPECIFIED         = 187,
+    QMI_VOICE_CALL_END_REASON_INTERWORKING_UNSPECIFIED           = 188,
+    QMI_VOICE_CALL_END_REASON_OUTGOING_CALLS_BARRED_WITHIN_CUG   = 189,
+    QMI_VOICE_CALL_END_REASON_NO_CUG_SELECTION                   = 190,
+    QMI_VOICE_CALL_END_REASON_UNKNOWN_CUG_INDEX                  = 191,
+    QMI_VOICE_CALL_END_REASON_CUG_INDEX_INCOMPATIBLE             = 192,
+    QMI_VOICE_CALL_END_REASON_CUG_CALL_FAILURE_UNSPECIFIED       = 193,
+    QMI_VOICE_CALL_END_REASON_CLIR_NOT_SUBSCRIBED                = 194,
+    QMI_VOICE_CALL_END_REASON_CCBS_POSSIBLE                      = 195,
+    QMI_VOICE_CALL_END_REASON_CCBS_NOT_POSSIBLE                  = 196,
+    QMI_VOICE_CALL_END_REASON_IMSI_UNKNOWN_IN_HLR                = 197,
+    QMI_VOICE_CALL_END_REASON_ILLEGAL_MS                         = 198,
+    QMI_VOICE_CALL_END_REASON_IMSI_UNKNOWN_IN_VLR                = 199,
+    QMI_VOICE_CALL_END_REASON_IMEI_NOT_ACCEPTED                  = 200,
+    QMI_VOICE_CALL_END_REASON_ILLEGAL_ME                         = 201,
+    QMI_VOICE_CALL_END_REASON_PLMN_NOT_ALLOWED                   = 202,
+    QMI_VOICE_CALL_END_REASON_LOCATION_AREA_NOT_ALLOWED          = 203,
+    QMI_VOICE_CALL_END_REASON_ROAMING_NOT_ALLOWED_IN_THIS_LOCATION_AREA = 204,
+    QMI_VOICE_CALL_END_REASON_NO_SUITABLE_CELLS_IN_LOCATION_AREA = 205,
+    QMI_VOICE_CALL_END_REASON_NETWORK_FAILURE                    = 206,
+    QMI_VOICE_CALL_END_REASON_MAC_FAILURE                        = 207,
+    QMI_VOICE_CALL_END_REASON_SYNCH_FAILURE                      = 208,
+    QMI_VOICE_CALL_END_REASON_NETWORK_CONGESTION                 = 209,
+    QMI_VOICE_CALL_END_REASON_GSM_AUTHENTICATION_UNACCEPTABLE    = 210,
+    QMI_VOICE_CALL_END_REASON_SERVICE_NOT_SUBSCRIBED             = 211,
+    QMI_VOICE_CALL_END_REASON_SERVICE_TEMPORARILY_OUT_OF_ORDER   = 212,
+    QMI_VOICE_CALL_END_REASON_CALL_CANNOT_BE_IDENTIFIED          = 213,
+    QMI_VOICE_CALL_END_REASON_INCORRECT_SEMANTICS_IN_MESSAGE     = 214,
+    QMI_VOICE_CALL_END_REASON_MANDATORY_INFORMATION_INVALID      = 215,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_FAILURE             = 216,
+    QMI_VOICE_CALL_END_REASON_INVALID_SIM                        = 217,
+    QMI_VOICE_CALL_END_REASON_WRONG_STATE                        = 218,
+    QMI_VOICE_CALL_END_REASON_ACCESS_CLASS_BLOCKED               = 219,
+    QMI_VOICE_CALL_END_REASON_NO_RESOURCES                       = 220,
+    QMI_VOICE_CALL_END_REASON_INVALID_USER_DATA                  = 221,
+    QMI_VOICE_CALL_END_REASON_TIMER_T3230_EXPIRED                = 222,
+    QMI_VOICE_CALL_END_REASON_NO_CELL_AVAILABLE                  = 223,
+    QMI_VOICE_CALL_END_REASON_ABORT_MESSAGE_RECEIVED             = 224,
+    QMI_VOICE_CALL_END_REASON_RADIO_LINK_LOST                    = 225,
+    QMI_VOICE_CALL_END_REASON_TIMER_T303_EXPIRED                 = 226,
+    QMI_VOICE_CALL_END_REASON_CNM_MM_RELEASE_PENDING             = 227,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RR_RELEASE_INDICATION                = 228,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RR_RANDOM_ACCESS_FAILURE             = 229,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_RELEASE_INDICATION               = 230,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_CLOSE_SESSION_INDICATION         = 231,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_RRC_OPEN_SESSION_FAILURE             = 232,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_FAILURE                    = 233,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_FAILURE_REDIAL_NOT_ALLOWED = 234,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_LOW_LEVEL_IMMEDIATE_RETRY            = 235,
+    QMI_VOICE_CALL_END_REASON_ACCESS_STRATUM_REJECT_ABORT_RADIO_UNAVAILABLE              = 236,
+    QMI_VOICE_CALL_END_REASON_SERVICE_OPTION_NOT_SUPPORTED       = 237,
+    QMI_VOICE_CALL_END_REASON_BAD_REQUEST_WAIT_INVITE            = 300,
+    QMI_VOICE_CALL_END_REASON_BAD_REQUEST_WAIT_REINVITE          = 301,
+    QMI_VOICE_CALL_END_REASON_INVALID_REMOTE_URI                 = 302,
+    QMI_VOICE_CALL_END_REASON_REMOTE_UNSUPPORTED_MEDIA_TYPE      = 303,
+    QMI_VOICE_CALL_END_REASON_PEER_NOT_REACHABLE                 = 304,
+    QMI_VOICE_CALL_END_REASON_NETWORK_NO_RESPONSE_TIMEOUT        = 305,
+    QMI_VOICE_CALL_END_REASON_NETWORK_NO_RESPONSE_HOLD_FAILURE   = 306,
+    QMI_VOICE_CALL_END_REASON_DATA_CONNECTION_LOST               = 307,
+    QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_REJECTED         = 308,
+    QMI_VOICE_CALL_END_REASON_SIP_403_FORBIDDEN                  = 309,
+    QMI_VOICE_CALL_END_REASON_NO_NETWORK_RESPONSE                = 310,
+    QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_FAILED           = 311,
+    QMI_VOICE_CALL_END_REASON_UPGRADE_DOWNGRADE_CANCELLED        = 312,
+    QMI_VOICE_CALL_END_REASON_SSAC_REJECT                        = 313,
+    QMI_VOICE_CALL_END_REASON_THERMAL_EMERGENCY                  = 314,
+    QMI_VOICE_CALL_END_REASON_1XCSFB_SOFT_FAILURE                = 315,
+    QMI_VOICE_CALL_END_REASON_1XCSFB_HARD_FAILURE                = 316,
+} QmiVoiceCallEndReason;
+
+/**
+ * qmi_voice_call_end_reason_get_string:
+ *
+ * Since: 1.26
+ */
+
+/**
+ * QmiVoiceCallControlResultType:
+ * @QMI_VOICE_CALL_CONTROL_RESULT_TYPE_VOICE: Voice.
+ * @QMI_VOICE_CALL_CONTROL_RESULT_TYPE_SUPS: Supplementary service.
+ * @QMI_VOICE_CALL_CONTROL_RESULT_TYPE_USSD: Unstructured supplementary service.
+ *
+ * Call control result type.
+ *
+ * Since: 1.26
+ */
+typedef enum {
+    QMI_VOICE_CALL_CONTROL_RESULT_TYPE_VOICE = 0x00,
+    QMI_VOICE_CALL_CONTROL_RESULT_TYPE_SUPS  = 0x01,
+    QMI_VOICE_CALL_CONTROL_RESULT_TYPE_USSD  = 0x02,
+} QmiVoiceCallControlResultType;
+
+/**
+ * qmi_voice_call_control_result_type_get_string:
+ *
+ * Since: 1.26
+ */
+
+/**
+ * QmiVoiceCallControlSupplementaryServiceType:
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_ACTIVATE: Activate.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_DEACTIVATE: Deactivate.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_REGISTER: Register.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_ERASE: Erase.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_INTERROGATE: Interrogate.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_REGISTER_PASSWORD: Register password.
+ * @QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_USSD: USSD.
+ *
+ * Call control supplementary service type.
+ *
+ * Since: 1.26
+ */
+typedef enum {
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_ACTIVATE          = 0x01,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_DEACTIVATE        = 0x02,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_REGISTER          = 0x03,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_ERASE             = 0x04,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_INTERROGATE       = 0x05,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_REGISTER_PASSWORD = 0x06,
+    QMI_VOICE_CALL_CONTROL_SUPPLEMENTARY_SERVICE_TYPE_USSD              = 0x07,
+} QmiVoiceCallControlSupplementaryServiceType;
+
+/**
+ * qmi_voice_call_control_supplementary_service_type_get_string:
+ *
+ * Since: 1.26
+ */
+
 #endif /* _LIBQMI_GLIB_QMI_ENUMS_VOICE_H_ */
diff --git a/src/libqmi-glib/qmi-enums-wds.h b/src/libqmi-glib/qmi-enums-wds.h
index 9bf08fd..4ef84f7 100644
--- a/src/libqmi-glib/qmi-enums-wds.h
+++ b/src/libqmi-glib/qmi-enums-wds.h
@@ -450,6 +450,32 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MPIT_EXPIRED: MPIT expired. Since: 1.14.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IPV6_ADDRESS_TRANSFER_FAILED: IPv6 address transfer failed. Since: 1.14.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_TRAT_SWAP_FAILED: TRAT swap failed. Since: 1.14.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_EHRPD_TO_HRPD_FALLBACK: eHRPD to HRPD fallback. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MANDATORY_APN_DISABLED: Mandatory APN disabled. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MIP_CONFIG_FAILURE: MIP config failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_PDN_INACTIVITY_TIMER_EXPIRED: PDN inactivity timeout expired. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MAX_V4_CONNECTIONS: Max IPv4 connections. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MAX_V6_CONNECTIONS: Max IPv6 connections. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_MISMATCH: APN mismatch. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IP_VERSION_MISMATCH: IP version mismatch. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DUN_CALL_DISALLOWED: DUN call disallowed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INVALID_PROFILE: Invalid profile. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_EPC_NONEPC_TRANSITION: EPC to non-EPC transition. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INVALID_PROFILE_ID: Invalid profile ID. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CALL_ALREADY_PRESENT: Call already present. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INTERFACE_IN_USE: Interface in use. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IP_PDP_MISMATCH: IP PDP mismatch. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_DISALLOWED_ON_ROAMING: APN disallowed on roaming. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_PARAMETER_CHANGE: APN parameter change. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INTERFACE_IN_USE_CONFIG_MATCH: Interface in use config match. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_NULL_APN_DISALLOWED: NULL APN disallowed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_THERMAL_MITIGATION: Thermal mitigation. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_SUBS_ID_MISMATCH: Subs ID mismatch Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DATA_SETTINGS_DISABLED: Data settings disabled. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DATA_ROAMING_SETTINGS_DISABLED: Data roaming settings disabled. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_FORMAT_INVALID: APN format invalid. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DDS_CALL_ABORT: DDS call abort. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_VALIDATION_FAILURE: Validation failure. Since 1.24.10.
  *
  * Internal call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL.
  *
@@ -479,6 +505,32 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MPIT_EXPIRED                    = 221,
     QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IPV6_ADDRESS_TRANSFER_FAILED    = 222,
     QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_TRAT_SWAP_FAILED                = 223,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_EHRPD_TO_HRPD_FALLBACK          = 224,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MANDATORY_APN_DISABLED          = 225,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MIP_CONFIG_FAILURE              = 226,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_PDN_INACTIVITY_TIMER_EXPIRED    = 227,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MAX_V4_CONNECTIONS              = 228,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_MAX_V6_CONNECTIONS              = 229,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_MISMATCH                    = 230,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IP_VERSION_MISMATCH             = 231,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DUN_CALL_DISALLOWED             = 232,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INVALID_PROFILE                 = 233,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_EPC_NONEPC_TRANSITION           = 234,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INVALID_PROFILE_ID              = 235,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_CALL_ALREADY_PRESENT            = 236,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INTERFACE_IN_USE                = 237,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_IP_PDP_MISMATCH                 = 238,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_DISALLOWED_ON_ROAMING       = 239,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_PARAMETER_CHANGE            = 240,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_INTERFACE_IN_USE_CONFIG_MATCH   = 241,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_NULL_APN_DISALLOWED             = 242,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_THERMAL_MITIGATION              = 243,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_SUBS_ID_MISMATCH                = 244,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DATA_SETTINGS_DISABLED          = 245,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DATA_ROAMING_SETTINGS_DISABLED  = 246,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_APN_FORMAT_INVALID              = 247,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_DDS_CALL_ABORT                  = 248,
+    QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_VALIDATION_FAILURE              = 249,
 } QmiWdsVerboseCallEndReasonInternal;
 
 /**
@@ -505,8 +557,17 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_GPS: (CDMA) Call originated during GPS.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_SMS: (CDMA) Call originated during SMS.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_CDMA_SERVICE: (CDMA) No service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_MC_ABORT: MC abort. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_PSIST_NG: Persistence test failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_UIM_NOT_PRESENT: UIM not present. Since 1.24.10.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_RETRY_ORDER: Retry order.
- * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED: Configuration failed.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_BLOCK: Access blocked. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_BLOCK_ALL: Access blocked for all. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_IS707B_MAX_ACCESS_PROBES: Maximum access probes for IS-707B call. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_THERMAL_EMERGENCY: Thermal emergency. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CALL_ORIGINATION_THROTTLED: Call origination throttled. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED: Voice call originated and concurrent voice/data not supported. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFERENCE_FAILED: Conference failed. Since 1.24.10.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_REJECTED: Incoming rejected.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GATEWAY_SERVICE: No gateway service.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GPRS_CONTEXT: No GPRS context.
@@ -524,6 +585,59 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONGESTION: Congestion.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_PDP_CONTEXT_ACTIVATED: No PDP context activated.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_CLASS_DSAC_REJECTION: Access class DSAC rejection.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_PDP_ACTIVATE_MAX_RETRY_FAILED: Maximum retries failed to activate PDP context. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_RAB_FAILURE: RAB failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EPS_SERVICE_NOT_ALLOWED: EPS service not allowed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_TRACKING_AREA_NOT_ALLOWED: Tracking area not allowed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ROAMING_NOT_ALLOWED_IN_TRACKING_AREA: Roaming not allowed in tracking area. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SUITABLE_CELLS_IN_TRACKING_AREA: No suitable cells in tracking area. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NOT_AUTHORIZED_CLOSED_SUBSCRIBER_GROUP: Not authorized in closed subscriber group. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_UNKNOWN_EPS_BEARER_CONTEXT: EPS Session Management, unknown EPS bearer context. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_DRB_RELEASED_AT_RRC: DRB released at RRC. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NAS_SIGNAL_CONNECTION_RELEASED: NAS signal connection released. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_DETACHED: EPS Mobility Management, detached. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_ATTACH_FAILED: EPS Mobility Management, attach failed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_ATTACH_STARTED: EPS Mobility Management, attach started. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED: LTE NAS service request failed. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_ACTIVE_DEDICATED_BEARER_REACTIVATED_BY_NW: EPS Session Management, active dedicated bearer reactivated by network. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_LOWER_LAYER_FAILURE: EPS Session Management, lower layer failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_SYNC_UP_WITH_NW: EPS Session Management, sync up with network. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_NW_ACTIVATED_DEDICATED_BEARER_WITH_ID_OF_DEFAULT_BEARER: EPS Session Management, network activated dedicated bearer with id of default bearer. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_BAD_OTA_MESSAGE: EPS Session Management, bad OTA message. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_DS_REJECTED_CALL: EPS Session Management, DS rejected call. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT: EPS Session Management, context transferred due to IRAT. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_DS_EXPLICIT_DEACT: DS explicit deactivation. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_LOCAL_CAUSE_NONE: EPS Session Management, local cause none. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED_NO_THROTTLE: LTE NAS service request failed, no throttle. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACL_FAILURE: ACL failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED_DS_DISALLOW: LTE NAS service request failed, DS disallow. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_T3417_EXPIRED: EPS Mobility Management, T3417 expired. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_T3417_EXT_EXPIRED: EPS Mobility Management, T3417 ext expired. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_TXN: LTE Radio Resource Control, UL data confirmation failure, txn. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_HANDOVER: LTE Radio Resource Control, UL data confirmation failure, handover. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_CONN_REL: LTE Radio Resource Control, UL data confirmation failure, connection release. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_RLF: LTE Radio Resource Control, UL data confirmation failure, radio link failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_CTRL_NOT_CONN: LTE Radio Resource Control, UL data confirmation failure, ctrl not conn. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE: LTE Radio Resource Control, connection establishment failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_ABORTED: LTE Radio Resource Control, connection establishment failure, aborted. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_ACCESS_BARRED: LTE Radio Resource Control, connection establishment failure, access barred. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_CELL_RESELECTION: LTE Radio Resource Control, connection establishment failure, cell reselection. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_CONFIG_FAILURE: LTE Radio Resource Control, connection establishment failure, config failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_TIMER_EXPIRED: LTE Radio Resource Control, connection establishment failure, timer expired. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_LINK_FAILURE: LTE Radio Resource Control, connection establishment failure, link failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_NOT_CAMPED: LTE Radio Resource Control, connection establishment failure, not camped. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_SI_FAILURE: LTE Radio Resource Control, connection establishment failure, SI failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_REJECTED: LTE Radio Resource Control, connection establishment failure, rejected. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_NORMAL: LTE Radio Resource Control, connection release, normal. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_RLF: LTE Radio Resource Control, connection release, radio link failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_CRE_FAILURE: LTE Radio Resource Control, connection release, cre failure. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_OOS_DURING_CRE: LTE Radio Resource Control, connection release, oos during cre. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_ABORTED: LTE Radio Resource Control, connection release, aborted. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_SIB_READ_ERROR: LTE Radio Resource Control, connection release, SIB read error. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_DETACH_WITH_REATTACH_LTE_NW_DETACH: Detach with reattach LTE network detach. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_DETACH_WITHOUT_REATTACH_LTE_NW_DETACH: Detach without reattach LTE network detach. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_PROC_TIMEOUT: EPS Session Management, proc timeout. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_MESSAGE_EXCEED_MAX_L2_LIMIT: Message exceed max L2 limit. Since 1.24.10.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_GENERAL_OR_BUSY: (EV-DO) Received Connection Deny (General or Network busy).
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE: (EV-DO) Received Connection Deny (Billing or Authentication failure).
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CHANGE: (EV-DO) Change HDR.
@@ -532,7 +646,13 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ORIGINATION_DURING_GPS_FIX: (EV-DO) HDR call ended in favor of a GPS fix.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CONNECTION_SETUP_TIMEOUT: (EV-DO) Connection setup timeout.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_RELEASED_BY_CM: (EV-DO) Released HDR call by call manager.
- * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_HYBRID_HDR_SERVICE: (EV-DO) No hybrid HDR service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_COLLOCATED_ACQUISITION_FAILED: Failed to acquire co-located HDR for origination. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_OTASP_COMMIT_IN_PROGRESS: (EV-DO) OTASP commit in progress. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_HYBRID_SERVICE: (EV-DO) No hybrid HDR service.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_LOCK_GRANTED: (EV-DO) No lock granted. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HOLD_OTHER_IN_PROGRESS: (EV-DO) hold other in progress. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_FADE: (EV-DO) Fade. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ACCESS_FAILURE: (EV-DO) Access failure. Since 1.24.10.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CLIENT_END: Client end.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SERVICE: No service.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_FADE: Fade.
@@ -540,6 +660,13 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_ATTEMPT_IN_PROGRESS: Access attempt in progress.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_FAILURE: Access Failure.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_REDIRECTION_OR_HANDOFF: Redirection or handoff.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_OFFLINE: Offline. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMERGENCY_MODE: Emergency mode. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_PHONE_IN_USE: Phone in use. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INVALID_MODE: Invalid mode. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_INVALID_SIM_STATE: Invalid SIM state. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_COLLOCATED_HDR: No collocated HDR. Since 1.24.10.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_CM_CALL_CONTROL_REJECTED: Call control rejected. Since 1.24.10.
  *
  * Call manager specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_CM.
  *
@@ -562,9 +689,18 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_GPS = 513,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED_DURING_SMS = 514,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_CDMA_SERVICE                 = 515,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_MC_ABORT                        = 516,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_PSIST_NG                        = 517,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_UIM_NOT_PRESENT                 = 518,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_RETRY_ORDER                     = 519,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_BLOCK                    = 520,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_BLOCK_ALL                = 521,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_IS707B_MAX_ACCESS_PROBES        = 522,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_THERMAL_EMERGENCY               = 523,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_CALL_ORIGINATION_THROTTLED      = 524,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_USER_CALL_ORIGINATED            = 525,
 
-    QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFIGURATION_FAILED                   = 1000,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONFERENCE_FAILED                      = 1000,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_INCOMING_REJECTED                      = 1001,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GATEWAY_SERVICE                     = 1002,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_GPRS_CONTEXT                        = 1003,
@@ -582,6 +718,59 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONGESTION                             = 1015,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_PDP_CONTEXT_ACTIVATED               = 1016,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_CLASS_DSAC_REJECTION            = 1017,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_PDP_ACTIVATE_MAX_RETRY_FAILED          = 1018,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_RAB_FAILURE                            = 1019,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EPS_SERVICE_NOT_ALLOWED                = 1020,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_TRACKING_AREA_NOT_ALLOWED              = 1021,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ROAMING_NOT_ALLOWED_IN_TRACKING_AREA   = 1022,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SUITABLE_CELLS_IN_TRACKING_AREA     = 1023,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_NOT_AUTHORIZED_CLOSED_SUBSCRIBER_GROUP = 1024,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_UNKNOWN_EPS_BEARER_CONTEXT         = 1025,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_DRB_RELEASED_AT_RRC                    = 1026,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_NAS_SIGNAL_CONNECTION_RELEASED         = 1027,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_DETACHED                           = 1028,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_ATTACH_FAILED                      = 1029,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_ATTACH_STARTED                     = 1030,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED         = 1031,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_ACTIVE_DEDICATED_BEARER_REACTIVATED_BY_NW               = 1032,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_LOWER_LAYER_FAILURE                                     = 1033,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_SYNC_UP_WITH_NW                                         = 1034,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_NW_ACTIVATED_DEDICATED_BEARER_WITH_ID_OF_DEFAULT_BEARER = 1035,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_BAD_OTA_MESSAGE                                         = 1036,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_DS_REJECTED_CALL                                        = 1037,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT                         = 1038,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_DS_EXPLICIT_DEACT                                           = 1039,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_LOCAL_CAUSE_NONE                                        = 1040,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED_NO_THROTTLE                  = 1041,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACL_FAILURE                                                 = 1042,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LTE_NAS_SERVICE_REQUEST_FAILED_DS_DISALLOW                  = 1043,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_T3417_EXPIRED                                           = 1044,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMM_T3417_EXT_EXPIRED                                       = 1045,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_TXN                       = 1046,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_HANDOVER                  = 1047,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_CONN_REL                  = 1048,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_RLF                       = 1049,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_UL_DATA_CONFIRMATION_FAILURE_CTRL_NOT_CONN             = 1050,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE                       = 1051,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_ABORTED               = 1052,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_ACCESS_BARRED         = 1053,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_CELL_RESELECTION      = 1054,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_CONFIG_FAILURE        = 1055,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_TIMER_EXPIRED         = 1056,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_LINK_FAILURE          = 1057,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_NOT_CAMPED            = 1058,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_SI_FAILURE            = 1059,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_ESTABLISHMENT_FAILURE_REJECTED              = 1060,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_NORMAL         = 1061,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_RLF            = 1062,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_CRE_FAILURE    = 1063,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_OOS_DURING_CRE = 1064,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_ABORTED        = 1065,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_LRRC_CONNECTION_RELEASE_SIB_READ_ERROR = 1066,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_DETACH_WITH_REATTACH_LTE_NW_DETACH     = 1067,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_DETACH_WITHOUT_REATTACH_LTE_NW_DETACH  = 1068,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_ESM_PROC_TIMEOUT                       = 1069,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_MESSAGE_EXCEED_MAX_L2_LIMIT            = 1070,
 
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_GENERAL_OR_BUSY                   = 1500,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_CONNECTION_DENY_BILLING_OR_AUTHENTICATION_FAILURE = 1501,
@@ -591,7 +780,13 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ORIGINATION_DURING_GPS_FIX                    = 1505,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_CONNECTION_SETUP_TIMEOUT                      = 1506,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_RELEASED_BY_CM                                = 1507,
-    QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_HYBRID_HDR_SERVICE                             = 1510,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_COLLOCATED_ACQUISITION_FAILED                 = 1508,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_OTASP_COMMIT_IN_PROGRESS                          = 1509,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_HYBRID_SERVICE                             = 1510,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_NO_LOCK_GRANTED                               = 1511,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HOLD_OTHER_IN_PROGRESS                            = 1512,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_FADE                                          = 1513,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_HDR_ACCESS_FAILURE                                = 1514,
 
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_CLIENT_END                 = 2000,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_SERVICE                 = 2001,
@@ -599,7 +794,15 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_RELEASE_NORMAL             = 2003,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_ATTEMPT_IN_PROGRESS = 2004,
     QMI_WDS_VERBOSE_CALL_END_REASON_CM_ACCESS_FAILURE             = 2005,
-    QMI_WDS_VERBOSE_CALL_END_REASON_CM_REDIRECTION_OR_HANDOFF     = 2006
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_REDIRECTION_OR_HANDOFF     = 2006,
+
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_OFFLINE               = 2500,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_EMERGENCY_MODE        = 2501,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_PHONE_IN_USE          = 2502,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_INVALID_MODE          = 2503,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_INVALID_SIM_STATE     = 2504,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_NO_COLLOCATED_HDR     = 2505,
+    QMI_WDS_VERBOSE_CALL_END_REASON_CM_CALL_CONTROL_REJECTED = 2506,
 } QmiWdsVerboseCallEndReasonCm;
 
 /**
@@ -649,6 +852,7 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE: Message and protocol state uncompatible.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR: Protocol error.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT: APN type conflict.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_PROXY_CALL_SESSION_CONTROL_FUNCTION_ADDRESS: Invalid proxy call session control function address. Since 1.24.10.
  *
  * 3GPP-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP.
  *
@@ -697,8 +901,9 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_CONDITIONAL_IE_ERROR                    = 100,
     QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101,
 
-    QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR    = 111,
-    QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT = 112
+    QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR                                      = 111,
+    QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT                                   = 112,
+    QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_PROXY_CALL_SESSION_CONTROL_FUNCTION_ADDRESS = 113,
 } QmiWdsVerboseCallEndReason3gpp;
 
 /**
@@ -715,6 +920,7 @@
  * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_OPTION_MISMATCH: Option mismatch.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_PAP_FAILURE: PAP failure.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CHAP_FAILURE: CHAP failure.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CLOSE_IN_PROGRESS: Close in progress. Since 1.24.10.
  *
  * PPP-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_PPP.
  *
@@ -727,8 +933,10 @@
     QMI_WDS_VERBOSE_CALL_END_REASON_PPP_AUTHENTICATION_FAILURE = 2,
     QMI_WDS_VERBOSE_CALL_END_REASON_PPP_OPTION_MISMATCH        = 3,
 
-    QMI_WDS_VERBOSE_CALL_END_REASON_PPP_PAP_FAILURE  = 31,
-    QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CHAP_FAILURE = 32
+    QMI_WDS_VERBOSE_CALL_END_REASON_PPP_PAP_FAILURE       = 31,
+    QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CHAP_FAILURE      = 32,
+    QMI_WDS_VERBOSE_CALL_END_REASON_PPP_CLOSE_IN_PROGRESS = 33,
+
 } QmiWdsVerboseCallEndReasonPpp;
 
 /**
@@ -790,6 +998,7 @@
  * QmiWdsVerboseCallEndReasonIpv6:
  * @QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_PREFIX_UNAVAILABLE: Prefix unavailable.
  * @QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_HRPD_IPV6_DISABLED: HRDP IPv6 disabled.
+ * @QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_DISABLED: IPv6 disabled. Since 1.24.10.
  *
  * IPv6-specific call end reasons, given when the @QmiWdsVerboseCallEndReasonType is #QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_IPV6.
  *
@@ -797,7 +1006,8 @@
  */
 typedef enum {
     QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_PREFIX_UNAVAILABLE = 1,
-    QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_HRPD_IPV6_DISABLED = 2
+    QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_HRPD_IPV6_DISABLED = 2,
+    QMI_WDS_VERBOSE_CALL_END_REASON_IPV6_DISABLED           = 3,
 } QmiWdsVerboseCallEndReasonIpv6;
 
 /**
diff --git a/src/libqmi-glib/qmi-errors.h b/src/libqmi-glib/qmi-errors.h
index 65b9a68..a2a22ca 100644
--- a/src/libqmi-glib/qmi-errors.h
+++ b/src/libqmi-glib/qmi-errors.h
@@ -73,7 +73,7 @@
  * @QMI_CORE_ERROR_UNSUPPORTED: Not supported.
  * @QMI_CORE_ERROR_TLV_EMPTY: TLV has no value. Empty TLVs are not a real error, so this error type is never generated. Since: 1.12. Deprecated: 1.22.
  * @QMI_CORE_ERROR_UNEXPECTED_MESSAGE: QMI message is unexpected. Since: 1.16.
- * @QMI_CORE_ERROR_INVALID_DATA: Invalid data found in the message. Since: 1.26.
+ * @QMI_CORE_ERROR_INVALID_DATA: Invalid data found in the message. Since: 1.24.6.
  *
  * Common errors that may be reported by libqmi-glib.
  *
diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c
index 2938b14..80315e5 100644
--- a/src/libqmi-glib/qmi-message.c
+++ b/src/libqmi-glib/qmi-message.c
@@ -1326,7 +1326,7 @@
      * but hey, the strings read using this method should all really be ASCII-7
      * and we're trying to do our best to overcome modem firmware problems...
      */
-    if (g_utf8_validate ((const gchar *)ptr, valid_string_length, NULL)) {
+    if (__qmi_string_utf8_validate_printable (ptr, valid_string_length)) {
         *out = g_malloc (valid_string_length + 1);
         memcpy (*out, ptr, valid_string_length);
         (*out)[valid_string_length] = '\0';
@@ -1344,10 +1344,6 @@
         }
     }
 
-    *out = g_malloc (valid_string_length + 1);
-    memcpy (*out, ptr, valid_string_length);
-    (*out)[valid_string_length] = '\0';
-
     *offset = (*offset + string_length);
     return TRUE;
 }
@@ -1360,26 +1356,37 @@
                                         gchar       *out,
                                         GError     **error)
 {
+    const guint8 *ptr;
+    const gchar  *end = NULL;
+
     g_return_val_if_fail (self != NULL, FALSE);
     g_return_val_if_fail (offset != NULL, FALSE);
     g_return_val_if_fail (out != NULL, FALSE);
 
-    if (string_length > 0) {
-        const guint8 *ptr;
+    if (string_length == 0)
+        return TRUE;
 
-        if (!(ptr = tlv_error_if_read_overflow (self, tlv_offset, *offset, string_length, error)))
-            return FALSE;
+    if (!(ptr = tlv_error_if_read_overflow (self, tlv_offset, *offset, string_length, error)))
+        return FALSE;
 
-        if (!g_utf8_validate ((const gchar *)ptr, string_length, NULL)) {
-            g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_INVALID_DATA, "invalid string");
-            return FALSE;
-        }
-
+    /* full string valid? */
+    if (g_utf8_validate ((const gchar *)ptr, string_length, &end)) {
         memcpy (out, ptr, string_length);
+        *offset = (*offset + string_length);
+        return TRUE;
     }
 
-    *offset = (*offset + string_length);
-    return TRUE;
+    /* partial string valid? */
+    if (end && end > (const gchar *)ptr) {
+        /* copy only the valid bytes */
+        memcpy (out, ptr, end - (const gchar *)ptr);
+        /* but update offset with the full expected length */
+        *offset = (*offset + string_length);
+        return TRUE;
+    }
+
+    g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_INVALID_DATA, "invalid string");
+    return FALSE;
 }
 
 guint16
@@ -1621,52 +1628,84 @@
     contents = NULL;
     switch (qmi_message_get_service (self)) {
     case QMI_SERVICE_CTL:
+#if defined HAVE_QMI_SERVICE_CTL
         contents = __qmi_message_ctl_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_DMS:
+#if defined HAVE_QMI_SERVICE_DMS
         contents = __qmi_message_dms_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_WDS:
+#if defined HAVE_QMI_SERVICE_WDS
         contents = __qmi_message_wds_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_NAS:
+#if defined HAVE_QMI_SERVICE_NAS
         contents = __qmi_message_nas_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_WMS:
+#if defined HAVE_QMI_SERVICE_WMS
         contents = __qmi_message_wms_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_PDC:
+#if defined HAVE_QMI_SERVICE_PDC
         contents = __qmi_message_pdc_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_PDS:
+#if defined HAVE_QMI_SERVICE_PDS
         contents = __qmi_message_pds_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_PBM:
+#if defined HAVE_QMI_SERVICE_PBM
         contents = __qmi_message_pbm_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_UIM:
+#if defined HAVE_QMI_SERVICE_UIM
         contents = __qmi_message_uim_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_OMA:
+#if defined HAVE_QMI_SERVICE_OMA
         contents = __qmi_message_oma_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_GAS:
+#if defined HAVE_QMI_SERVICE_GAS
         contents = __qmi_message_gas_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_WDA:
+#if defined HAVE_QMI_SERVICE_WDA
         contents = __qmi_message_wda_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_VOICE:
+#if defined HAVE_QMI_SERVICE_VOICE
         contents = __qmi_message_voice_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_LOC:
+#if defined HAVE_QMI_SERVICE_LOC
         contents = __qmi_message_loc_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_QOS:
+#if defined HAVE_QMI_SERVICE_QOS
         contents = __qmi_message_qos_get_printable (self, context, line_prefix);
+#endif
         break;
     case QMI_SERVICE_DSD:
+#if defined HAVE_QMI_SERVICE_DSD
         contents = __qmi_message_dsd_get_printable (self, context, line_prefix);
+#endif
         break;
 
     case QMI_SERVICE_UNKNOWN:
@@ -1722,9 +1761,17 @@
 {
     switch (qmi_message_get_service (self)) {
     case QMI_SERVICE_WDS:
+#if defined HAVE_QMI_SERVICE_WDS
         return __qmi_message_wds_is_abortable (self, context);
+#else
+        return FALSE;
+#endif
     case QMI_SERVICE_NAS:
+#if defined HAVE_QMI_SERVICE_NAS
         return __qmi_message_nas_is_abortable (self, context);
+#else
+        return FALSE;
+#endif
 
     case QMI_SERVICE_UNKNOWN:
         g_assert_not_reached ();
diff --git a/src/libqmi-glib/qmi-message.h b/src/libqmi-glib/qmi-message.h
index d77723a..72f73e7 100644
--- a/src/libqmi-glib/qmi-message.h
+++ b/src/libqmi-glib/qmi-message.h
@@ -891,7 +891,7 @@
  * reading from within the TLV value (0 for the first item). If the variable
  * is successfully read, @offset will be updated to point past the read item.
  *
- * Since 1.26 the read string is guaranteed to be valid UTF-8. Also, in order to
+ * Since 1.24.6 the read string is guaranteed to be valid UTF-8. Also, in order to
  * overcome known firmware errors on string fields, this method will also
  * attempt to parse the string as GSM-7 or UCS-2 if the initial UTF-8 validation
  * fails.
@@ -925,7 +925,12 @@
  * reading from within the TLV value (0 for the first item). If the variable
  * is successfully read, @offset will be updated to point past the read item.
  *
- * Since 1.26 the read string is guaranteed to be valid UTF-8.
+ * Since 1.24.6 the read string is guaranteed to be valid UTF-8.
+ *
+ * The fixed sized field may be suffixed with e.g. 0xFF if the contents are
+ * shorter than @string_length. Since 1.26, this method will return the valid
+ * UTF-8 characters in the start of the string, instead of returning an error
+ * when doing the full UTF-8 string validation.
  *
  * Returns: %TRUE if the variable is successfully read, otherwise %FALSE is returned and @error is set.
  *
diff --git a/src/libqmi-glib/qmi-proxy.c b/src/libqmi-glib/qmi-proxy.c
index d3e3b6b..0fdf8b7 100644
--- a/src/libqmi-glib/qmi-proxy.c
+++ b/src/libqmi-glib/qmi-proxy.c
@@ -729,38 +729,35 @@
 
     self = client->proxy;
 
+    if (condition & G_IO_IN || condition & G_IO_PRI) {
+        r = g_input_stream_read (g_io_stream_get_input_stream (G_IO_STREAM (client->connection)),
+                                buffer,
+                                BUFFER_SIZE,
+                                NULL,
+                                &error);
+        if (r < 0) {
+            g_warning ("Error reading from istream: %s", error ? error->message : "unknown");
+            if (error)
+                g_error_free (error);
+            untrack_client (self, client);
+            return FALSE;
+        }
+
+        if (r > 0) {
+            if (!G_UNLIKELY (client->buffer))
+                client->buffer = g_byte_array_sized_new (r);
+            g_byte_array_append (client->buffer, buffer, r);
+
+            /* Try to parse input messages */
+            parse_request (self, client);
+        }
+    }
+
     if (condition & G_IO_HUP || condition & G_IO_ERR) {
         untrack_client (self, client);
         return FALSE;
     }
 
-    if (!(condition & G_IO_IN || condition & G_IO_PRI))
-        return TRUE;
-
-    r = g_input_stream_read (g_io_stream_get_input_stream (G_IO_STREAM (client->connection)),
-                             buffer,
-                             BUFFER_SIZE,
-                             NULL,
-                             &error);
-    if (r < 0) {
-        g_warning ("Error reading from istream: %s", error ? error->message : "unknown");
-        if (error)
-            g_error_free (error);
-        untrack_client (self, client);
-        return FALSE;
-    }
-
-    if (r == 0)
-        return TRUE;
-
-    /* else, r > 0 */
-    if (!G_UNLIKELY (client->buffer))
-        client->buffer = g_byte_array_sized_new (r);
-    g_byte_array_append (client->buffer, buffer, r);
-
-    /* Try to parse input messages */
-    parse_request (self, client);
-
     return TRUE;
 }
 
diff --git a/src/libqmi-glib/qmi-utils.c b/src/libqmi-glib/qmi-utils.c
index 5cf606b..2c87165 100644
--- a/src/libqmi-glib/qmi-utils.c
+++ b/src/libqmi-glib/qmi-utils.c
@@ -120,6 +120,41 @@
 }
 
 /*****************************************************************************/
+
+gboolean
+__qmi_string_utf8_validate_printable (const guint8 *utf8,
+                                      gsize         utf8_len)
+{
+    const gchar *p;
+    const gchar *init;
+
+    g_assert (utf8);
+    g_assert (utf8_len);
+
+    /* First check if valid UTF-8 */
+    init = (const gchar *)utf8;
+    if (!g_utf8_validate (init, utf8_len, NULL))
+        return FALSE;
+
+    /* Then check if contents are printable. If one is not,
+     * check fails. */
+    for (p = init; (gsize)(p - init) < utf8_len; p = g_utf8_next_char (p)) {
+        gunichar unichar;
+
+        /* Explicitly allow CR and LF even if they're control characters, given
+         * that NMEA traces reported via QMI LOC indications seem to have these
+         * suffixed. */
+        if (*p == '\r' || *p == '\n')
+            continue;
+
+        unichar = g_utf8_get_char (p);
+        if (!g_unichar_isprint (unichar))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+/*****************************************************************************/
 /* GSM 03.38 encoding conversion stuff, imported from ModemManager */
 
 #define GSM_DEF_ALPHABET_SIZE 128
diff --git a/src/libqmi-glib/qmi-utils.h b/src/libqmi-glib/qmi-utils.h
index 4131dd5..6963851 100644
--- a/src/libqmi-glib/qmi-utils.h
+++ b/src/libqmi-glib/qmi-utils.h
@@ -86,6 +86,10 @@
                              GError **error);
 
 G_GNUC_INTERNAL
+gboolean __qmi_string_utf8_validate_printable (const guint8 *utf8,
+                                               gsize         utf8_len);
+
+G_GNUC_INTERNAL
 gchar *__qmi_string_utf8_from_gsm7 (const guint8 *gsm,
                                     gsize         gsm_len);
 
diff --git a/src/libqmi-glib/test/test-fixture.c b/src/libqmi-glib/test/test-fixture.c
index 05fa015..cfbc2b4 100644
--- a/src/libqmi-glib/test/test-fixture.c
+++ b/src/libqmi-glib/test/test-fixture.c
@@ -22,10 +22,18 @@
 #define VIRTUAL_SOCKET_PATH "virtual-socket-path"
 
 static const QmiService services [] = {
+#if defined HAVE_QMI_SERVICE_DMS
     QMI_SERVICE_DMS,
+#endif
+#if defined HAVE_QMI_SERVICE_NAS
     QMI_SERVICE_NAS,
+#endif
+#if defined HAVE_QMI_SERVICE_WDS
     QMI_SERVICE_WDS,
+#endif
+#if defined HAVE_QMI_SERVICE_PDS
     QMI_SERVICE_PDS
+#endif
 };
 
 static void
diff --git a/src/libqmi-glib/test/test-generated.c b/src/libqmi-glib/test/test-generated.c
index e312496..8162c54 100644
--- a/src/libqmi-glib/test/test-generated.c
+++ b/src/libqmi-glib/test/test-generated.c
@@ -29,6 +29,8 @@
 /*****************************************************************************/
 /* DMS Get IDs */
 
+#if defined HAVE_QMI_MESSAGE_DMS_GET_IDS
+
 static void
 dms_get_ids_ready (QmiClientDms *client,
                    GAsyncResult *res,
@@ -103,9 +105,13 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_IDS */
+
 /*****************************************************************************/
 /* DMS UIM Get PIN Status */
 
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS
+
 static void
 dms_uim_get_pin_status_ready (QmiClientDms *client,
                               GAsyncResult *res,
@@ -193,9 +199,13 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS */
+
 /*****************************************************************************/
 /* DMS UIM Verify PIN */
 
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN
+
 static void
 dms_uim_verify_pin_ready (QmiClientDms *client,
                           GAsyncResult *res,
@@ -256,6 +266,8 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN */
+
 /*****************************************************************************/
 /* DMS Get Time
  *
@@ -265,6 +277,8 @@
  * read of the same buffer, as QMI_DMS_TIME_SOURCE_DEVICE is actually 0x0000.
  */
 
+#if defined HAVE_QMI_MESSAGE_DMS_GET_TIME
+
 static void
 dms_get_time_ready (QmiClientDms *client,
                     GAsyncResult *res,
@@ -337,8 +351,13 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_TIME */
+
 /*****************************************************************************/
 /* NAS Network Scan */
+
+#if defined HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN
+
 typedef struct {
     guint16 mcc;
     guint16 mnc;
@@ -522,28 +541,6 @@
 }
 
 static void
-nas_get_cell_location_info_ready (QmiClientNas *client,
-                                  GAsyncResult *res,
-                                  TestFixture  *fixture)
-{
-    QmiMessageNasGetCellLocationInfoOutput *output;
-    GError *error = NULL;
-    gboolean st;
-
-    output = qmi_client_nas_get_cell_location_info_finish (client, res, &error);
-    g_assert_no_error (error);
-    g_assert (output);
-
-    st = qmi_message_nas_get_cell_location_info_output_get_result (output, &error);
-    g_assert_no_error (error);
-    g_assert (st);
-
-    qmi_message_nas_get_cell_location_info_output_unref (output);
-
-    test_fixture_loop_stop (fixture);
-}
-
-static void
 test_generated_nas_network_scan (TestFixture *fixture)
 {
     guint8 expected[] = {
@@ -608,6 +605,35 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN */
+
+/*****************************************************************************/
+/* NAS Get Cell Location */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
+
+static void
+nas_get_cell_location_info_ready (QmiClientNas *client,
+                                  GAsyncResult *res,
+                                  TestFixture  *fixture)
+{
+    QmiMessageNasGetCellLocationInfoOutput *output;
+    GError *error = NULL;
+    gboolean st;
+
+    output = qmi_client_nas_get_cell_location_info_finish (client, res, &error);
+    g_assert_no_error (error);
+    g_assert (output);
+
+    st = qmi_message_nas_get_cell_location_info_output_get_result (output, &error);
+    g_assert_no_error (error);
+    g_assert (st);
+
+    qmi_message_nas_get_cell_location_info_output_unref (output);
+
+    test_fixture_loop_stop (fixture);
+}
+
 static void
 test_generated_nas_get_cell_location_info (TestFixture *fixture)
 {
@@ -643,7 +669,257 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO */
+
 /*****************************************************************************/
+/* NAS Get Serving System */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM
+
+static void
+nas_get_serving_system_ready (QmiClientNas *client,
+                              GAsyncResult *res,
+                              TestFixture  *fixture)
+{
+    QmiMessageNasGetServingSystemOutput *output;
+    GError *error = NULL;
+    gboolean st;
+
+    output = qmi_client_nas_get_serving_system_finish (client, res, &error);
+    g_assert_no_error (error);
+    g_assert (output);
+
+    st = qmi_message_nas_get_serving_system_output_get_result (output, &error);
+    g_assert_no_error (error);
+    g_assert (st);
+
+    /* current plmn in GSM-7 instead of UTF-8:
+     *   <<<<<< TLV:
+     *   <<<<<<   type       = "Current PLMN" (0x12)
+     *   <<<<<<   length     = 10
+     *   <<<<<<   value      = DE:00:32:00:05:49:76:3A:4C:06
+     *   <<<<<<   translated = [ mcc = '222' mnc = '50' description = 'Iliad' ]
+     */
+    {
+        guint16 mcc;
+        guint16 mnc;
+        const gchar *description;
+
+        g_assert (qmi_message_nas_get_serving_system_output_get_current_plmn (output, &mcc, &mnc, &description, &error));
+        g_assert_no_error (error);
+        g_assert_cmpuint (mcc, ==, 222);
+        g_assert_cmpuint (mnc, ==, 50);
+        g_assert_cmpstr (description, ==, "Iliad");
+    }
+
+    qmi_message_nas_get_serving_system_output_unref (output);
+
+    test_fixture_loop_stop (fixture);
+}
+
+static void
+test_generated_nas_get_serving_system (TestFixture *fixture)
+{
+    guint8 expected[] = {
+        0x01,
+        0x0C, 0x00, 0x00, 0x03, 0x01,
+        0x00, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00
+    };
+    guint8 response[] = {
+        0x01,
+        0x6E, 0x00, 0x80, 0x03, 0x01,
+        0x02, 0x01, 0x00, 0x24, 0x00, 0x62, 0x00, 0x02,
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06,
+        0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x05, 0x10,
+        0x01, 0x00, 0x01, 0x11, 0x04, 0x00, 0x03, 0x03,
+        0x04, 0x05, 0x12, 0x0A, 0x00, 0xDE, 0x00, 0x32,
+        0x00, 0x05, 0x49, 0x76, 0x3A, 0x4C, 0x06, 0x15,
+        0x03, 0x00, 0x01, 0x05, 0x01, 0x1B, 0x01, 0x00,
+        0x00, 0x1C, 0x02, 0x00, 0xB4, 0x5F, 0x1D, 0x04,
+        0x00, 0xCF, 0x5A, 0x13, 0x01, 0x21, 0x05, 0x00,
+        0x02, 0x03, 0x00, 0x00, 0x00, 0x25, 0x08, 0x00,
+        0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+        0x26, 0x02, 0x00, 0x22, 0x01, 0x27, 0x05, 0x00,
+        0xDE, 0x00, 0x32, 0x00, 0x00, 0x28, 0x01, 0x00,
+        0x00
+    };
+
+    test_port_context_set_command (fixture->ctx,
+                                   expected, G_N_ELEMENTS (expected),
+                                   response, G_N_ELEMENTS (response),
+                                   fixture->service_info[QMI_SERVICE_NAS].transaction_id++);
+
+    qmi_client_nas_get_serving_system (QMI_CLIENT_NAS (fixture->service_info[QMI_SERVICE_NAS].client), NULL, 3, NULL,
+                                       (GAsyncReadyCallback) nas_get_serving_system_ready,
+                                       fixture);
+
+    test_fixture_loop_run (fixture);
+}
+
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM */
+
+/*****************************************************************************/
+/* NAS Get System Info */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO
+
+static void
+nas_get_system_info_ready (QmiClientNas *client,
+                           GAsyncResult *res,
+                           TestFixture  *fixture)
+{
+    QmiMessageNasGetSystemInfoOutput *output;
+    GError *error = NULL;
+    gboolean st;
+
+    output = qmi_client_nas_get_system_info_finish (client, res, &error);
+    g_assert_no_error (error);
+    g_assert (output);
+
+    st = qmi_message_nas_get_system_info_output_get_result (output, &error);
+    g_assert_no_error (error);
+    g_assert (st);
+
+    {
+        gboolean                    domain_valid = FALSE;
+        QmiNasNetworkServiceDomain  domain;
+        gboolean                    service_capability_valid = FALSE;
+        QmiNasNetworkServiceDomain  service_capability;
+        gboolean                    roaming_status_valid = FALSE;
+        QmiNasRoamingStatus         roaming_status;
+        gboolean                    forbidden_valid = FALSE;
+        gboolean                    forbidden;
+        gboolean                    lac_valid = FALSE;
+        guint16                     lac;
+        gboolean                    cid_valid = FALSE;
+        guint32                     cid;
+        gboolean                    registration_reject_info_valid = FALSE;
+        QmiNasNetworkServiceDomain  registration_reject_domain;
+        guint8                      registration_reject_cause;
+        gboolean                    network_id_valid = FALSE;
+        const gchar                *mcc = NULL;
+        const gchar                *mnc = NULL;
+        gboolean                    tac_valid = FALSE;
+        guint16                     tac;
+
+        /*
+         *	LTE service:
+         *		Status: 'available'
+         *		True Status: 'available'
+         *		Preferred data path: 'no'
+         *		Domain: 'cs-ps'
+         *		Service capability: 'cs-ps'
+         *		Roaming status: 'off'
+         *		Forbidden: 'no'
+         *		Cell ID: '1609474'
+         *		MCC: '530'
+         *		MNC: '24'                -- Given as 2 digits, suffixed with 0xFF!
+         *		Tracking Area Code: '63001'
+         *		Voice support: 'yes'
+         *		IMS voice support: 'no'
+         *		eMBMS coverage info support: 'no'
+         *		eMBMS coverage info trace ID: '65535'
+         *		Cell access: 'all-calls'
+         *		Registration restriction: 'unrestricted'
+         *		Registration domain: 'not-applicable'
+         */
+
+        g_assert (qmi_message_nas_get_system_info_output_get_lte_system_info (output,
+                                                                              &domain_valid,
+                                                                              &domain,
+                                                                              &service_capability_valid,
+                                                                              &service_capability,
+                                                                              &roaming_status_valid,
+                                                                              &roaming_status,
+                                                                              &forbidden_valid,
+                                                                              &forbidden,
+                                                                              &lac_valid,
+                                                                              &lac,
+                                                                              &cid_valid,
+                                                                              &cid,
+                                                                              &registration_reject_info_valid,
+                                                                              &registration_reject_domain,
+                                                                              &registration_reject_cause,
+                                                                              &network_id_valid,
+                                                                              &mcc,
+                                                                              &mnc,
+                                                                              &tac_valid,
+                                                                              &tac,
+                                                                              &error));
+        g_assert_no_error (error);
+        g_assert (domain_valid);
+        g_assert_cmpuint (domain, ==, QMI_NAS_NETWORK_SERVICE_DOMAIN_CS_PS);
+        g_assert (service_capability_valid);
+        g_assert_cmpuint (service_capability, ==, QMI_NAS_NETWORK_SERVICE_DOMAIN_CS_PS);
+        g_assert (roaming_status_valid);
+        g_assert_cmpuint (roaming_status, ==, QMI_NAS_ROAMING_STATUS_OFF);
+        g_assert (forbidden_valid);
+        g_assert (!forbidden);
+        g_assert (!lac_valid);
+        g_assert (cid_valid);
+        g_assert_cmpuint (cid, ==, 1616133);
+        g_assert (!registration_reject_info_valid);
+        g_assert (network_id_valid);
+        g_assert_cmpstr (mcc, ==, "530");
+        g_assert_cmpstr (mnc, ==, "24");
+        g_assert (tac_valid);
+        g_assert_cmpuint (tac, ==, 63001);
+    }
+
+    qmi_message_nas_get_system_info_output_unref (output);
+
+    test_fixture_loop_stop (fixture);
+}
+
+static void
+test_generated_nas_get_system_info (TestFixture *fixture)
+{
+    guint8 expected[] = {
+        0x01,
+        0x0C, 0x00, 0x00, 0x03, 0x01,
+        0x00, 0x01, 0x00, 0x4D, 0x00, 0x00, 0x00
+    };
+    guint8 response[] = {
+        0x01,
+        0x9A, 0x00, 0x80, 0x03, 0x01,
+        0x02, 0x01, 0x00, 0x4D, 0x00, 0x8E, 0x00, 0x02,
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x03,
+        0x00, 0x00, 0x00, 0x00, 0x13, 0x03, 0x00, 0x00,
+        0x00, 0x00, 0x14, 0x03, 0x00, 0x02, 0x02, 0x00,
+        0x19, 0x1D, 0x00, 0x01, 0x03, 0x01, 0x03, 0x01,
+        0x00, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x05,
+        0xA9, 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35,
+        0x33, 0x30, 0x32, 0x34, 0xFF, 0x01, 0x19, 0xF6,
+        0x1E, 0x02, 0x00, 0xFF, 0xFF, 0x21, 0x01, 0x00,
+        0x01, 0x26, 0x01, 0x00, 0x00, 0x27, 0x04, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x29, 0x01, 0x00, 0x00,
+        0x2A, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2F,
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00,
+        0xFF, 0xFF, 0x38, 0x04, 0x00, 0x03, 0x00, 0x00,
+        0x00, 0x39, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+        0x3E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+        0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x04,
+        0x00, 0x04, 0x00, 0x00, 0x00
+    };
+
+    test_port_context_set_command (fixture->ctx,
+                                   expected, G_N_ELEMENTS (expected),
+                                   response, G_N_ELEMENTS (response),
+                                   fixture->service_info[QMI_SERVICE_NAS].transaction_id++);
+
+    qmi_client_nas_get_system_info (QMI_CLIENT_NAS (fixture->service_info[QMI_SERVICE_NAS].client), NULL, 3, NULL,
+                                    (GAsyncReadyCallback) nas_get_system_info_ready,
+                                    fixture);
+
+    test_fixture_loop_run (fixture);
+}
+
+#endif
+
+/*****************************************************************************/
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
 
 static void
 nas_get_cell_location_info_invalid_response_ready (QmiClientNas *client,
@@ -695,6 +971,8 @@
     test_fixture_loop_run (fixture);
 }
 
+#endif
+
 /*****************************************************************************/
 
 int main (int argc, char **argv)
@@ -704,17 +982,35 @@
     /* Test the setup/teardown test methods */
     TEST_ADD ("/libqmi-glib/generated/core", test_generated_core);
 
-    /* DMS */
-    TEST_ADD ("/libqmi-glib/generated/dms/get-ids",                test_generated_dms_get_ids);
-    TEST_ADD ("/libqmi-glib/generated/dms/uim-get-pin-status",     test_generated_dms_uim_get_pin_status);
-    TEST_ADD ("/libqmi-glib/generated/dms/uim-verify-pin",         test_generated_dms_uim_verify_pin);
-    TEST_ADD ("/libqmi-glib/generated/dms/get-time",               test_generated_dms_get_time);
-    /* NAS */
-    TEST_ADD ("/libqmi-glib/generated/nas/network-scan",           test_generated_nas_network_scan);
-    TEST_ADD ("/libqmi-glib/generated/nas/get-cell-location-info", test_generated_nas_get_cell_location_info);
+#if defined HAVE_QMI_MESSAGE_DMS_GET_IDS
+    TEST_ADD ("/libqmi-glib/generated/dms/get-ids", test_generated_dms_get_ids);
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS
+    TEST_ADD ("/libqmi-glib/generated/dms/uim-get-pin-status", test_generated_dms_uim_get_pin_status);
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN
+    TEST_ADD ("/libqmi-glib/generated/dms/uim-verify-pin", test_generated_dms_uim_verify_pin);
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_TIME
+    TEST_ADD ("/libqmi-glib/generated/dms/get-time", test_generated_dms_get_time);
+#endif
 
-    /* Invalid responses */
+#if defined HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN
+    TEST_ADD ("/libqmi-glib/generated/nas/network-scan", test_generated_nas_network_scan);
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
+    TEST_ADD ("/libqmi-glib/generated/nas/get-cell-location-info", test_generated_nas_get_cell_location_info);
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM
+    TEST_ADD ("/libqmi-glib/generated/nas/get-serving-system", test_generated_nas_get_serving_system);
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO
+    TEST_ADD ("/libqmi-glib/generated/nas/get-system-info", test_generated_nas_get_system_info);
+#endif
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
     TEST_ADD ("/libqmi-glib/generated/nas/invalid/get-cell-location-info", test_generated_nas_get_cell_location_info_invalid_response);
+#endif
 
     return g_test_run ();
 }
diff --git a/src/libqmi-glib/test/test-message.c b/src/libqmi-glib/test/test-message.c
index e41917a..97c6e0c 100644
--- a/src/libqmi-glib/test/test-message.c
+++ b/src/libqmi-glib/test/test-message.c
@@ -18,10 +18,7 @@
 #include <string.h>
 #include <stdio.h>
 
-#include "qmi-message.h"
-#include "qmi-errors.h"
-#include "qmi-error-types.h"
-#include "qmi-utils.h"
+#include <libqmi-glib.h>
 
 /*****************************************************************************/
 
@@ -175,8 +172,9 @@
 }
 
 static void
-test_message_overflow_common (const guint8 *buffer,
-                              guint buffer_len)
+test_message_printable_common (const guint8 *buffer,
+                               guint         buffer_len,
+                               const gchar  *expected_in_printable)
 {
     QmiMessage *message;
     GByteArray *array;
@@ -190,8 +188,10 @@
     g_assert (message);
 
     printable = qmi_message_get_printable_full (message, NULL, "");
+#ifdef TEST_PRINT_MESSAGE
     g_print ("\n%s\n", printable);
-    g_assert (strstr (printable, "ERROR: Reading TLV would overflow"));
+#endif
+    g_assert (strstr (printable, expected_in_printable));
     g_free (printable);
 
     g_byte_array_unref (array);
@@ -211,9 +211,11 @@
         0x06, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x05
     };
 
-    test_message_overflow_common (buffer, G_N_ELEMENTS (buffer));
+    test_message_printable_common (buffer, G_N_ELEMENTS (buffer), "ERROR: Reading TLV would overflow");
 }
 
+#if defined HAVE_QMI_INDICATION_PDS_EVENT_REPORT
+
 static void
 test_message_parse_missing_size (void)
 {
@@ -234,9 +236,32 @@
         0x01
     };
 
-    test_message_overflow_common (buffer, G_N_ELEMENTS (buffer));
+    test_message_printable_common (buffer, G_N_ELEMENTS (buffer), "ERROR: Reading TLV would overflow");
 }
 
+#endif
+
+#if defined HAVE_QMI_INDICATION_LOC_NMEA
+
+static void
+test_message_parse_string_with_crlf (void)
+{
+    /* LOC indication: NMEA
+     * The NMEA trace comes suffixed with \r\n, this test makes sure the proper
+     * parsing is done on the string.
+     */
+    const guint8 buffer[] = {
+        0x01, 0x2D, 0x00, 0x80, 0x10, 0x01, 0x04, 0xB4, 0x00, 0x26, 0x00, 0x21,
+        0x00, 0x01, 0x1E, 0x00, 0x24, 0x47, 0x50, 0x47, 0x53, 0x41, 0x2C, 0x41,
+        0x2C, 0x31, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
+        0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2A, 0x31, 0x45, 0x0D, 0x0A
+    };
+
+    test_message_printable_common (buffer, sizeof (buffer), "$GPGSA,A,1,,,,,,,,,,,,,,,*1E");
+}
+
+#endif
+
 /*****************************************************************************/
 
 static void
@@ -322,6 +347,7 @@
     _g_assert_cmpmem (buffer, buffer_length, expected_buffer, sizeof (expected_buffer));
 
     qmi_message_unref (self);
+    g_byte_array_unref (qmi);
 }
 
 static void
@@ -1564,7 +1590,12 @@
     g_test_add_func ("/libqmi-glib/message/parse/complete-and-short",    test_message_parse_complete_and_short);
     g_test_add_func ("/libqmi-glib/message/parse/complete-and-complete", test_message_parse_complete_and_complete);
     g_test_add_func ("/libqmi-glib/message/parse/wrong-tlv",             test_message_parse_wrong_tlv);
+#if defined HAVE_QMI_INDICATION_PDS_EVENT_REPORT
     g_test_add_func ("/libqmi-glib/message/parse/missing-size",          test_message_parse_missing_size);
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_NMEA
+    g_test_add_func ("/libqmi-glib/message/parse/string-with-crlf",      test_message_parse_string_with_crlf);
+#endif
 
     g_test_add_func ("/libqmi-glib/message/new/request",           test_message_new_request);
     g_test_add_func ("/libqmi-glib/message/new/request-from-data", test_message_new_request_from_data);
diff --git a/src/qmi-firmware-update/qfu-main.c b/src/qmi-firmware-update/qfu-main.c
index 5a7c350..f4e6142 100644
--- a/src/qmi-firmware-update/qfu-main.c
+++ b/src/qmi-firmware-update/qfu-main.c
@@ -554,25 +554,25 @@
     context = g_option_context_new ("- Update firmware in QMI devices");
     g_option_context_set_description (context, context_description);
 
-    group = g_option_group_new ("selection", "Generic device selection options", "", NULL, NULL);
+    group = g_option_group_new ("selection", "Generic device selection options:", "", NULL, NULL);
     g_option_group_add_entries (group, context_selection_entries);
     g_option_context_add_group (context, group);
 
 #if defined WITH_UDEV
-    group = g_option_group_new ("update", "Update options (normal mode)", "", NULL, NULL);
+    group = g_option_group_new ("update", "Update options (normal mode):", "", NULL, NULL);
     g_option_group_add_entries (group, context_update_entries);
     g_option_context_add_group (context, group);
 #endif
 
-    group = g_option_group_new ("reset", "Reset options (normal mode)", "", NULL, NULL);
+    group = g_option_group_new ("reset", "Reset options (normal mode):", "", NULL, NULL);
     g_option_group_add_entries (group, context_reset_entries);
     g_option_context_add_group (context, group);
 
-    group = g_option_group_new ("update-download", "Update options (download mode)", "", NULL, NULL);
+    group = g_option_group_new ("update-download", "Update options (download mode):", "", NULL, NULL);
     g_option_group_add_entries (group, context_update_download_entries);
     g_option_context_add_group (context, group);
 
-    group = g_option_group_new ("verify", "Verify options", "", NULL, NULL);
+    group = g_option_group_new ("verify", "Verify options:", "", NULL, NULL);
     g_option_group_add_entries (group, context_verify_entries);
     g_option_context_add_group (context, group);
 
diff --git a/src/qmicli/qmicli-dms.c b/src/qmicli/qmicli-dms.c
index 2c64a4b..5a7b304 100644
--- a/src/qmicli/qmicli-dms.c
+++ b/src/qmicli/qmicli-dms.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_DMS
+
 #undef VALIDATE_UNKNOWN
 #define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
 
@@ -105,239 +107,354 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_DMS_GET_IDS
     { "dms-get-ids", 0, 0, G_OPTION_ARG_NONE, &get_ids_flag,
       "Get IDs",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_CAPABILITIES
     { "dms-get-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_capabilities_flag,
       "Get capabilities",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MANUFACTURER
     { "dms-get-manufacturer", 0, 0, G_OPTION_ARG_NONE, &get_manufacturer_flag,
       "Get manufacturer",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MODEL
     { "dms-get-model", 0, 0, G_OPTION_ARG_NONE, &get_model_flag,
       "Get model",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_REVISION
     { "dms-get-revision", 0, 0, G_OPTION_ARG_NONE, &get_revision_flag,
       "Get revision",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MSISDN
     { "dms-get-msisdn", 0, 0, G_OPTION_ARG_NONE, &get_msisdn_flag,
       "Get MSISDN",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_POWER_STATE
     { "dms-get-power-state", 0, 0, G_OPTION_ARG_NONE, &get_power_state_flag,
       "Get power state",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_PIN_PROTECTION
     { "dms-uim-set-pin-protection", 0, 0, G_OPTION_ARG_STRING, &uim_set_pin_protection_str,
       "Set PIN protection in the UIM",
       "[(PIN|PIN2),(disable|enable),(current PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN
     { "dms-uim-verify-pin", 0, 0, G_OPTION_ARG_STRING, &uim_verify_pin_str,
       "Verify PIN",
       "[(PIN|PIN2),(current PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN
     { "dms-uim-unblock-pin", 0, 0, G_OPTION_ARG_STRING, &uim_unblock_pin_str,
       "Unblock PIN",
       "[(PIN|PIN2),(PUK),(new PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_CHANGE_PIN
     { "dms-uim-change-pin", 0, 0, G_OPTION_ARG_STRING, &uim_change_pin_str,
       "Change PIN",
       "[(PIN|PIN2),(old PIN),(new PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS
     { "dms-uim-get-pin-status", 0, 0, G_OPTION_ARG_NONE, &uim_get_pin_status_flag,
       "Get PIN status",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_ICCID
     { "dms-uim-get-iccid", 0, 0, G_OPTION_ARG_NONE, &uim_get_iccid_flag,
       "Get ICCID",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_IMSI
     { "dms-uim-get-imsi", 0, 0, G_OPTION_ARG_NONE, &uim_get_imsi_flag,
       "Get IMSI",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_STATE
     { "dms-uim-get-state", 0, 0, G_OPTION_ARG_NONE, &uim_get_state_flag,
       "Get UIM State",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_CK_STATUS
     { "dms-uim-get-ck-status", 0, 0, G_OPTION_ARG_STRING, &uim_get_ck_status_str,
       "Get CK Status",
       "[(pn|pu|pp|pc|pf)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_CK_PROTECTION
     { "dms-uim-set-ck-protection", 0, 0, G_OPTION_ARG_STRING, &uim_set_ck_protection_str,
       "Disable CK protection",
       "[(pn|pu|pp|pc|pf),(disable),(key)]"
     },
+#endif
     { "dms-uim-unblock-ck", 0, 0, G_OPTION_ARG_STRING, &uim_unblock_ck_str,
       "Unblock CK",
       "[(pn|pu|pp|pc|pf),(key)]"
     },
+#if defined HAVE_QMI_MESSAGE_DMS_GET_HARDWARE_REVISION
     { "dms-get-hardware-revision", 0, 0, G_OPTION_ARG_NONE, &get_hardware_revision_flag,
       "Get the HW revision",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_OPERATING_MODE
     { "dms-get-operating-mode", 0, 0, G_OPTION_ARG_NONE, &get_operating_mode_flag,
       "Get the device operating mode",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_OPERATING_MODE
     { "dms-set-operating-mode", 0, 0, G_OPTION_ARG_STRING, &set_operating_mode_str,
       "Set the device operating mode",
       "[(Operating mode)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_TIME
     { "dms-get-time", 0, 0, G_OPTION_ARG_NONE, &get_time_flag,
       "Get the device time",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_PRL_VERSION
     { "dms-get-prl-version", 0, 0, G_OPTION_ARG_NONE, &get_prl_version_flag,
       "Get the PRL version",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_ACTIVATION_STATE
     { "dms-get-activation-state", 0, 0, G_OPTION_ARG_NONE, &get_activation_state_flag,
       "Get the state of the service activation",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_AUTOMATIC
     { "dms-activate-automatic", 0, 0, G_OPTION_ARG_STRING, &activate_automatic_str,
       "Request automatic service activation",
       "[Activation Code]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_MANUAL
     { "dms-activate-manual", 0, 0, G_OPTION_ARG_STRING, &activate_manual_str,
       "Request manual service activation",
       "[SPC,SID,MDN,MIN]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_USER_LOCK_STATE
     { "dms-get-user-lock-state", 0, 0, G_OPTION_ARG_NONE, &get_user_lock_state_flag,
       "Get the state of the user lock",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_STATE
     { "dms-set-user-lock-state", 0, 0, G_OPTION_ARG_STRING, &set_user_lock_state_str,
       "Set the state of the user lock",
       "[(disable|enable),(current lock code)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_CODE
     { "dms-set-user-lock-code", 0, 0, G_OPTION_ARG_STRING, &set_user_lock_code_str,
       "Change the user lock code",
       "[(old lock code),(new lock code)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_READ_USER_DATA
     { "dms-read-user-data", 0, 0, G_OPTION_ARG_NONE, &read_user_data_flag,
       "Read user data",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_WRITE_USER_DATA
     { "dms-write-user-data", 0, 0, G_OPTION_ARG_STRING, &write_user_data_str,
       "Write user data",
       "[(User data)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_READ_ERI_FILE
     { "dms-read-eri-file", 0, 0, G_OPTION_ARG_NONE, &read_eri_file_flag,
       "Read ERI file",
       NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_RESTORE_FACTORY_DEFAULTS
     { "dms-restore-factory-defaults", 0, 0, G_OPTION_ARG_STRING, &restore_factory_defaults_str,
       "Restore factory defaults",
       "[(Service Programming Code)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_VALIDATE_SERVICE_PROGRAMMING_CODE
     { "dms-validate-service-programming-code", 0, 0, G_OPTION_ARG_STRING, &validate_service_programming_code_str,
       "Validate the Service Programming Code",
       "[(Service Programming Code)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_ID
     { "dms-set-firmware-id", 0, 0, G_OPTION_ARG_NONE, &set_firmware_id_flag,
       "Set firmware id",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BAND_CAPABILITIES
     { "dms-get-band-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_band_capabilities_flag,
       "Get band capabilities",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FACTORY_SKU
     { "dms-get-factory-sku", 0, 0, G_OPTION_ARG_NONE, &get_factory_sku_flag,
       "Get factory stock keeping unit",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && defined HAVE_QMI_MESSAGE_DMS_GET_STORED_IMAGE_INFO
     { "dms-list-stored-images", 0, 0, G_OPTION_ARG_NONE, &list_stored_images_flag,
       "List stored images",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES
     { "dms-select-stored-image", 0, 0, G_OPTION_ARG_STRING, &select_stored_image_str,
       "Select stored image",
       "[modem#,pri#] where # is the index"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && \
+    defined HAVE_QMI_MESSAGE_DMS_DELETE_STORED_IMAGE
     { "dms-delete-stored-image", 0, 0, G_OPTION_ARG_STRING, &delete_stored_image_str,
       "Delete stored image",
       "[modem#|pri#] where # is the index"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FIRMWARE_PREFERENCE
     { "dms-get-firmware-preference", 0, 0, G_OPTION_ARG_NONE, &get_firmware_preference_flag,
       "Get firmware preference",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
     { "dms-set-firmware-preference", 0, 0, G_OPTION_ARG_STRING, &set_firmware_preference_str,
       "Set firmware preference",
       "[(fwver),(config),(carrier)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BOOT_IMAGE_DOWNLOAD_MODE
     { "dms-get-boot-image-download-mode", 0, 0, G_OPTION_ARG_NONE, &get_boot_image_download_mode_flag,
       "Get boot image download mode",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_BOOT_IMAGE_DOWNLOAD_MODE
     { "dms-set-boot-image-download-mode", 0, 0, G_OPTION_ARG_STRING, &set_boot_image_download_mode_str,
       "Set boot image download mode",
       "[normal|boot-and-recovery]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SOFTWARE_VERSION
     { "dms-get-software-version", 0, 0, G_OPTION_ARG_NONE, &get_software_version_flag,
       "Get software version",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FCC_AUTHENTICATION
     { "dms-set-fcc-authentication", 0, 0, G_OPTION_ARG_NONE, &set_fcc_authentication_flag,
       "Set FCC authentication",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SUPPORTED_MESSAGES
     { "dms-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_HP_CHANGE_DEVICE_MODE
     { "dms-hp-change-device-mode", 0, 0, G_OPTION_ARG_STRING, &hp_change_device_mode_str,
       "Change device mode (HP specific)",
       "[fastboot]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_CURRENT_FIRMWARE
     { "dms-swi-get-current-firmware", 0, 0, G_OPTION_ARG_NONE, &swi_get_current_firmware_flag,
       "Get Current Firmware (Sierra Wireless specific)",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_USB_COMPOSITION
     { "dms-swi-get-usb-composition", 0, 0, G_OPTION_ARG_NONE, &swi_get_usb_composition_flag,
       "Get current and supported USB compositions (Sierra Wireless specific)",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_SET_USB_COMPOSITION
     { "dms-swi-set-usb-composition", 0, 0, G_OPTION_ARG_STRING, &swi_set_usb_composition_str,
       "Set USB composition (Sierra Wireless specific)",
       "[#]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
     { "dms-foxconn-change-device-mode", 0, 0, G_OPTION_ARG_STRING, &foxconn_change_device_mode_str,
       "Change device mode (Foxconn specific)",
       "[fastboot-ota|fastboot-online]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
     { "dms-foxconn-get-firmware-version", 0, 0, G_OPTION_ARG_STRING, &foxconn_get_firmware_version_str,
       "Get firmware version (Foxconn specific)",
       "[firmware-mcfg-apps|firmware-mcfg|apps]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MAC_ADDRESS
     { "dms-get-mac-address", 0, 0, G_OPTION_ARG_STRING, &get_mac_address_str,
       "Get default MAC address",
       "[wlan|bt]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_RESET
     { "dms-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
     { "dms-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a DMS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
     },
     /* deprecated entries (hidden in --help) */
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
     { "dms-dell-change-device-mode", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &dell_change_device_mode_str,
       "Change device mode (DELL specific)",
       "[fastboot-ota|fastboot-online]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
     { "dms-dell-get-firmware-version", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &dell_get_firmware_version_str,
       "Get firmware version (DELL specific)",
       "[firmware-mcfg-apps|firmware-mcfg|apps]"
     },
+#endif
     { NULL }
 };
 
@@ -347,7 +464,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("dms",
-                                "DMS options",
+                                "DMS options:",
                                 "Show Device Management Service options",
                                 NULL,
                                 NULL);
@@ -456,6 +573,9 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE || \
+    defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
+
 static void
 operation_shutdown_skip_cid_release (gboolean operation_status)
 {
@@ -466,6 +586,10 @@
     qmicli_async_operation_done (operation_status, TRUE);
 }
 
+#endif
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_IDS
+
 static void
 get_ids_ready (QmiClientDms *client,
                GAsyncResult *res)
@@ -516,6 +640,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_IDS */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_CAPABILITIES
+
 static void
 get_capabilities_ready (QmiClientDms *client,
                         GAsyncResult *res)
@@ -583,6 +711,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_CAPABILITIES */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MANUFACTURER
+
 static void
 get_manufacturer_ready (QmiClientDms *client,
                         GAsyncResult *res)
@@ -618,6 +750,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_MANUFACTURER */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MODEL
+
 static void
 get_model_ready (QmiClientDms *client,
                  GAsyncResult *res)
@@ -653,6 +789,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_MODEL */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_REVISION
+
 static void
 get_revision_ready (QmiClientDms *client,
                     GAsyncResult *res)
@@ -688,6 +828,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_REVISION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MSISDN
+
 static void
 get_msisdn_ready (QmiClientDms *client,
                   GAsyncResult *res)
@@ -723,6 +867,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_MSISDN */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_POWER_STATE
+
 static void
 get_power_state_ready (QmiClientDms *client,
                        GAsyncResult *res)
@@ -767,6 +915,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_POWER_STATE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_PIN_PROTECTION
+
 static QmiMessageDmsUimSetPinProtectionInput *
 uim_set_pin_protection_input_create (const gchar *str)
 {
@@ -852,6 +1004,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_SET_PIN_PROTECTION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN
+
 static QmiMessageDmsUimVerifyPinInput *
 uim_verify_pin_input_create (const gchar *str)
 {
@@ -934,6 +1090,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN
+
 static QmiMessageDmsUimUnblockPinInput *
 uim_unblock_pin_input_create (const gchar *str)
 {
@@ -1019,6 +1179,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_CHANGE_PIN
+
 static QmiMessageDmsUimChangePinInput *
 uim_change_pin_input_create (const gchar *str)
 {
@@ -1104,6 +1268,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_CHANGE_PIN */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS
+
 static void
 uim_get_pin_status_ready (QmiClientDms *client,
                           GAsyncResult *res)
@@ -1169,6 +1337,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_ICCID
+
 static void
 uim_get_iccid_ready (QmiClientDms *client,
                      GAsyncResult *res)
@@ -1204,6 +1376,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_ICCID */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_IMSI
+
 static void
 uim_get_imsi_ready (QmiClientDms *client,
                     GAsyncResult *res)
@@ -1239,6 +1415,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_IMSI */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_STATE
+
 static void
 uim_get_state_ready (QmiClientDms *client,
                     GAsyncResult *res)
@@ -1274,6 +1454,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_STATE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_CK_STATUS
+
 static QmiMessageDmsUimGetCkStatusInput *
 uim_get_ck_status_input_create (const gchar *str)
 {
@@ -1357,6 +1541,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_GET_CK_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_CK_PROTECTION
+
 static QmiMessageDmsUimSetCkProtectionInput *
 uim_set_ck_protection_input_create (const gchar *str)
 {
@@ -1444,6 +1632,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_SET_CK_PROTECTION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_CK
+
 static QmiMessageDmsUimUnblockCkInput *
 uim_unblock_ck_input_create (const gchar *str)
 {
@@ -1522,6 +1714,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_CK */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_HARDWARE_REVISION
+
 static void
 get_hardware_revision_ready (QmiClientDms *client,
                              GAsyncResult *res)
@@ -1557,6 +1753,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_HARDWARE_REVISION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_OPERATING_MODE
+
 static void
 get_operating_mode_ready (QmiClientDms *client,
                           GAsyncResult *res)
@@ -1608,6 +1808,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_OPERATING_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_OPERATING_MODE
+
 static QmiMessageDmsSetOperatingModeInput *
 set_operating_mode_input_create (const gchar *str)
 {
@@ -1663,6 +1867,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_OPERATING_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_TIME
+
 static void
 get_time_ready (QmiClientDms *client,
                 GAsyncResult *res)
@@ -1744,6 +1952,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_TIME */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_PRL_VERSION
+
 static void
 get_prl_version_ready (QmiClientDms *client,
                        GAsyncResult *res)
@@ -1791,6 +2003,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_PRL_VERSION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_ACTIVATION_STATE
+
 static void
 get_activation_state_ready (QmiClientDms *client,
                             GAsyncResult *res)
@@ -1829,6 +2045,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_ACTIVATION_STATE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_MANUAL
+
 static QmiMessageDmsActivateManualInput *
 activate_manual_input_create (const gchar *str)
 {
@@ -1897,6 +2117,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_ACTIVATE_MANUAL */
+
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_AUTOMATIC
+
 static QmiMessageDmsActivateAutomaticInput *
 activate_automatic_input_create (const gchar *str)
 {
@@ -1945,6 +2169,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_USER_LOCK_STATE
+
 static void
 get_user_lock_state_ready (QmiClientDms *client,
                            GAsyncResult *res)
@@ -1983,6 +2211,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_USER_LOCK_STATE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_STATE
+
 static QmiMessageDmsSetUserLockStateInput *
 set_user_lock_state_input_create (const gchar *str)
 {
@@ -2049,6 +2281,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_CODE
+
 static QmiMessageDmsSetUserLockCodeInput *
 set_user_lock_code_input_create (const gchar *str)
 {
@@ -2114,6 +2350,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_CODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_READ_USER_DATA
+
 static void
 read_user_data_ready (QmiClientDms *client,
                       GAsyncResult *res)
@@ -2158,6 +2398,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_READ_USER_DATA */
+
+#if defined HAVE_QMI_MESSAGE_DMS_WRITE_USER_DATA
+
 static QmiMessageDmsWriteUserDataInput *
 write_user_data_input_create (const gchar *str)
 {
@@ -2216,6 +2460,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_WRITE_USER_DATA */
+
+#if defined HAVE_QMI_MESSAGE_DMS_READ_ERI_FILE
+
 static void
 read_eri_file_ready (QmiClientDms *client,
                      GAsyncResult *res)
@@ -2260,6 +2508,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_READ_ERI_FILE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_RESTORE_FACTORY_DEFAULTS
+
 static QmiMessageDmsRestoreFactoryDefaultsInput *
 restore_factory_defaults_input_create (const gchar *str)
 {
@@ -2312,6 +2564,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_RESTORE_FACTORY_DEFAULTS */
+
+#if defined HAVE_QMI_MESSAGE_DMS_VALIDATE_SERVICE_PROGRAMMING_CODE
+
 static QmiMessageDmsValidateServiceProgrammingCodeInput *
 validate_service_programming_code_input_create (const gchar *str)
 {
@@ -2363,6 +2619,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_VALIDATE_SERVICE_PROGRAMMING_CODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_ID
+
 static void
 set_firmware_id_ready (QmiClientDms *client,
                        GAsyncResult *res)
@@ -2393,6 +2653,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_ID */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BAND_CAPABILITIES
+
 static void
 get_band_capabilities_ready (QmiClientDms *client,
                              GAsyncResult *res)
@@ -2459,6 +2723,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_BAND_CAPABILITIES */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FACTORY_SKU
+
 static void
 get_factory_sku_ready (QmiClientDms *client,
                        GAsyncResult *res)
@@ -2494,6 +2762,11 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_FACTORY_SKU */
+
+#if defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES &&  \
+    defined HAVE_QMI_MESSAGE_DMS_GET_STORED_IMAGE_INFO
+
 typedef struct {
     QmiMessageDmsListStoredImagesOutput *list_images_output;
     guint i;
@@ -2510,30 +2783,19 @@
 static void get_image_info (ListImagesContext *operation_ctx);
 
 static void
-get_stored_image_info_ready (QmiClientDms *client,
-                             GAsyncResult *res,
-                             ListImagesContext *operation_ctx)
+print_image_info (ListImagesContext *operation_ctx,
+                  QmiMessageDmsGetStoredImageInfoOutput *output)
 {
     GArray *array;
-    QmiMessageDmsGetStoredImageInfoOutput *output;
-    GError *error = NULL;
     QmiMessageDmsListStoredImagesOutputListImage *image;
     QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement *subimage;
-    gchar *unique_id_str;
-
-    output = qmi_client_dms_get_stored_image_info_finish (client, res, &error);
-    if (!output) {
-        /* Fully ignore errors */
-        g_error_free (error);
-    } else if (!qmi_message_dms_get_stored_image_info_output_get_result (output, &error)) {
-        /* Fully ignore errors */
-        g_error_free (error);
-    }
+    g_autofree gchar *unique_id_str = NULL;
 
     qmi_message_dms_list_stored_images_output_get_list (
         operation_ctx->list_images_output,
         &array,
         NULL);
+
     image = &g_array_index (array, QmiMessageDmsListStoredImagesOutputListImage, operation_ctx->i);
     subimage = &g_array_index (image->sublist,
                                QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement,
@@ -2603,12 +2865,23 @@
                          lock_id);
             }
         }
-
-        qmi_message_dms_get_stored_image_info_output_unref (output);
     }
-
     g_print ("\n");
-    g_free (unique_id_str);
+}
+
+static void
+get_stored_image_info_ready (QmiClientDms *client,
+                             GAsyncResult *res,
+                             ListImagesContext *operation_ctx)
+{
+
+    g_autoptr(QmiMessageDmsGetStoredImageInfoOutput) output = NULL;
+
+    output = qmi_client_dms_get_stored_image_info_finish (client, res, NULL);
+    if (output && !qmi_message_dms_get_stored_image_info_output_get_result (output, NULL))
+        g_clear_pointer (&output, qmi_message_dms_get_stored_image_info_output_unref);
+
+    print_image_info (operation_ctx, output);
 
     /* Go on to the next one */
     operation_ctx->j++;
@@ -2622,7 +2895,7 @@
     QmiMessageDmsListStoredImagesOutputListImage *image;
     QmiMessageDmsListStoredImagesOutputListImageSublistSublistElement *subimage;
     QmiMessageDmsGetStoredImageInfoInputImage image_id;
-    QmiMessageDmsGetStoredImageInfoInput *input;
+    g_autoptr(QmiMessageDmsGetStoredImageInfoInput) input = NULL;
 
     qmi_message_dms_list_stored_images_output_get_list (
         operation_ctx->list_images_output,
@@ -2668,14 +2941,12 @@
     image_id.build_id = subimage->build_id;
     input = qmi_message_dms_get_stored_image_info_input_new ();
     qmi_message_dms_get_stored_image_info_input_set_image (input, &image_id, NULL);
-
     qmi_client_dms_get_stored_image_info (ctx->client,
                                           input,
                                           10,
                                           ctx->cancellable,
                                           (GAsyncReadyCallback)get_stored_image_info_ready,
                                           operation_ctx);
-    qmi_message_dms_get_stored_image_info_input_unref (input);
 }
 
 static void
@@ -2713,6 +2984,11 @@
     get_image_info (operation_ctx);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && HAVE_QMI_MESSAGE_DMS_GET_STORED_IMAGE_INFO */
+
+#if defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && \
+    defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
+
 typedef struct {
     gint modem_index;
     gint pri_index;
@@ -2933,8 +3209,15 @@
         task);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES
+        * HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
+
 /* Note:
  *  used by both --dms-set-firmware-preference and --dms-select-stored-image
+ * But only one single symbol check, as the select operation already
+ * requires SET_FIRMWARE_PREFERENCE.
  */
 static void
 dms_set_firmware_preference_ready (QmiClientDms *client,
@@ -3005,6 +3288,11 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES
+
 static void
 get_stored_image_select_ready (QmiClientDms *client,
                                GAsyncResult *res)
@@ -3053,6 +3341,13 @@
     g_array_unref (pri_image_id.unique_id);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
+        * HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && \
+    defined HAVE_QMI_MESSAGE_DMS_DELETE_STORED_IMAGE
+
 static void
 delete_stored_image_ready (QmiClientDms *client,
                            GAsyncResult *res)
@@ -3135,6 +3430,12 @@
         g_array_unref (pri_image_id.unique_id);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
+        * HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES
+        * HAVE_QMI_MESSAGE_DMS_DELETE_STORED_IMAGE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FIRMWARE_PREFERENCE
+
 static void
 dms_get_firmware_preference_ready (QmiClientDms *client,
                                    GAsyncResult *res)
@@ -3191,6 +3492,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_FIRMWARE_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
+
 typedef struct {
     QmiMessageDmsSetFirmwarePreferenceInputListImage modem_image_id;
     QmiMessageDmsSetFirmwarePreferenceInputListImage pri_image_id;
@@ -3257,6 +3562,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BOOT_IMAGE_DOWNLOAD_MODE
+
 static void
 get_boot_image_download_mode_ready (QmiClientDms *client,
                                     GAsyncResult *res)
@@ -3291,6 +3600,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_BOOT_IMAGE_DOWNLOAD_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_BOOT_IMAGE_DOWNLOAD_MODE
+
 static QmiMessageDmsSetBootImageDownloadModeInput *
 set_boot_image_download_mode_input_create (const gchar *str)
 {
@@ -3346,6 +3659,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_BOOT_IMAGE_DOWNLOAD_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SOFTWARE_VERSION
+
 static void
 get_software_version_ready (QmiClientDms *client,
                             GAsyncResult *res)
@@ -3380,6 +3697,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif
+
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FCC_AUTHENTICATION
+
 static void
 set_fcc_authentication_ready (QmiClientDms *client,
                               GAsyncResult *res)
@@ -3410,6 +3731,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SET_FCC_AUTHENTICATION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientDms *client,
                               GAsyncResult *res)
@@ -3448,6 +3773,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_SUPPORTED_MESSAGES */
+
+#if defined HAVE_QMI_MESSAGE_DMS_HP_CHANGE_DEVICE_MODE
+
 static QmiMessageDmsHpChangeDeviceModeInput *
 hp_change_device_mode_input_create (const gchar *str)
 {
@@ -3506,6 +3835,10 @@
     operation_shutdown_skip_cid_release (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_HP_CHANGE_DEVICE_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_CURRENT_FIRMWARE
+
 static void
 swi_get_current_firmware_ready (QmiClientDms *client,
                                 GAsyncResult *res)
@@ -3578,6 +3911,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SWI_GET_CURRENT_FIRMWARE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_USB_COMPOSITION
+
 static void
 swi_get_usb_composition_ready (QmiClientDms *client,
                                GAsyncResult *res)
@@ -3631,6 +3968,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SWI_GET_USB_COMPOSITION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_SET_USB_COMPOSITION
+
 static void
 swi_set_usb_composition_ready (QmiClientDms *client,
                                GAsyncResult *res)
@@ -3687,6 +4028,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_SWI_SET_USB_COMPOSITION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
+
 static QmiMessageDmsFoxconnChangeDeviceModeInput *
 foxconn_change_device_mode_input_create (const gchar *str)
 {
@@ -3745,6 +4090,10 @@
     operation_shutdown_skip_cid_release (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE */
+
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
+
 static QmiMessageDmsFoxconnGetFirmwareVersionInput *
 foxconn_get_firmware_version_input_create (const gchar *str)
 {
@@ -3804,6 +4153,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION */
+
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MAC_ADDRESS
+
 static QmiMessageDmsGetMacAddressInput *
 get_mac_address_input_create (const gchar *str)
 {
@@ -3870,6 +4223,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_GET_MAC_ADDRESS */
+
+#if defined HAVE_QMI_MESSAGE_DMS_RESET
+
 static void
 reset_ready (QmiClientDms *client,
              GAsyncResult *res)
@@ -3900,6 +4257,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_DMS_RESET */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -3918,7 +4277,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get IDs? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_IDS
     if (get_ids_flag) {
         g_debug ("Asynchronously getting IDs...");
         qmi_client_dms_get_ids (ctx->client,
@@ -3929,8 +4288,9 @@
                                 NULL);
         return;
     }
+#endif
 
-    /* Request to get capabilities? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_CAPABILITIES
     if (get_capabilities_flag) {
         g_debug ("Asynchronously getting capabilities...");
         qmi_client_dms_get_capabilities (ctx->client,
@@ -3941,8 +4301,9 @@
                                          NULL);
         return;
     }
+#endif
 
-    /* Request to get manufacturer? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MANUFACTURER
     if (get_manufacturer_flag) {
         g_debug ("Asynchronously getting manufacturer...");
         qmi_client_dms_get_manufacturer (ctx->client,
@@ -3953,8 +4314,9 @@
                                          NULL);
         return;
     }
+#endif
 
-    /* Request to get model? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MODEL
     if (get_model_flag) {
         g_debug ("Asynchronously getting model...");
         qmi_client_dms_get_model (ctx->client,
@@ -3965,8 +4327,9 @@
                                   NULL);
         return;
     }
+#endif
 
-    /* Request to get revision? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_REVISION
     if (get_revision_flag) {
         g_debug ("Asynchronously getting revision...");
         qmi_client_dms_get_revision (ctx->client,
@@ -3977,8 +4340,9 @@
                                      NULL);
         return;
     }
+#endif
 
-    /* Request to get msisdn? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MSISDN
     if (get_msisdn_flag) {
         g_debug ("Asynchronously getting msisdn...");
         qmi_client_dms_get_msisdn (ctx->client,
@@ -3989,8 +4353,9 @@
                                    NULL);
         return;
     }
+#endif
 
-    /* Request to get power status? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_POWER_STATE
     if (get_power_state_flag) {
         g_debug ("Asynchronously getting power status...");
         qmi_client_dms_get_power_state (ctx->client,
@@ -4001,8 +4366,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to set PIN protection? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_PIN_PROTECTION
     if (uim_set_pin_protection_str) {
         QmiMessageDmsUimSetPinProtectionInput *input;
 
@@ -4021,8 +4387,9 @@
         qmi_message_dms_uim_set_pin_protection_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to verify PIN? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_VERIFY_PIN
     if (uim_verify_pin_str) {
         QmiMessageDmsUimVerifyPinInput *input;
 
@@ -4041,8 +4408,9 @@
         qmi_message_dms_uim_verify_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to unblock PIN? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_PIN
     if (uim_unblock_pin_str) {
         QmiMessageDmsUimUnblockPinInput *input;
 
@@ -4061,8 +4429,9 @@
         qmi_message_dms_uim_unblock_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to change the PIN? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_CHANGE_PIN
     if (uim_change_pin_str) {
         QmiMessageDmsUimChangePinInput *input;
 
@@ -4081,8 +4450,9 @@
         qmi_message_dms_uim_change_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get PIN status? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_PIN_STATUS
     if (uim_get_pin_status_flag) {
         g_debug ("Asynchronously getting PIN status...");
         qmi_client_dms_uim_get_pin_status (ctx->client,
@@ -4093,8 +4463,9 @@
                                            NULL);
         return;
     }
+#endif
 
-    /* Request to get UIM ICCID? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_ICCID
     if (uim_get_iccid_flag) {
         g_debug ("Asynchronously getting UIM ICCID...");
         qmi_client_dms_uim_get_iccid (ctx->client,
@@ -4105,8 +4476,9 @@
                                       NULL);
         return;
     }
+#endif
 
-    /* Request to get UIM IMSI? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_IMSI
     if (uim_get_imsi_flag) {
         g_debug ("Asynchronously getting UIM IMSI...");
         qmi_client_dms_uim_get_imsi (ctx->client,
@@ -4117,8 +4489,9 @@
                                      NULL);
         return;
     }
+#endif
 
-    /* Request to get UIM state? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_STATE
     if (uim_get_state_flag) {
         g_debug ("Asynchronously getting UIM state...");
         qmi_client_dms_uim_get_state (ctx->client,
@@ -4129,8 +4502,9 @@
                                       NULL);
         return;
     }
+#endif
 
-    /* Request to get hardware revision? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_HARDWARE_REVISION
     if (get_hardware_revision_flag) {
         g_debug ("Asynchronously getting hardware revision...");
         qmi_client_dms_get_hardware_revision (ctx->client,
@@ -4141,8 +4515,9 @@
                                               NULL);
         return;
     }
+#endif
 
-    /* Request to get operating mode? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_OPERATING_MODE
     if (get_operating_mode_flag) {
         g_debug ("Asynchronously getting operating mode...");
         qmi_client_dms_get_operating_mode (ctx->client,
@@ -4153,8 +4528,9 @@
                                            NULL);
         return;
     }
+#endif
 
-    /* Request to set operating mode? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_OPERATING_MODE
     if (set_operating_mode_str) {
         QmiMessageDmsSetOperatingModeInput *input;
 
@@ -4173,8 +4549,9 @@
         qmi_message_dms_set_operating_mode_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get time? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_TIME
     if (get_time_flag) {
         g_debug ("Asynchronously getting time...");
         qmi_client_dms_get_time (ctx->client,
@@ -4185,8 +4562,9 @@
                                  NULL);
         return;
     }
+#endif
 
-    /* Request to get the PRL version? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_PRL_VERSION
     if (get_prl_version_flag) {
         g_debug ("Asynchronously getting PRL version...");
         qmi_client_dms_get_prl_version (ctx->client,
@@ -4197,8 +4575,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to get the activation state? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_ACTIVATION_STATE
     if (get_activation_state_flag) {
         g_debug ("Asynchronously getting activation state...");
         qmi_client_dms_get_activation_state (ctx->client,
@@ -4209,8 +4588,9 @@
                                              NULL);
         return;
     }
+#endif
 
-    /* Request to activate automatically? */
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_AUTOMATIC
     if (activate_automatic_str) {
         QmiMessageDmsActivateAutomaticInput *input;
 
@@ -4229,8 +4609,9 @@
         qmi_message_dms_activate_automatic_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to activate manually? */
+#if defined HAVE_QMI_MESSAGE_DMS_ACTIVATE_MANUAL
     if (activate_manual_str) {
         QmiMessageDmsActivateManualInput *input;
 
@@ -4249,8 +4630,9 @@
         qmi_message_dms_activate_manual_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get the activation state? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_USER_LOCK_STATE
     if (get_user_lock_state_flag) {
         g_debug ("Asynchronously getting user lock state...");
         qmi_client_dms_get_user_lock_state (ctx->client,
@@ -4261,8 +4643,9 @@
                                             NULL);
         return;
     }
+#endif
 
-    /* Request to set user lock state? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_STATE
     if (set_user_lock_state_str) {
         QmiMessageDmsSetUserLockStateInput *input;
 
@@ -4281,8 +4664,9 @@
         qmi_message_dms_set_user_lock_state_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to set user lock code? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_USER_LOCK_CODE
     if (set_user_lock_code_str) {
         QmiMessageDmsSetUserLockCodeInput *input;
 
@@ -4301,8 +4685,9 @@
         qmi_message_dms_set_user_lock_code_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read user data? */
+#if defined HAVE_QMI_MESSAGE_DMS_READ_USER_DATA
     if (read_user_data_flag) {
         g_debug ("Asynchronously reading user data...");
         qmi_client_dms_read_user_data (ctx->client,
@@ -4313,8 +4698,9 @@
                                        NULL);
         return;
     }
+#endif
 
-    /* Request to write user data? */
+#if defined HAVE_QMI_MESSAGE_DMS_WRITE_USER_DATA
     if (write_user_data_str) {
         QmiMessageDmsWriteUserDataInput *input;
 
@@ -4333,8 +4719,9 @@
         qmi_message_dms_write_user_data_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read ERI file? */
+#if defined HAVE_QMI_MESSAGE_DMS_READ_ERI_FILE
     if (read_eri_file_flag) {
         g_debug ("Asynchronously reading ERI file...");
         qmi_client_dms_read_eri_file (ctx->client,
@@ -4345,8 +4732,9 @@
                                       NULL);
         return;
     }
+#endif
 
-    /* Request to restore factory defaults? */
+#if defined HAVE_QMI_MESSAGE_DMS_RESTORE_FACTORY_DEFAULTS
     if (restore_factory_defaults_str) {
         QmiMessageDmsRestoreFactoryDefaultsInput *input;
 
@@ -4365,8 +4753,9 @@
         qmi_message_dms_restore_factory_defaults_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to validate SPC? */
+#if defined HAVE_QMI_MESSAGE_DMS_VALIDATE_SERVICE_PROGRAMMING_CODE
     if (validate_service_programming_code_str) {
         QmiMessageDmsValidateServiceProgrammingCodeInput *input;
 
@@ -4385,8 +4774,9 @@
         qmi_message_dms_validate_service_programming_code_input_unref (input);
         return;
     }
+#endif
 
-    /* Set firmware id? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_ID
     if (set_firmware_id_flag) {
         g_debug ("Asynchronously setting firmware id...");
         qmi_client_dms_set_firmware_id (ctx->client,
@@ -4397,8 +4787,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to get CK status? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_GET_CK_STATUS
     if (uim_get_ck_status_str) {
         QmiMessageDmsUimGetCkStatusInput *input;
 
@@ -4417,8 +4808,9 @@
         qmi_message_dms_uim_get_ck_status_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to set CK protection? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_SET_CK_PROTECTION
     if (uim_set_ck_protection_str) {
         QmiMessageDmsUimSetCkProtectionInput *input;
 
@@ -4437,8 +4829,9 @@
         qmi_message_dms_uim_set_ck_protection_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to set CK protection? */
+#if defined HAVE_QMI_MESSAGE_DMS_UIM_UNBLOCK_CK
     if (uim_unblock_ck_str) {
         QmiMessageDmsUimUnblockCkInput *input;
 
@@ -4457,8 +4850,9 @@
         qmi_message_dms_uim_unblock_ck_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get band capabilities? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BAND_CAPABILITIES
     if (get_band_capabilities_flag) {
         g_debug ("Asynchronously getting band capabilities...");
         qmi_client_dms_get_band_capabilities (ctx->client,
@@ -4469,8 +4863,9 @@
                                               NULL);
         return;
     }
+#endif
 
-    /* Request to get factory SKU? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FACTORY_SKU
     if (get_factory_sku_flag) {
         g_debug ("Asynchronously getting factory SKU...");
         qmi_client_dms_get_factory_sku (ctx->client,
@@ -4481,8 +4876,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to list stored images? */
+#if defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && defined HAVE_QMI_MESSAGE_DMS_GET_STORED_IMAGE_INFO
     if (list_stored_images_flag) {
         g_debug ("Asynchronously listing stored images...");
         qmi_client_dms_list_stored_images (ctx->client,
@@ -4493,8 +4889,10 @@
                                            NULL);
         return;
     }
+#endif
 
-    /* Request to select stored image? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES
     if (select_stored_image_str) {
         g_debug ("Asynchronously selecting stored image...");
         get_stored_image (ctx->client,
@@ -4503,8 +4901,11 @@
                           NULL);
         return;
     }
+#endif
 
-    /* Request to delete stored image? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE && \
+    defined HAVE_QMI_MESSAGE_DMS_LIST_STORED_IMAGES && \
+    defined HAVE_QMI_MESSAGE_DMS_DELETE_STORED_IMAGE
     if (delete_stored_image_str) {
         g_debug ("Asynchronously deleting stored image...");
         get_stored_image (ctx->client,
@@ -4513,8 +4914,9 @@
                           NULL);
         return;
     }
+#endif
 
-    /* Get firmware preference? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_FIRMWARE_PREFERENCE
     if (get_firmware_preference_flag) {
         qmi_client_dms_get_firmware_preference (
             client,
@@ -4525,8 +4927,9 @@
             NULL);
         return;
     }
+#endif
 
-    /* Set firmware preference? */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FIRMWARE_PREFERENCE
     if (set_firmware_preference_str) {
         QmiMessageDmsSetFirmwarePreferenceInput *input;
         SetFirmwarePreferenceContext             firmware_preference_ctx;
@@ -4551,8 +4954,9 @@
         qmi_message_dms_set_firmware_preference_input_unref (input);
         return;
     }
+#endif
 
-    /* Get boot image download mode */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_BOOT_IMAGE_DOWNLOAD_MODE
     if (get_boot_image_download_mode_flag) {
         g_debug ("Asynchronously getting boot image download mode...");
         qmi_client_dms_get_boot_image_download_mode (ctx->client,
@@ -4563,8 +4967,9 @@
                                                      NULL);
         return;
     }
+#endif
 
-    /* Set boot image download mode */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_BOOT_IMAGE_DOWNLOAD_MODE
     if (set_boot_image_download_mode_str) {
         QmiMessageDmsSetBootImageDownloadModeInput *input;
 
@@ -4583,8 +4988,9 @@
         qmi_message_dms_set_boot_image_download_mode_input_unref (input);
         return;
     }
+#endif
 
-    /* Get software version */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SOFTWARE_VERSION
     if (get_software_version_flag) {
         g_debug ("Asynchronously getting software version...");
         qmi_client_dms_get_software_version (ctx->client,
@@ -4595,8 +5001,9 @@
                                              NULL);
         return;
     }
+#endif
 
-    /* Set FCC authentication */
+#if defined HAVE_QMI_MESSAGE_DMS_SET_FCC_AUTHENTICATION
     if (set_fcc_authentication_flag) {
         g_debug ("Asynchronously setting FCC auth...");
         qmi_client_dms_set_fcc_authentication (ctx->client,
@@ -4607,8 +5014,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported DMS messages...");
         qmi_client_dms_get_supported_messages (ctx->client,
@@ -4619,8 +5027,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to change device download mode */
+#if defined HAVE_QMI_MESSAGE_DMS_HP_CHANGE_DEVICE_MODE
     if (hp_change_device_mode_str) {
         QmiMessageDmsHpChangeDeviceModeInput *input;
 
@@ -4641,8 +5050,9 @@
         qmi_message_dms_hp_change_device_mode_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get current firmware */
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_CURRENT_FIRMWARE
     if (swi_get_current_firmware_flag) {
         g_debug ("Asynchronously getting current firmware (Sierra Wireless specific)...");
         qmi_client_dms_swi_get_current_firmware (ctx->client,
@@ -4653,8 +5063,9 @@
                                                  NULL);
         return;
     }
+#endif
 
-    /* Request to get current USB composition */
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_GET_USB_COMPOSITION
     if (swi_get_usb_composition_flag) {
         g_debug ("Asynchronously getting USB compositionss (Sierra Wireless specific)...");
         qmi_client_dms_swi_get_usb_composition (ctx->client,
@@ -4665,8 +5076,9 @@
                                                 NULL);
         return;
     }
+#endif
 
-    /* Request to set current USB composition */
+#if defined HAVE_QMI_MESSAGE_DMS_SWI_SET_USB_COMPOSITION
     if (swi_set_usb_composition_str) {
         QmiMessageDmsSwiSetUsbCompositionInput *input;
 
@@ -4687,8 +5099,9 @@
         qmi_message_dms_swi_set_usb_composition_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to change device download mode */
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_CHANGE_DEVICE_MODE
     if (foxconn_change_device_mode_str || dell_change_device_mode_str) {
         QmiMessageDmsFoxconnChangeDeviceModeInput *input;
 
@@ -4709,8 +5122,9 @@
         qmi_message_dms_foxconn_change_device_mode_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get firmware version? */
+#if defined HAVE_QMI_MESSAGE_DMS_FOXCONN_GET_FIRMWARE_VERSION
     if (foxconn_get_firmware_version_str || dell_get_firmware_version_str) {
         QmiMessageDmsFoxconnGetFirmwareVersionInput *input;
 
@@ -4731,8 +5145,9 @@
         qmi_message_dms_foxconn_get_firmware_version_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get MAC address? */
+#if defined HAVE_QMI_MESSAGE_DMS_GET_MAC_ADDRESS
     if (get_mac_address_str) {
         QmiMessageDmsGetMacAddressInput *input;
 
@@ -4753,8 +5168,9 @@
         qmi_message_dms_get_mac_address_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to reset DMS service? */
+#if defined HAVE_QMI_MESSAGE_DMS_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting DMS service...");
         qmi_client_dms_reset (ctx->client,
@@ -4765,6 +5181,7 @@
                               NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -4774,3 +5191,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_DMS */
diff --git a/src/qmicli/qmicli-dsd.c b/src/qmicli/qmicli-dsd.c
index 143d25c..543c777 100644
--- a/src/qmicli/qmicli-dsd.c
+++ b/src/qmicli/qmicli-dsd.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_DSD
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -47,14 +49,18 @@
 static gboolean  noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_DSD_GET_APN_INFO
     { "dsd-get-apn-info", 0, 0, G_OPTION_ARG_STRING, &get_apn_info_str,
       "Gets the settings associated to a given APN type",
       "[(type)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_DSD_SET_APN_TYPE
     { "dsd-set-apn-type", 0, 0, G_OPTION_ARG_STRING, &set_apn_type_str,
       "Sets the types associated to a given APN name",
       "[(name), (type1|type2|type3...)]"
     },
+#endif
     { "dsd-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a DSD client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -68,7 +74,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("dsd",
-                                "DSD options",
+                                "DSD options:",
                                 "Show Data System Determination options",
                                 NULL,
                                 NULL);
@@ -122,6 +128,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_DSD_GET_APN_INFO
+
 static void
 get_apn_info_ready (QmiClientDsd *client,
                     GAsyncResult *res)
@@ -180,6 +188,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_DSD_GET_APN_INFO */
+
+#if defined HAVE_QMI_MESSAGE_DSD_SET_APN_TYPE
+
 static void
 set_apn_type_ready (QmiClientDsd *client,
                     GAsyncResult *res)
@@ -247,6 +259,8 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_DSD_SET_APN_TYPE */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -265,7 +279,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get APN info? */
+#if defined HAVE_QMI_MESSAGE_DSD_GET_APN_INFO
     if (get_apn_info_str) {
         QmiMessageDsdGetApnInfoInput *input;
 
@@ -284,8 +298,9 @@
         qmi_message_dsd_get_apn_info_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to set APN type? */
+#if defined HAVE_QMI_MESSAGE_DSD_SET_APN_TYPE
     if (set_apn_type_str) {
         QmiMessageDsdSetApnTypeInput *input;
 
@@ -304,6 +319,7 @@
         qmi_message_dsd_set_apn_type_input_unref (input);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -313,3 +329,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_DSD */
diff --git a/src/qmicli/qmicli-gas.c b/src/qmicli/qmicli-gas.c
index 111b843..afdd750 100644
--- a/src/qmicli/qmicli-gas.c
+++ b/src/qmicli/qmicli-gas.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_GAS
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -48,6 +50,7 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_GET_FIRMWARE_LIST
     { "gas-dms-get-firmware-list", 0, 0, G_OPTION_ARG_NONE, &get_firmware_list_flag,
       "Gets the list of stored firmware",
       NULL
@@ -56,10 +59,13 @@
       "Gets the currently active firmware",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_SET_ACTIVE_FIRMWARE
     { "gas-dms-set-active-firmware", 0, 0, G_OPTION_ARG_INT, &set_active_firmware_int,
       "Sets the active firmware index",
       "[index]"
     },
+#endif
     { "gas-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a GAS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -73,7 +79,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("gas",
-                                "GAS options",
+                                "GAS options:",
                                 "Show General Application Service options",
                                 NULL,
                                 NULL);
@@ -128,6 +134,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_GET_FIRMWARE_LIST
+
 static void
 print_firmware_listing (guint8       idx,
                         const gchar *name,
@@ -189,6 +197,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_GAS_DMS_GET_FIRMWARE_LIST */
+
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_SET_ACTIVE_FIRMWARE
+
 static void
 set_active_firmware_ready (QmiClientGas *client,
                            GAsyncResult *res)
@@ -218,6 +230,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_GAS_DMS_SET_ACTIVE_FIRMWARE */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -236,15 +250,20 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get list of stored firmware? */
-    if (get_firmware_list_flag) {
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_GET_FIRMWARE_LIST
+    if (get_firmware_list_flag || get_active_firmware_flag) {
         QmiMessageGasDmsGetFirmwareListInput *input;
 
         input = qmi_message_gas_dms_get_firmware_list_input_new ();
-        qmi_message_gas_dms_get_firmware_list_input_set_mode (input,
-                                                              QMI_GAS_FIRMWARE_LISTING_MODE_ALL_FIRMWARE,
-                                                              NULL);
-        g_debug ("Asynchronously getting stored firmware list...");
+        if (get_firmware_list_flag) {
+            g_debug ("Asynchronously getting full firmware list...");
+            qmi_message_gas_dms_get_firmware_list_input_set_mode (input, QMI_GAS_FIRMWARE_LISTING_MODE_ALL_FIRMWARE, NULL);
+        } else if (get_active_firmware_flag) {
+            g_debug ("Asynchronously getting active firmware list...");
+            qmi_message_gas_dms_get_firmware_list_input_set_mode (input, QMI_GAS_FIRMWARE_LISTING_MODE_ACTIVE_FIRMWARE, NULL);
+        } else
+            g_assert_not_reached ();
+
         qmi_client_gas_dms_get_firmware_list (ctx->client,
                                               input,
                                               10,
@@ -254,27 +273,9 @@
         qmi_message_gas_dms_get_firmware_list_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get list of stored firmware? */
-    if (get_active_firmware_flag) {
-        QmiMessageGasDmsGetFirmwareListInput *input;
-
-        input = qmi_message_gas_dms_get_firmware_list_input_new ();
-        qmi_message_gas_dms_get_firmware_list_input_set_mode (input,
-                                                              QMI_GAS_FIRMWARE_LISTING_MODE_ACTIVE_FIRMWARE,
-                                                              NULL);
-        g_debug ("Asynchronously getting active firmware...");
-        qmi_client_gas_dms_get_firmware_list (ctx->client,
-                                              input,
-                                              10,
-                                              ctx->cancellable,
-                                              (GAsyncReadyCallback)get_firmware_list_ready,
-                                              NULL);
-        qmi_message_gas_dms_get_firmware_list_input_unref (input);
-        return;
-    }
-
-    /* Request to set active firmware index? */
+#if defined HAVE_QMI_MESSAGE_GAS_DMS_SET_ACTIVE_FIRMWARE
     if (set_active_firmware_int >= 0) {
         QmiMessageGasDmsSetActiveFirmwareInput *input;
 
@@ -290,6 +291,7 @@
         qmi_message_gas_dms_set_active_firmware_input_unref (input);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -299,3 +301,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_GAS */
diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-helpers.c
index 4c9e815..672673a 100644
--- a/src/qmicli/qmicli-helpers.c
+++ b/src/qmicli/qmicli-helpers.c
@@ -586,25 +586,37 @@
     g_return_val_if_fail (out != NULL, FALSE);
     g_return_val_if_fail (str, FALSE);
 
+    /* Ignore ':' digits in the binary string input */
+    for (len = 0, i = 0; str[i]; i++) {
+        if (str[i] == ':')
+            continue;
+        len++;
+    }
+
     /* Length must be a multiple of 2 */
-    len = strlen (str);
     if (len & 1)
         return FALSE;
 
     *out = g_array_sized_new (FALSE, TRUE, sizeof (guint8), len >> 1);
     g_array_set_size (*out, len >> 1);
 
-    for (i = 0, j = 0; i < len; i += 2, j++) {
+    i = 0;
+    j = 0;
+    while (str[i]) {
         gint a, b;
 
-        a = g_ascii_xdigit_value (str[i]);
-        b = g_ascii_xdigit_value (str[i + 1]);
+        while (str[i] == ':')
+            i++;
+        a = g_ascii_xdigit_value (str[i++]);
+        while (str[i] == ':')
+            i++;
+        b = g_ascii_xdigit_value (str[i++]);
         if (a < 0 || b < 0) {
             g_array_unref (*out);
             return FALSE;
         }
 
-        g_array_index (*out, guint8, j) = (a << 4) | b;
+        g_array_index (*out, guint8, j++) = (a << 4) | b;
     }
 
     return TRUE;
diff --git a/src/qmicli/qmicli-loc.c b/src/qmicli/qmicli-loc.c
index dab8a46..caddf30 100644
--- a/src/qmicli/qmicli-loc.c
+++ b/src/qmicli/qmicli-loc.c
@@ -34,6 +34,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_LOC
+
 /* Context */
 
 typedef enum {
@@ -72,56 +74,77 @@
 #define DEFAULT_LOC_TIMEOUT_SECS 30
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_LOC_START || defined HAVE_QMI_MESSAGE_LOC_STOP
     {
         "loc-session-id", 0, 0, G_OPTION_ARG_INT, &session_id,
         "Session ID for the LOC session",
         "[ID]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_LOC_START
     {
         "loc-start", 0, 0, G_OPTION_ARG_NONE, &start_flag,
         "Start location gathering",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_LOC_STOP
     {
         "loc-stop", 0, 0, G_OPTION_ARG_NONE, &stop_flag,
         "Stop location gathering",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-get-position-report", 0, 0, G_OPTION_ARG_NONE, &get_position_report_flag,
         "Get position reported by the location module",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-get-gnss-sv-info", 0, 0, G_OPTION_ARG_NONE, &get_gnss_sv_info_flag,
         "Show GNSS space vehicle info",
         NULL,
     },
+#endif
+#if (defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT || defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO) && \
+    defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-timeout", 0, 0, G_OPTION_ARG_INT, &timeout,
         "Maximum time to wait for information in `--loc-get-position-report' and `--loc-get-gnss-sv-info' (default 30s)",
         "[SECS]",
     },
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-follow-position-report", 0, 0, G_OPTION_ARG_NONE, &follow_position_report_flag,
         "Follow all position updates reported by the location module indefinitely",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-follow-gnss-sv-info", 0, 0, G_OPTION_ARG_NONE, &follow_gnss_sv_info_flag,
         "Follow all GNSS space vehicle info updates reported by the location module indefinitely",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_INDICATION_LOC_NMEA && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     {
         "loc-follow-nmea", 0, 0, G_OPTION_ARG_NONE, &follow_nmea_flag,
         "Follow all NMEA trace updates reported by the location module indefinitely",
         NULL,
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_LOC_DELETE_ASSISTANCE_DATA
     {
         "loc-delete-assistance-data", 0, 0, G_OPTION_ARG_NONE, &delete_assistance_data_flag,
         "Delete positioning assistance data",
         NULL,
     },
+#endif
     { "loc-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a LOC client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -135,7 +158,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("loc",
-                                "LOC options",
+                                "LOC options:",
                                 "Show location options", NULL, NULL);
     g_option_group_add_entries (group, entries);
 
@@ -229,6 +252,11 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if (defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT || \
+     defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO ||    \
+     defined HAVE_QMI_INDICATION_LOC_NMEA) &&           \
+    defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
+
 static void monitoring_step_run (void);
 
 static gboolean
@@ -259,6 +287,12 @@
     g_assert_not_reached ();
 }
 
+#endif /* HAVE_QMI_INDICATION_LOC_POSITION_REPORT
+        * HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO
+        * HAVE_QMI_INDICATION_LOC_NMEA */
+
+#if defined HAVE_QMI_INDICATION_LOC_NMEA && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
+
 static void
 nmea_received (QmiClientLoc               *client,
                QmiIndicationLocNmeaOutput *output)
@@ -271,6 +305,10 @@
         g_print ("%s", nmea);
 }
 
+#endif /* HAVE_QMI_INDICATION_LOC_NMEA */
+
+#if defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
+
 static void
 gnss_sv_info_received (QmiClientLoc                     *client,
                        QmiIndicationLocGnssSvInfoOutput *output)
@@ -323,6 +361,10 @@
         operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO */
+
+#if defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT && defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
+
 static void
 position_report_received (QmiClientLoc                         *client,
                           QmiIndicationLocPositionReportOutput *output)
@@ -534,26 +576,39 @@
         operation_shutdown (FALSE);
 }
 
+#endif /* HAVE_QMI_INDICATION_LOC_POSITION_REPORT */
+
+#if (defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT || \
+     defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO ||    \
+     defined HAVE_QMI_INDICATION_LOC_NMEA) && \
+    defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
+
 static void
 monitoring_step_ongoing (void)
 {
+#if defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT
     if (get_position_report_flag || follow_position_report_flag)
         ctx->position_report_indication_id = g_signal_connect (ctx->client,
                                                                "position-report",
                                                                G_CALLBACK (position_report_received),
                                                                NULL);
+#endif
 
+#if defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO
     if (get_gnss_sv_info_flag || follow_gnss_sv_info_flag)
         ctx->gnss_sv_info_indication_id = g_signal_connect (ctx->client,
                                                             "gnss-sv-info",
                                                             G_CALLBACK (gnss_sv_info_received),
                                                             NULL);
+#endif
 
+#if defined HAVE_QMI_INDICATION_LOC_NMEA
     if (follow_nmea_flag)
         ctx->nmea_indication_id = g_signal_connect (ctx->client,
                                                     "nmea",
                                                     G_CALLBACK (nmea_received),
                                                     NULL);
+#endif
 
     g_assert (ctx->position_report_indication_id ||
               ctx->gnss_sv_info_indication_id ||
@@ -668,6 +723,12 @@
     }
 }
 
+#endif /* HAVE_QMI_INDICATION_LOC_POSITION_REPORT
+        * HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO
+        * HAVE_QMI_INDICATION_LOC_NMEA */
+
+#if defined HAVE_QMI_MESSAGE_LOC_DELETE_ASSISTANCE_DATA
+
 static gboolean
 delete_assistance_data_timed_out (void)
 {
@@ -731,6 +792,10 @@
     qmi_message_loc_delete_assistance_data_output_unref (output);
 }
 
+#endif /* HAVE_QMI_MESSAGE_LOC_DELETE_ASSISTANCE_DATA */
+
+#if defined HAVE_QMI_MESSAGE_LOC_STOP
+
 static void
 stop_ready (QmiClientLoc *client,
             GAsyncResult *res)
@@ -761,6 +826,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_LOC_STOP */
+
+#if defined HAVE_QMI_MESSAGE_LOC_START
+
 static void
 start_ready (QmiClientLoc *client,
              GAsyncResult *res)
@@ -791,6 +860,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_LOC_START */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -809,7 +880,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to start location gathering? */
+#if defined HAVE_QMI_MESSAGE_LOC_START
     if (start_flag) {
         QmiMessageLocStartInput *input;
 
@@ -827,8 +898,9 @@
         qmi_message_loc_start_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to stop location gathering? */
+#if defined HAVE_QMI_MESSAGE_LOC_STOP
     if (stop_flag) {
         QmiMessageLocStopInput *input;
 
@@ -843,8 +915,9 @@
         qmi_message_loc_stop_input_unref (input);
         return;
     }
+#endif
 
-    /* Delete assistance data */
+#if defined HAVE_QMI_MESSAGE_LOC_DELETE_ASSISTANCE_DATA
     if (delete_assistance_data_flag) {
         QmiMessageLocDeleteAssistanceDataInput *input;
 
@@ -859,13 +932,19 @@
         qmi_message_loc_delete_assistance_data_input_unref (input);
         return;
     }
+#endif
 
-    /* All the remaining actions require monitoring */
+#if (defined HAVE_QMI_INDICATION_LOC_POSITION_REPORT || \
+     defined HAVE_QMI_INDICATION_LOC_GNSS_SV_INFO ||    \
+     defined HAVE_QMI_INDICATION_LOC_NMEA) &&           \
+    defined HAVE_QMI_MESSAGE_LOC_REGISTER_EVENTS
     if (get_position_report_flag || get_gnss_sv_info_flag || follow_position_report_flag || follow_gnss_sv_info_flag || follow_nmea_flag) {
+        /* All the remaining actions require monitoring */
         ctx->monitoring_step = MONITORING_STEP_FIRST;
         monitoring_step_run ();
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -875,3 +954,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_LOC */
diff --git a/src/qmicli/qmicli-nas.c b/src/qmicli/qmicli-nas.c
index af8aff5..7f5ba63 100644
--- a/src/qmicli/qmicli-nas.c
+++ b/src/qmicli/qmicli-nas.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_NAS
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -63,78 +65,114 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH
     { "nas-get-signal-strength", 0, 0, G_OPTION_ARG_NONE, &get_signal_strength_flag,
       "Get signal strength",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO
     { "nas-get-signal-info", 0, 0, G_OPTION_ARG_NONE, &get_signal_info_flag,
       "Get signal info",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TX_RX_INFO
     { "nas-get-tx-rx-info", 0, 0, G_OPTION_ARG_STRING, &get_tx_rx_info_str,
       "Get TX/RX info",
       "[(Radio Interface)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK
     { "nas-get-home-network", 0, 0, G_OPTION_ARG_NONE, &get_home_network_flag,
       "Get home network",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM
     { "nas-get-serving-system", 0, 0, G_OPTION_ARG_NONE, &get_serving_system_flag,
       "Get serving system",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO
     { "nas-get-system-info", 0, 0, G_OPTION_ARG_NONE, &get_system_info_flag,
       "Get system info",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TECHNOLOGY_PREFERENCE
     { "nas-get-technology-preference", 0, 0, G_OPTION_ARG_NONE, &get_technology_preference_flag,
       "Get technology preference",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE
     { "nas-get-system-selection-preference", 0, 0, G_OPTION_ARG_NONE, &get_system_selection_preference_flag,
       "Get system selection preference",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_SET_SYSTEM_SELECTION_PREFERENCE
     { "nas-set-system-selection-preference", 0, 0, G_OPTION_ARG_STRING, &set_system_selection_preference_str,
       "Set system selection preference",
       "[cdma-1x|cdma-1xevdo|gsm|umts|lte|td-scdma][,[automatic|manual=MCCMNC]]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN
     { "nas-network-scan", 0, 0, G_OPTION_ARG_NONE, &network_scan_flag,
       "Scan networks",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
     { "nas-get-cell-location-info", 0, 0, G_OPTION_ARG_NONE, &get_cell_location_info_flag,
       "Get Cell Location Info",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_FORCE_NETWORK_SEARCH
     { "nas-force-network-search", 0, 0, G_OPTION_ARG_NONE, &force_network_search_flag,
       "Force network search",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME
     { "nas-get-operator-name", 0, 0, G_OPTION_ARG_NONE, &get_operator_name_flag,
       "Get operator name data",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_LTE_CPHY_CA_INFO
     { "nas-get-lte-cphy-ca-info", 0, 0, G_OPTION_ARG_NONE, &get_lte_cphy_ca_info_flag,
       "Get LTE Cphy CA Info",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_RF_BAND_INFORMATION
     { "nas-get-rf-band-info", 0, 0, G_OPTION_ARG_NONE, &get_rf_band_info_flag,
       "Get RF Band Info",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SUPPORTED_MESSAGES
     { "nas-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_SWI_GET_STATUS
     { "nas-swi-get-status", 0, 0, G_OPTION_ARG_NONE, &swi_get_status_flag,
       "Get status ((Sierra Wireless specific)",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_NAS_RESET
     { "nas-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
     { "nas-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a NAS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -148,7 +186,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("nas",
-                                "NAS options",
+                                "NAS options:",
                                 "Show Network Access Service options",
                                 NULL,
                                 NULL);
@@ -218,6 +256,9 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO || \
+    defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH
+
 static gboolean
 get_db_from_sinr_level (QmiNasEvdoSinrLevel level,
                         gdouble *out)
@@ -258,6 +299,11 @@
     }
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO
+        * HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO
+
 static void
 get_signal_info_ready (QmiClientNas *client,
                        GAsyncResult *res)
@@ -379,6 +425,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH
+
 static QmiMessageNasGetSignalStrengthInput *
 get_signal_strength_input_create (void)
 {
@@ -542,6 +592,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TX_RX_INFO
+
 static void
 get_tx_rx_info_ready (QmiClientNas *client,
                       GAsyncResult *res,
@@ -697,6 +751,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_TX_RX_INFO */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK
+
 static void
 get_home_network_ready (QmiClientNas *client,
                         GAsyncResult *res)
@@ -802,6 +860,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM
+
 static void
 get_serving_system_ready (QmiClientNas *client,
                           GAsyncResult *res)
@@ -1243,6 +1305,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO
+
 static void
 get_system_info_ready (QmiClientNas *client,
                        GAsyncResult *res)
@@ -1969,6 +2035,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TECHNOLOGY_PREFERENCE
+
 static void
 get_technology_preference_ready (QmiClientNas *client,
                                  GAsyncResult *res)
@@ -2023,6 +2093,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_TECHNOLOGY_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE
+
 static void
 get_system_selection_preference_ready (QmiClientNas *client,
                                        GAsyncResult *res)
@@ -2264,6 +2338,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_NAS_SET_SYSTEM_SELECTION_PREFERENCE
+
 static QmiMessageNasSetSystemSelectionPreferenceInput *
 set_system_selection_preference_input_create (const gchar *str)
 {
@@ -2377,6 +2455,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_SET_SYSTEM_SELECTION_PREFERENCE */
+
+#if defined HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN
+
 static void
 network_scan_ready (QmiClientNas *client,
                     GAsyncResult *res)
@@ -2478,6 +2560,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
+
 static gchar *
 str_from_bcd_plmn (const gchar *bcd)
 {
@@ -3015,6 +3101,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO */
+
+#if defined HAVE_QMI_MESSAGE_NAS_FORCE_NETWORK_SEARCH
+
 static void
 force_network_search_ready (QmiClientNas *client,
                             GAsyncResult *res)
@@ -3044,6 +3134,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_FORCE_NETWORK_SEARCH */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME
+
 static void
 get_operator_name_ready (QmiClientNas *client,
                          GAsyncResult *res)
@@ -3176,6 +3270,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_LTE_CPHY_CA_INFO
+
 static void
 get_lte_cphy_ca_info_ready (QmiClientNas *client,
                             GAsyncResult *res)
@@ -3290,6 +3388,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_LTE_CPHY_CA_INFO */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_RF_BAND_INFORMATION
+
 static void
 get_rf_band_info_ready (QmiClientNas *client,
                         GAsyncResult *res)
@@ -3381,6 +3483,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_RF_BAND_INFORMATION */
+
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientNas *client,
                               GAsyncResult *res)
@@ -3419,9 +3525,13 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_GET_SUPPORTED_MESSAGES */
+
+#if defined HAVE_QMI_MESSAGE_NAS_SWI_GET_STATUS
+
 static void
 swi_get_status_ready (QmiClientNas *client,
-                              GAsyncResult *res)
+                      GAsyncResult *res)
 {
     QmiMessageNasSwiGetStatusOutput *output;
     GError *error = NULL;
@@ -3511,6 +3621,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_SWI_GET_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_NAS_RESET
+
 static void
 reset_ready (QmiClientNas *client,
              GAsyncResult *res)
@@ -3541,6 +3655,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_NAS_RESET */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -3559,7 +3675,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get signal strength? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_STRENGTH
     if (get_signal_strength_flag) {
         QmiMessageNasGetSignalStrengthInput *input;
 
@@ -3575,8 +3691,9 @@
         qmi_message_nas_get_signal_strength_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get signal info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SIGNAL_INFO
     if (get_signal_info_flag) {
         g_debug ("Asynchronously getting signal info...");
         qmi_client_nas_get_signal_info (ctx->client,
@@ -3587,8 +3704,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to get tx/rx info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TX_RX_INFO
     if (get_tx_rx_info_str) {
         QmiMessageNasGetTxRxInfoInput *input;
         QmiNasRadioInterface interface;
@@ -3610,8 +3728,9 @@
         qmi_message_nas_get_tx_rx_info_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get home network? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_HOME_NETWORK
     if (get_home_network_flag) {
         g_debug ("Asynchronously getting home network...");
         qmi_client_nas_get_home_network (ctx->client,
@@ -3622,8 +3741,9 @@
                                          NULL);
         return;
     }
+#endif
 
-    /* Request to get serving system? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SERVING_SYSTEM
     if (get_serving_system_flag) {
         g_debug ("Asynchronously getting serving system...");
         qmi_client_nas_get_serving_system (ctx->client,
@@ -3634,8 +3754,9 @@
                                            NULL);
         return;
     }
+#endif
 
-    /* Request to get system info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_INFO
     if (get_system_info_flag) {
         g_debug ("Asynchronously getting system info...");
         qmi_client_nas_get_system_info (ctx->client,
@@ -3646,8 +3767,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to get technology preference? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_TECHNOLOGY_PREFERENCE
     if (get_technology_preference_flag) {
         g_debug ("Asynchronously getting technology preference...");
         qmi_client_nas_get_technology_preference (ctx->client,
@@ -3658,8 +3780,9 @@
                                                   NULL);
         return;
     }
+#endif
 
-    /* Request to get system_selection preference? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SYSTEM_SELECTION_PREFERENCE
     if (get_system_selection_preference_flag) {
         g_debug ("Asynchronously getting system selection preference...");
         qmi_client_nas_get_system_selection_preference (ctx->client,
@@ -3670,8 +3793,9 @@
                                                         NULL);
         return;
     }
+#endif
 
-    /* Request to set system_selection preference? */
+#if defined HAVE_QMI_MESSAGE_NAS_SET_SYSTEM_SELECTION_PREFERENCE
     if (set_system_selection_preference_str) {
         QmiMessageNasSetSystemSelectionPreferenceInput *input;
         g_debug ("Asynchronously setting system selection preference...");
@@ -3691,8 +3815,9 @@
         qmi_message_nas_set_system_selection_preference_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to scan networks? */
+#if defined HAVE_QMI_MESSAGE_NAS_NETWORK_SCAN
     if (network_scan_flag) {
         g_debug ("Asynchronously scanning networks...");
         qmi_client_nas_network_scan (ctx->client,
@@ -3703,8 +3828,9 @@
                                      NULL);
         return;
     }
+#endif
 
-    /* Request to get cell location info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_CELL_LOCATION_INFO
     if (get_cell_location_info_flag) {
         g_debug ("Asynchronously getting cell location info ...");
         qmi_client_nas_get_cell_location_info (ctx->client,
@@ -3715,8 +3841,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to force network search */
+#if defined HAVE_QMI_MESSAGE_NAS_FORCE_NETWORK_SEARCH
     if (force_network_search_flag) {
         g_debug ("Forcing network search...");
         qmi_client_nas_force_network_search (ctx->client,
@@ -3727,8 +3854,9 @@
                                              NULL);
         return;
     }
+#endif
 
-    /* Request to get operator name data */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_OPERATOR_NAME
     if (get_operator_name_flag) {
         g_debug ("Asynchronously getting operator name data...");
         qmi_client_nas_get_operator_name (ctx->client,
@@ -3739,8 +3867,9 @@
                                           NULL);
         return;
     }
+#endif
 
-    /* Request to get carrier aggregation info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_LTE_CPHY_CA_INFO
     if (get_lte_cphy_ca_info_flag) {
         g_debug ("Asynchronously getting carrier aggregation info ...");
         qmi_client_nas_get_lte_cphy_ca_info (ctx->client,
@@ -3751,8 +3880,9 @@
                                              NULL);
         return;
     }
+#endif
 
-    /* Request to get rf band info? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_RF_BAND_INFORMATION
     if (get_rf_band_info_flag) {
         g_debug ("Asynchronously getting RF band info ...");
         qmi_client_nas_get_rf_band_information (ctx->client,
@@ -3763,8 +3893,9 @@
                                                 NULL);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_NAS_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported NAS messages...");
         qmi_client_nas_get_supported_messages (ctx->client,
@@ -3775,8 +3906,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to get status */
+#if defined HAVE_QMI_MESSAGE_NAS_SWI_GET_STATUS
     if (swi_get_status_flag) {
         g_debug ("Asynchronously getting status (Sierra Wireless specific)...");
         qmi_client_nas_swi_get_status (ctx->client,
@@ -3787,8 +3919,9 @@
                                        NULL);
         return;
     }
+#endif
 
-    /* Request to reset NAS service? */
+#if defined HAVE_QMI_MESSAGE_NAS_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting NAS service...");
         qmi_client_nas_reset (ctx->client,
@@ -3799,6 +3932,7 @@
                               NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -3808,3 +3942,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_NAS */
diff --git a/src/qmicli/qmicli-pbm.c b/src/qmicli/qmicli-pbm.c
index fb1aec0..ece89c6 100644
--- a/src/qmicli/qmicli-pbm.c
+++ b/src/qmicli/qmicli-pbm.c
@@ -32,6 +32,8 @@
 
 #include "qmicli.h"
 
+#if defined HAVE_QMI_SERVICE_PBM
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -45,10 +47,12 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_PBM_GET_ALL_CAPABILITIES
     { "pbm-get-all-capabilities", 0, 0, G_OPTION_ARG_NONE, &get_all_capabilities_flag,
       "Get all phonebook capabilities",
       NULL
     },
+#endif
     { "pbm-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a PBM client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -62,7 +66,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("pbm",
-                                "PBM options",
+                                "PBM options:",
                                 "Show Phonebook Management options",
                                 NULL,
                                 NULL);
@@ -113,6 +117,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_PBM_GET_ALL_CAPABILITIES
+
 static void
 get_all_capabilities_ready (QmiClientPbm *client,
                             GAsyncResult *res)
@@ -296,6 +302,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_PBM_GET_ALL_CAPABILITIES */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -314,7 +322,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get all capabilities? */
+#if defined HAVE_QMI_MESSAGE_PBM_GET_ALL_CAPABILITIES
     if (get_all_capabilities_flag) {
         g_debug ("Asynchronously getting phonebook capabilities...");
         qmi_client_pbm_get_all_capabilities (ctx->client,
@@ -325,6 +333,7 @@
                                              NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -334,3 +343,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_PBM */
diff --git a/src/qmicli/qmicli-pdc.c b/src/qmicli/qmicli-pdc.c
index 413c0df..59f1d61 100644
--- a/src/qmicli/qmicli-pdc.c
+++ b/src/qmicli/qmicli-pdc.c
@@ -15,7 +15,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright (C) 2013-2017 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2013-2020 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #include "config.h"
@@ -34,6 +34,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_PDC
+
 #define LIST_CONFIGS_TIMEOUT_SECS 2
 #define LOAD_CONFIG_CHUNK_SIZE 0x400
 
@@ -59,6 +61,7 @@
     QmiDevice *device;
     QmiClientPdc *client;
     GCancellable *cancellable;
+    gboolean skip_cid_release;
 
     /* local data */
     guint timeout_id;
@@ -76,6 +79,8 @@
 
     guint set_selected_config_indication_id;
     guint activate_config_indication_id;
+    guint device_removed_indication_id;
+
     guint deactivate_config_indication_id;
 
     guint token;
@@ -90,32 +95,68 @@
 static gchar *load_config_str;
 static gboolean noop_flag;
 
+#if defined HAVE_QMI_MESSAGE_PDC_LIST_CONFIGS && \
+    defined HAVE_QMI_INDICATION_PDC_LIST_CONFIGS && \
+    defined HAVE_QMI_MESSAGE_PDC_GET_SELECTED_CONFIG && \
+    defined HAVE_QMI_INDICATION_PDC_GET_SELECTED_CONFIG && \
+    defined HAVE_QMI_MESSAGE_PDC_GET_CONFIG_INFO && \
+    defined HAVE_QMI_INDICATION_PDC_GET_CONFIG_INFO
+# define HAVE_QMI_ACTION_PDC_LIST_CONFIGS
+#endif
+
+#if defined HAVE_QMI_MESSAGE_PDC_ACTIVATE_CONFIG && \
+    defined HAVE_QMI_INDICATION_PDC_ACTIVATE_CONFIG && \
+    defined HAVE_QMI_MESSAGE_PDC_SET_SELECTED_CONFIG && \
+    defined HAVE_QMI_INDICATION_PDC_SET_SELECTED_CONFIG
+# define HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG
+#endif
+
+#if defined HAVE_QMI_MESSAGE_PDC_DEACTIVATE_CONFIG && \
+    defined HAVE_QMI_INDICATION_PDC_DEACTIVATE_CONFIG
+# define HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG
+#endif
+
+#if defined HAVE_QMI_MESSAGE_PDC_LOAD_CONFIG && \
+    defined HAVE_QMI_INDICATION_PDC_LOAD_CONFIG
+# define HAVE_QMI_ACTION_PDC_LOAD_CONFIG
+#endif
+
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_ACTION_PDC_LIST_CONFIGS
     {
         "pdc-list-configs", 0, 0, G_OPTION_ARG_STRING, &list_configs_str,
         "List all configs",
         "[(platform|software)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG
     {
         "pdc-delete-config", 0, 0, G_OPTION_ARG_STRING, &delete_config_str,
         "Delete config",
         "[(platform|software),ConfigId]"
     },
+#endif
+#if defined HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG
     {
         "pdc-activate-config", 0, 0, G_OPTION_ARG_STRING, &activate_config_str,
         "Activate config",
         "[(platform|software),ConfigId]"
     },
+#endif
+#if defined HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG
     {
         "pdc-deactivate-config", 0, 0, G_OPTION_ARG_STRING, &deactivate_config_str,
         "Deactivate config",
         "[(platform|software),ConfigId]"
     },
+#endif
+#if defined HAVE_QMI_ACTION_PDC_LOAD_CONFIG
     {
         "pdc-load-config", 0, 0, G_OPTION_ARG_STRING, &load_config_str,
         "Load config to device",
         "[Path to config]"
     },
+#endif
     {
         "pdc-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
         "Just allocate or release a PDC client. Use with `--client-no-release-cid' and/or `--client-cid'",
@@ -130,7 +171,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("pdc",
-                                "PDC options",
+                                "PDC options:",
                                 "Show platform device configurations options", NULL, NULL);
     g_option_group_add_entries (group, entries);
 
@@ -217,6 +258,9 @@
     if (context->activate_config_indication_id)
         g_signal_handler_disconnect (context->client, context->activate_config_indication_id);
 
+    if (context->device_removed_indication_id)
+        g_signal_handler_disconnect (context->device, context->device_removed_indication_id);
+
     if (context->deactivate_config_indication_id)
         g_signal_handler_disconnect (context->client, context->deactivate_config_indication_id);
 
@@ -231,13 +275,62 @@
 operation_shutdown (gboolean operation_status)
 {
     /* Cleanup context and finish async operation */
+    qmicli_async_operation_done (operation_status, ctx->skip_cid_release);
     context_free (ctx);
     ctx = NULL;
-    qmicli_async_operation_done (operation_status, FALSE);
 }
 
 /******************************************************************************/
-/* List configs */
+/* Common */
+
+#if defined HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG || \
+    defined HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG || \
+    defined HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG
+
+static QmiConfigTypeAndId *
+parse_type_and_id (const gchar *str)
+{
+    GArray *id = NULL;
+    guint num_parts;
+    gchar **substrings;
+    QmiPdcConfigurationType config_type;
+    QmiConfigTypeAndId *result = NULL;
+
+    substrings = g_strsplit (str, ",", -1);
+    num_parts = g_strv_length (substrings);
+
+    if (num_parts != 2) {
+        g_printerr ("Expected 2 parameters, but found %u\n", num_parts);
+        g_strfreev (substrings);
+        return NULL;
+    }
+
+    if (!qmicli_read_pdc_configuration_type_from_string (substrings[0], &config_type)) {
+        g_printerr ("Incorrect id specified: %s\n", substrings[0]);
+        g_strfreev (substrings);
+        return NULL;
+    }
+
+    if (!qmicli_read_binary_array_from_string (substrings[1], &id)) {
+        g_printerr ("Incorrect config type specified: %s\n", substrings[1]);
+        g_strfreev (substrings);
+        return NULL;
+    }
+
+    result = g_slice_new0 (QmiConfigTypeAndId);
+    result->config_type = config_type;
+    result->id = id;
+    return result;
+}
+
+#endif /* HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG
+        * HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG
+        * HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG */
+
+/******************************************************************************/
+/* List configs and get selected config */
+
+#if defined HAVE_QMI_ACTION_PDC_LIST_CONFIGS
 
 static const char *
 status_string (GArray *id)
@@ -387,32 +480,6 @@
 }
 
 static void
-list_configs_ready (QmiClientPdc *client,
-                    GAsyncResult *res)
-{
-    GError *error = NULL;
-    QmiMessagePdcListConfigsOutput *output;
-
-    output = qmi_client_pdc_list_configs_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (!qmi_message_pdc_list_configs_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't list configs: %s\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_list_configs_output_unref (output);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_list_configs_output_unref (output);
-}
-
-static void
 list_configs_ready_indication (QmiClientPdc *client,
                                QmiIndicationPdcListConfigsOutput *output)
 {
@@ -498,22 +565,51 @@
 }
 
 static void
-get_selected_config_ready (QmiClientPdc *client,
-                           GAsyncResult *res)
+list_configs_ready (QmiClientPdc *client,
+                    GAsyncResult *res)
 {
     GError *error = NULL;
-    QmiMessagePdcGetSelectedConfigOutput *output;
+    QmiMessagePdcListConfigsOutput *output;
 
-    output = qmi_client_pdc_get_selected_config_finish (client, res, &error);
-    if (!qmi_message_pdc_get_selected_config_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't get selected config: %s\n", error->message);
+    output = qmi_client_pdc_list_configs_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
         g_error_free (error);
-        qmi_message_pdc_get_selected_config_output_unref (output);
         operation_shutdown (FALSE);
         return;
     }
 
-    qmi_message_pdc_get_selected_config_output_unref (output);
+    if (!qmi_message_pdc_list_configs_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't list configs: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_list_configs_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    qmi_message_pdc_list_configs_output_unref (output);
+}
+
+static QmiMessagePdcListConfigsInput *
+list_configs_input_create (const gchar *str)
+{
+    QmiMessagePdcListConfigsInput *input = NULL;
+    QmiPdcConfigurationType config_type;
+    GError *error = NULL;
+
+    if (!qmicli_read_pdc_configuration_type_from_string (str, &config_type))
+        return NULL;
+
+    input = qmi_message_pdc_list_configs_input_new ();
+    if (!qmi_message_pdc_list_configs_input_set_config_type (input, config_type, &error) ||
+        !qmi_message_pdc_list_configs_input_set_token (input, ctx->token++, &error)) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_list_configs_input_unref (input);
+        return NULL;
+    }
+
+    return input;
 }
 
 static void
@@ -553,112 +649,22 @@
 }
 
 static void
-activate_config_ready_indication (QmiClientPdc *client,
-                                  QmiIndicationPdcActivateConfigOutput *output)
+get_selected_config_ready (QmiClientPdc *client,
+                           GAsyncResult *res)
 {
     GError *error = NULL;
-    guint16 error_code = 0;
+    QmiMessagePdcGetSelectedConfigOutput *output;
 
-    if (!qmi_indication_pdc_activate_config_output_get_indication_result (output, &error_code, &error)) {
-        g_printerr ("error: couldn't activate config: %s\n", error->message);
+    output = qmi_client_pdc_get_selected_config_finish (client, res, &error);
+    if (!qmi_message_pdc_get_selected_config_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't get selected config: %s\n", error->message);
         g_error_free (error);
+        qmi_message_pdc_get_selected_config_output_unref (output);
         operation_shutdown (FALSE);
         return;
     }
 
-    if (error_code != 0) {
-        g_printerr ("error: couldn't activate config: %s\n",
-                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    operation_shutdown (TRUE);
-}
-
-static void
-deactivate_config_ready_indication (QmiClientPdc *client,
-                                    QmiIndicationPdcDeactivateConfigOutput *output)
-{
-    GError *error = NULL;
-    guint16 error_code = 0;
-
-    if (!qmi_indication_pdc_deactivate_config_output_get_indication_result (output, &error_code, &error)) {
-        g_printerr ("error: couldn't deactivate config: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (error_code != 0) {
-        g_printerr ("error: couldn't deactivate config: %s\n",
-                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    operation_shutdown (TRUE);
-}
-
-static QmiMessagePdcListConfigsInput *
-list_configs_input_create (const gchar *str)
-{
-    QmiMessagePdcListConfigsInput *input = NULL;
-    QmiPdcConfigurationType config_type;
-    GError *error = NULL;
-
-    if (!qmicli_read_pdc_configuration_type_from_string (str, &config_type))
-        return NULL;
-
-    input = qmi_message_pdc_list_configs_input_new ();
-    if (!qmi_message_pdc_list_configs_input_set_config_type (input, config_type, &error) ||
-        !qmi_message_pdc_list_configs_input_set_token (input, ctx->token++, &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_list_configs_input_unref (input);
-        return NULL;
-    }
-
-    return input;
-}
-
-/******************************************************************************/
-/* Activate and deactivate configs */
-
-static QmiConfigTypeAndId *
-parse_type_and_id (const gchar *str)
-{
-    GArray *id = NULL;
-    guint num_parts;
-    gchar **substrings;
-    QmiPdcConfigurationType config_type;
-    QmiConfigTypeAndId *result = NULL;
-
-    substrings = g_strsplit (str, ",", -1);
-    num_parts = g_strv_length (substrings);
-
-    if (num_parts != 2) {
-        g_printerr ("Expected 2 parameters, but found %u\n", num_parts);
-        g_strfreev (substrings);
-        return NULL;
-    }
-
-    if (!qmicli_read_pdc_configuration_type_from_string (substrings[0], &config_type)) {
-        g_printerr ("Incorrect id specified: %s\n", substrings[0]);
-        g_strfreev (substrings);
-        return NULL;
-    }
-
-    if (!qmicli_read_binary_array_from_string (substrings[1], &id)) {
-        g_printerr ("Incorrect config type specified: %s\n", substrings[1]);
-        g_strfreev (substrings);
-        return NULL;
-    }
-
-    result = g_slice_new0 (QmiConfigTypeAndId);
-    result->config_type = config_type;
-    result->id = id;
-    return result;
+    qmi_message_pdc_get_selected_config_output_unref (output);
 }
 
 static QmiMessagePdcGetSelectedConfigInput *
@@ -683,6 +689,429 @@
     return input;
 }
 
+static void
+run_list_configs (void)
+{
+    QmiMessagePdcListConfigsInput *input;
+    QmiMessagePdcGetSelectedConfigInput *get_selected_config_input;
+
+    g_debug ("Listing configs asynchronously...");
+
+    /* Results are reported via indications */
+    ctx->list_configs_indication_id =
+        g_signal_connect (ctx->client,
+                          "list-configs",
+                          G_CALLBACK
+                          (list_configs_ready_indication), NULL);
+    ctx->get_selected_config_indication_id =
+        g_signal_connect (ctx->client, "get-selected-config",
+                          G_CALLBACK (get_selected_config_ready_indication), NULL);
+    ctx->get_config_info_indication_id =
+        g_signal_connect (ctx->client, "get-config-info",
+                          G_CALLBACK (get_config_info_ready_indication), NULL);
+
+    input = list_configs_input_create (list_configs_str);
+    if (!input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    get_selected_config_input = get_selected_config_input_create (list_configs_str);
+    if (!get_selected_config_input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    /* We need a timeout, because there will be no indications if no configs
+     * are loaded */
+    ctx->timeout_id = g_timeout_add_seconds (LIST_CONFIGS_TIMEOUT_SECS,
+                                             (GSourceFunc) list_configs_timeout,
+                                             NULL);
+
+    qmi_client_pdc_list_configs (ctx->client,
+                                 input,
+                                 10,
+                                 ctx->cancellable,
+                                 (GAsyncReadyCallback) list_configs_ready,
+                                 NULL);
+    qmi_message_pdc_list_configs_input_unref (input);
+
+    qmi_client_pdc_get_selected_config (ctx->client,
+                                        get_selected_config_input,
+                                        10,
+                                        ctx->cancellable,
+                                        (GAsyncReadyCallback) get_selected_config_ready,
+                                        NULL);
+    qmi_message_pdc_get_selected_config_input_unref (get_selected_config_input);
+}
+
+#endif /* HAVE_QMI_ACTION_PDC_LIST_CONFIGS */
+
+/******************************************************************************/
+/* Activate config */
+
+#if defined HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG
+
+static void
+device_removed_indication (QmiDevice *device)
+{
+    g_print ("[%s] Successfully requested config activation\n",
+             qmi_device_get_path_display (ctx->device));
+
+    /* Device gone, don't attempt to release CIDs */
+    ctx->skip_cid_release = TRUE;
+
+    /* If device gets removed during an activate config operation,
+     * it means the operation is successful */
+    operation_shutdown (TRUE);
+}
+
+static void
+activate_config_ready_indication (QmiClientPdc *client,
+                                  QmiIndicationPdcActivateConfigOutput *output)
+{
+    GError *error = NULL;
+    guint16 error_code = 0;
+
+    if (!qmi_indication_pdc_activate_config_output_get_indication_result (output, &error_code, &error)) {
+        g_printerr ("error: couldn't activate config: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (error_code != 0) {
+        g_printerr ("error: couldn't activate config: %s\n",
+                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    /* NOTE: config activation is expected to reboot the device, so we may detect the
+     * actual reboot before receiving this indication */
+
+    g_print ("[%s] Successfully requested config activation\n",
+             qmi_device_get_path_display (ctx->device));
+
+    operation_shutdown (TRUE);
+}
+
+static void
+activate_config_ready (QmiClientPdc *client,
+                       GAsyncResult *res)
+{
+    GError *error = NULL;
+    QmiMessagePdcActivateConfigOutput *output;
+
+    output = qmi_client_pdc_activate_config_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_pdc_activate_config_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't activate config: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_activate_config_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    qmi_message_pdc_activate_config_output_unref (output);
+}
+
+static QmiMessagePdcActivateConfigInput *
+activate_config_input_create (const gchar *str)
+{
+    QmiMessagePdcActivateConfigInput *input = NULL;
+    QmiConfigTypeAndId *type_and_id;
+    GError *error = NULL;
+
+    type_and_id = parse_type_and_id (str);
+    if (!type_and_id)
+        return NULL;
+
+    input = qmi_message_pdc_activate_config_input_new ();
+    if (!qmi_message_pdc_activate_config_input_set_config_type (input, type_and_id->config_type, &error) ||
+        !qmi_message_pdc_activate_config_input_set_token (input, ctx->token++, &error)) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_activate_config_input_unref (input);
+        input = NULL;
+    }
+
+    g_array_unref (type_and_id->id);
+    g_slice_free (QmiConfigTypeAndId, type_and_id);
+    return input;
+}
+
+static void
+set_selected_config_ready_indication (QmiClientPdc *client,
+                                      QmiIndicationPdcSetSelectedConfigOutput *output)
+{
+    GError *error = NULL;
+    QmiMessagePdcActivateConfigInput *input;
+    guint16 error_code = 0;
+
+    if (!qmi_indication_pdc_set_selected_config_output_get_indication_result (output, &error_code, &error)) {
+        g_printerr ("error: couldn't set selected config: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (error_code != 0) {
+        g_printerr ("error: couldn't set selected config: %s\n",
+                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    input = activate_config_input_create (activate_config_str);
+    if (!input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    ctx->activate_config_indication_id =
+        g_signal_connect (ctx->client,
+                          "activate-config",
+                          G_CALLBACK (activate_config_ready_indication),
+                          NULL);
+    ctx->device_removed_indication_id =
+        g_signal_connect (ctx->device,
+                          QMI_DEVICE_SIGNAL_REMOVED,
+                          G_CALLBACK (device_removed_indication),
+                          NULL);
+    qmi_client_pdc_activate_config (ctx->client,
+                                    input,
+                                    10,
+                                    ctx->cancellable,
+                                    (GAsyncReadyCallback) activate_config_ready, NULL);
+    qmi_message_pdc_activate_config_input_unref (input);
+}
+
+static void
+set_selected_config_ready (QmiClientPdc *client,
+                           GAsyncResult *res)
+{
+    GError *error = NULL;
+    QmiMessagePdcSetSelectedConfigOutput *output;
+
+    output = qmi_client_pdc_set_selected_config_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    qmi_message_pdc_set_selected_config_output_unref (output);
+}
+
+static QmiMessagePdcSetSelectedConfigInput *
+set_selected_config_input_create (const gchar *str)
+{
+    QmiMessagePdcSetSelectedConfigInput *input = NULL;
+    QmiConfigTypeAndId *type_and_id;
+    GError *error = NULL;
+
+    type_and_id = parse_type_and_id (str);
+    if (!type_and_id)
+        return NULL;
+
+    input = qmi_message_pdc_set_selected_config_input_new ();
+    if (!qmi_message_pdc_set_selected_config_input_set_type_with_id (input, type_and_id, &error) ||
+        !qmi_message_pdc_set_selected_config_input_set_token (input, ctx->token++, &error)) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_set_selected_config_input_unref (input);
+        input = NULL;
+    }
+
+    g_array_unref (type_and_id->id);
+    g_slice_free (QmiConfigTypeAndId, type_and_id);
+    return input;
+}
+
+static void
+run_activate_config (void)
+{
+    QmiMessagePdcSetSelectedConfigInput *input;
+
+    g_debug ("Activating config asynchronously...");
+    input = set_selected_config_input_create (activate_config_str);
+    if (!input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    /* Results are reported via indications */
+    ctx->set_selected_config_indication_id =
+        g_signal_connect (ctx->client,
+                          "set-selected-config",
+                          G_CALLBACK (set_selected_config_ready_indication), NULL);
+    qmi_client_pdc_set_selected_config (ctx->client,
+                                        input,
+                                        10,
+                                        ctx->cancellable,
+                                        (GAsyncReadyCallback) set_selected_config_ready,
+                                        NULL);
+    qmi_message_pdc_set_selected_config_input_unref (input);
+}
+
+#endif /* HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG */
+
+/******************************************************************************/
+/* Deactivate config */
+
+#if defined HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG
+
+static void
+deactivate_config_ready_indication (QmiClientPdc *client,
+                                    QmiIndicationPdcDeactivateConfigOutput *output)
+{
+    GError *error = NULL;
+    guint16 error_code = 0;
+
+    if (!qmi_indication_pdc_deactivate_config_output_get_indication_result (output, &error_code, &error)) {
+        g_printerr ("error: couldn't deactivate config: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (error_code != 0) {
+        g_printerr ("error: couldn't deactivate config: %s\n",
+                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully requested config deactivation\n",
+             qmi_device_get_path_display (ctx->device));
+
+    operation_shutdown (TRUE);
+}
+
+static void
+deactivate_config_ready (QmiClientPdc *client,
+                         GAsyncResult *res)
+{
+    GError *error = NULL;
+    QmiMessagePdcDeactivateConfigOutput *output;
+
+    output = qmi_client_pdc_deactivate_config_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_pdc_deactivate_config_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't deactivate config: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_deactivate_config_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    qmi_message_pdc_deactivate_config_output_unref (output);
+}
+
+static QmiMessagePdcDeactivateConfigInput *
+deactivate_config_input_create (const gchar *str)
+{
+    QmiMessagePdcDeactivateConfigInput *input = NULL;
+    QmiConfigTypeAndId *type_and_id;
+    GError *error = NULL;
+
+    type_and_id = parse_type_and_id (str);
+    if (!type_and_id)
+        return NULL;
+
+    input = qmi_message_pdc_deactivate_config_input_new ();
+    if (!qmi_message_pdc_deactivate_config_input_set_config_type (input, type_and_id->config_type, &error) ||
+        !qmi_message_pdc_deactivate_config_input_set_token (input, ctx->token++, &error)) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_deactivate_config_input_unref (input);
+        input = NULL;
+    }
+
+    g_array_unref (type_and_id->id);
+    g_slice_free (QmiConfigTypeAndId, type_and_id);
+    return input;
+}
+
+static void
+run_deactivate_config (void)
+{
+    QmiMessagePdcDeactivateConfigInput *input;
+
+    g_debug ("Deactivating config asynchronously...");
+    input = deactivate_config_input_create (deactivate_config_str);
+    if (!input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    /* Results are reported via indications */
+    ctx->deactivate_config_indication_id =
+        g_signal_connect (ctx->client,
+                          "deactivate-config",
+                          G_CALLBACK
+                          (deactivate_config_ready_indication),
+                          NULL);
+
+    qmi_client_pdc_deactivate_config (ctx->client,
+                                      input,
+                                      10,
+                                      ctx->cancellable,
+                                      (GAsyncReadyCallback) deactivate_config_ready, NULL);
+    qmi_message_pdc_deactivate_config_input_unref (input);
+}
+
+#endif /* HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG */
+
+/******************************************************************************/
+/* Delete config */
+
+#if defined HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG
+
+static void
+delete_config_ready (QmiClientPdc *client,
+                     GAsyncResult *res)
+{
+    GError *error = NULL;
+    QmiMessagePdcDeleteConfigOutput *output;
+
+    output = qmi_client_pdc_delete_config_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_pdc_delete_config_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't delete config: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_delete_config_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully deleted config\n",
+             qmi_device_get_path_display (ctx->device));
+
+    qmi_message_pdc_delete_config_output_unref (output);
+    operation_shutdown (TRUE);
+}
+
 static QmiMessagePdcDeleteConfigInput *
 delete_config_input_create (const gchar *str)
 {
@@ -710,252 +1139,32 @@
 }
 
 static void
-delete_config_ready (QmiClientPdc *client,
-                     GAsyncResult *res)
+run_delete_config (void)
 {
-    GError *error = NULL;
-    QmiMessagePdcDeleteConfigOutput *output;
+    QmiMessagePdcDeleteConfigInput *input;
 
-    output = qmi_client_pdc_delete_config_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (!qmi_message_pdc_delete_config_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't delete config: %s\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_delete_config_output_unref (output);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_delete_config_output_unref (output);
-    operation_shutdown (TRUE);
-}
-
-static QmiMessagePdcActivateConfigInput *
-activate_config_input_create (const gchar *str)
-{
-    QmiMessagePdcActivateConfigInput *input = NULL;
-    QmiConfigTypeAndId *type_and_id;
-    GError *error = NULL;
-
-    type_and_id = parse_type_and_id (str);
-    if (!type_and_id)
-        return NULL;
-
-    input = qmi_message_pdc_activate_config_input_new ();
-    if (!qmi_message_pdc_activate_config_input_set_config_type (input, type_and_id->config_type, &error) ||
-        !qmi_message_pdc_activate_config_input_set_token (input, ctx->token++, &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_activate_config_input_unref (input);
-        input = NULL;
-    }
-
-    g_array_unref (type_and_id->id);
-    g_slice_free (QmiConfigTypeAndId, type_and_id);
-    return input;
-}
-
-static void
-activate_config_ready (QmiClientPdc *client,
-                       GAsyncResult *res)
-{
-    GError *error = NULL;
-    QmiMessagePdcActivateConfigOutput *output;
-
-    output = qmi_client_pdc_activate_config_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (!qmi_message_pdc_activate_config_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't activate config: %s\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_activate_config_output_unref (output);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_activate_config_output_unref (output);
-}
-
-static void
-deactivate_config_ready (QmiClientPdc *client,
-                         GAsyncResult *res)
-{
-    GError *error = NULL;
-    QmiMessagePdcDeactivateConfigOutput *output;
-
-    output = qmi_client_pdc_deactivate_config_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (!qmi_message_pdc_deactivate_config_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't deactivate config: %s\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_deactivate_config_output_unref (output);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_deactivate_config_output_unref (output);
-}
-
-static void
-set_selected_config_ready_indication_activation (QmiClientPdc *client,
-                                                 QmiIndicationPdcSetSelectedConfigOutput *output)
-{
-    GError *error = NULL;
-    QmiMessagePdcActivateConfigInput *input;
-    guint16 error_code = 0;
-
-    if (!qmi_indication_pdc_set_selected_config_output_get_indication_result (output, &error_code, &error)) {
-        g_printerr ("error: couldn't set selected config: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (error_code != 0) {
-        g_printerr ("error: couldn't set selected config: %s\n",
-                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    input = activate_config_input_create (activate_config_str);
+    g_debug ("Deleting config asynchronously...");
+    input = delete_config_input_create (delete_config_str);
     if (!input) {
         operation_shutdown (FALSE);
         return;
     }
 
-    qmi_client_pdc_activate_config (ctx->client,
-                                    input,
-                                    10,
-                                    ctx->cancellable,
-                                    (GAsyncReadyCallback) activate_config_ready, NULL);
-    qmi_message_pdc_activate_config_input_unref (input);
+    qmi_client_pdc_delete_config (ctx->client,
+                                  input,
+                                  10,
+                                  ctx->cancellable,
+                                  (GAsyncReadyCallback) delete_config_ready, NULL);
+    qmi_message_pdc_delete_config_input_unref (input);
 }
 
-static void
-set_selected_config_ready (QmiClientPdc *client,
-                           GAsyncResult *res)
-{
-    GError *error = NULL;
-    QmiMessagePdcSetSelectedConfigOutput *output;
-
-    output = qmi_client_pdc_set_selected_config_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_set_selected_config_output_unref (output);
-}
-
-static QmiMessagePdcDeactivateConfigInput *
-deactivate_config_input_create (const gchar *str)
-{
-    QmiMessagePdcDeactivateConfigInput *input = NULL;
-    QmiConfigTypeAndId *type_and_id;
-    GError *error = NULL;
-
-    type_and_id = parse_type_and_id (str);
-    if (!type_and_id)
-        return NULL;
-
-    input = qmi_message_pdc_deactivate_config_input_new ();
-    if (!qmi_message_pdc_deactivate_config_input_set_config_type (input, type_and_id->config_type, &error) ||
-        !qmi_message_pdc_deactivate_config_input_set_token (input, ctx->token++, &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_deactivate_config_input_unref (input);
-        input = NULL;
-    }
-
-    g_array_unref (type_and_id->id);
-    g_slice_free (QmiConfigTypeAndId, type_and_id);
-    return input;
-}
-
-static void
-set_selected_config_ready_indication_deactivation (QmiClientPdc *client,
-                                                   QmiIndicationPdcSetSelectedConfigOutput *output)
-{
-    GError *error = NULL;
-    QmiMessagePdcDeactivateConfigInput *input;
-    guint16 error_code = 0;
-
-    if (!qmi_indication_pdc_set_selected_config_output_get_indication_result (output, &error_code, &error)) {
-        g_printerr ("error: couldn't set selected config: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (error_code != 0) {
-        g_printerr ("error: couldn't set selected config: %s\n",
-                    qmi_protocol_error_get_string ((QmiProtocolError) error_code));
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    input = deactivate_config_input_create (activate_config_str);
-    if (!input) {
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_client_pdc_deactivate_config (ctx->client,
-                                      input,
-                                      10,
-                                      ctx->cancellable,
-                                      (GAsyncReadyCallback) deactivate_config_ready, NULL);
-    qmi_message_pdc_deactivate_config_input_unref (input);
-}
-
-static QmiMessagePdcSetSelectedConfigInput *
-set_selected_config_input_create (const gchar *str)
-{
-    QmiMessagePdcSetSelectedConfigInput *input = NULL;
-    QmiConfigTypeAndId *type_and_id;
-    GError *error = NULL;
-
-    type_and_id = parse_type_and_id (str);
-    if (!type_and_id)
-        return NULL;
-
-    input = qmi_message_pdc_set_selected_config_input_new ();
-    if (!qmi_message_pdc_set_selected_config_input_set_type_with_id (input, type_and_id, &error) ||
-        !qmi_message_pdc_set_selected_config_input_set_token (input, ctx->token++, &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_set_selected_config_input_unref (input);
-        input = NULL;
-    }
-
-    g_array_unref (type_and_id->id);
-    g_slice_free (QmiConfigTypeAndId, type_and_id);
-    return input;
-}
+#endif /* HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG */
 
 /******************************************************************************/
 /* Load config */
 
+#if defined HAVE_QMI_ACTION_PDC_LOAD_CONFIG
+
 static LoadConfigFileData *
 load_config_file_from_string (const gchar *str)
 {
@@ -1045,49 +1254,8 @@
     return input;
 }
 
-static QmiMessagePdcLoadConfigInput *
-load_config_input_create (const gchar *str)
-{
-    LoadConfigFileData *config_file;
-    QmiMessagePdcLoadConfigInput *input = NULL;
-
-    config_file = load_config_file_from_string (str);
-    if (!config_file)
-        return NULL;
-
-    input = load_config_input_create_chunk (config_file);
-    if (!input)
-        return NULL;
-
-    ctx->load_config_file_data = config_file;
-    return input;
-}
-
-static void
-load_config_ready (QmiClientPdc *client,
-                   GAsyncResult *res)
-{
-    GError *error = NULL;
-    QmiMessagePdcLoadConfigOutput *output;
-
-    output = qmi_client_pdc_load_config_finish (client, res, &error);
-    if (!output) {
-        g_printerr ("error: operation failed: %s\n", error->message);
-        g_error_free (error);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    if (!qmi_message_pdc_load_config_output_get_result (output, &error)) {
-        g_printerr ("error: couldn't load config: %s\n", error->message);
-        g_error_free (error);
-        qmi_message_pdc_load_config_output_unref (output);
-        operation_shutdown (FALSE);
-        return;
-    }
-
-    qmi_message_pdc_load_config_output_unref (output);
-}
+static void load_config_ready (QmiClientPdc *client,
+                               GAsyncResult *res);
 
 static void
 load_config_ready_indication (QmiClientPdc *client,
@@ -1148,6 +1316,80 @@
     qmi_message_pdc_load_config_input_unref (input);
 }
 
+static void
+load_config_ready (QmiClientPdc *client,
+                   GAsyncResult *res)
+{
+    GError *error = NULL;
+    QmiMessagePdcLoadConfigOutput *output;
+
+    output = qmi_client_pdc_load_config_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_pdc_load_config_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't load config: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_pdc_load_config_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    qmi_message_pdc_load_config_output_unref (output);
+}
+
+static QmiMessagePdcLoadConfigInput *
+load_config_input_create (const gchar *str)
+{
+    LoadConfigFileData *config_file;
+    QmiMessagePdcLoadConfigInput *input = NULL;
+
+    config_file = load_config_file_from_string (str);
+    if (!config_file)
+        return NULL;
+
+    input = load_config_input_create_chunk (config_file);
+    if (!input)
+        return NULL;
+
+    ctx->load_config_file_data = config_file;
+    return input;
+}
+
+static void
+run_load_config (void)
+{
+    QmiMessagePdcLoadConfigInput *input;
+
+    g_debug ("Loading config asynchronously...");
+    input = load_config_input_create (load_config_str);
+    if (!input) {
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    /* Results are reported via indications */
+    ctx->load_config_indication_id =
+        g_signal_connect (ctx->client,
+                          "load-config",
+                          G_CALLBACK (load_config_ready_indication),
+                          NULL);
+
+    qmi_client_pdc_load_config (ctx->client,
+                                input,
+                                10,
+                                ctx->cancellable,
+                                (GAsyncReadyCallback) load_config_ready,
+                                NULL);
+    qmi_message_pdc_load_config_input_unref (input);
+}
+
+#endif /* HAVE_QMI_ACTION_PDC_LOAD_CONFIG */
+
 /******************************************************************************/
 /* Common */
 
@@ -1166,174 +1408,40 @@
     /* Initialize context */
     ctx = context_new (device, client, cancellable);
 
-    /* Request to get all configs */
+#if defined HAVE_QMI_ACTION_PDC_LIST_CONFIGS
     if (list_configs_str) {
-        QmiMessagePdcListConfigsInput *input;
-        QmiMessagePdcGetSelectedConfigInput *get_selected_config_input;
-
-        g_debug ("Listing configs asynchronously...");
-
-        /* Results are reported via indications */
-        ctx->list_configs_indication_id =
-            g_signal_connect (client,
-                              "list-configs",
-                              G_CALLBACK
-                              (list_configs_ready_indication), NULL);
-        ctx->get_selected_config_indication_id =
-            g_signal_connect (client, "get-selected-config",
-                              G_CALLBACK (get_selected_config_ready_indication), NULL);
-        ctx->get_config_info_indication_id =
-            g_signal_connect (client, "get-config-info",
-                              G_CALLBACK (get_config_info_ready_indication), NULL);
-
-        input = list_configs_input_create (list_configs_str);
-        if (!input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        get_selected_config_input = get_selected_config_input_create (list_configs_str);
-        if (!get_selected_config_input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        /* We need a timeout, because there will be no indications if no configs
-         * are loaded */
-        ctx->timeout_id = g_timeout_add_seconds (LIST_CONFIGS_TIMEOUT_SECS,
-                                                 (GSourceFunc) list_configs_timeout,
-                                                 NULL);
-
-        qmi_client_pdc_list_configs (ctx->client,
-                                     input,
-                                     10,
-                                     ctx->cancellable,
-                                     (GAsyncReadyCallback) list_configs_ready,
-                                     NULL);
-        qmi_message_pdc_list_configs_input_unref (input);
-
-        qmi_client_pdc_get_selected_config (ctx->client,
-                                            get_selected_config_input,
-                                            10,
-                                            ctx->cancellable,
-                                            (GAsyncReadyCallback) get_selected_config_ready,
-                                            NULL);
-        qmi_message_pdc_get_selected_config_input_unref (get_selected_config_input);
+        run_list_configs ();
         return;
     }
+#endif
 
-    /* Request to delete config */
-    if (delete_config_str) {
-        QmiMessagePdcDeleteConfigInput *input;
-
-        g_debug ("Deleting config asynchronously...");
-        input = delete_config_input_create (delete_config_str);
-        if (!input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        qmi_client_pdc_delete_config (ctx->client,
-                                      input,
-                                      10,
-                                      ctx->cancellable,
-                                      (GAsyncReadyCallback) delete_config_ready, NULL);
-        qmi_message_pdc_delete_config_input_unref (input);
-        return;
-    }
-
-    /* Request to activate config */
+#if defined HAVE_QMI_ACTION_PDC_ACTIVATE_CONFIG
     if (activate_config_str) {
-        QmiMessagePdcSetSelectedConfigInput *input;
-
-        g_debug ("Activating config asynchronously...");
-        input = set_selected_config_input_create (activate_config_str);
-        if (!input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        /* Results are reported via indications */
-        ctx->set_selected_config_indication_id =
-            g_signal_connect (client,
-                              "set-selected-config",
-                              G_CALLBACK (set_selected_config_ready_indication_activation), NULL);
-        ctx->activate_config_indication_id =
-            g_signal_connect (client,
-                              "activate-config",
-                              G_CALLBACK
-                              (activate_config_ready_indication),
-                              NULL);
-
-        qmi_client_pdc_set_selected_config (ctx->client,
-                                            input,
-                                            10,
-                                            ctx->cancellable,
-                                            (GAsyncReadyCallback) set_selected_config_ready,
-                                            NULL);
-        qmi_message_pdc_set_selected_config_input_unref (input);
+        run_activate_config ();
         return;
     }
+#endif
 
-    /* Request to deactivate config */
+#if defined HAVE_QMI_ACTION_PDC_DEACTIVATE_CONFIG
     if (deactivate_config_str) {
-        QmiMessagePdcSetSelectedConfigInput *input;
-
-        g_debug ("Deactivating config asynchronously...");
-        input = set_selected_config_input_create (activate_config_str);
-        if (!input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        /* Results are reported via indications */
-        ctx->set_selected_config_indication_id =
-            g_signal_connect (client,
-                              "set-selected-config",
-                              G_CALLBACK (set_selected_config_ready_indication_deactivation), NULL);
-        ctx->deactivate_config_indication_id =
-            g_signal_connect (client,
-                              "deactivate-config",
-                              G_CALLBACK
-                              (deactivate_config_ready_indication),
-                              NULL);
-
-        qmi_client_pdc_set_selected_config (ctx->client,
-                                            input,
-                                            10,
-                                            ctx->cancellable,
-                                            (GAsyncReadyCallback) set_selected_config_ready,
-                                            NULL);
-        qmi_message_pdc_set_selected_config_input_unref (input);
+        run_deactivate_config ();
         return;
     }
+#endif
 
+#if defined HAVE_QMI_MESSAGE_PDC_DELETE_CONFIG
+    if (delete_config_str) {
+        run_delete_config ();
+        return;
+    }
+#endif
+
+#if defined HAVE_QMI_ACTION_PDC_LOAD_CONFIG
     if (load_config_str) {
-        QmiMessagePdcLoadConfigInput *input;
-
-        g_debug ("Loading config asynchronously...");
-        input = load_config_input_create (load_config_str);
-        if (!input) {
-            operation_shutdown (FALSE);
-            return;
-        }
-
-        /* Results are reported via indications */
-        ctx->load_config_indication_id =
-            g_signal_connect (client,
-                              "load-config",
-                              G_CALLBACK (load_config_ready_indication),
-                              NULL);
-
-        qmi_client_pdc_load_config (ctx->client,
-                                    input,
-                                    10,
-                                    ctx->cancellable,
-                                    (GAsyncReadyCallback) load_config_ready,
-                                    NULL);
-        qmi_message_pdc_load_config_input_unref (input);
+        run_load_config ();
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -1343,3 +1451,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_PDC */
diff --git a/src/qmicli/qmicli-qos.c b/src/qmicli/qmicli-qos.c
index c0bbe33..a3c4623 100644
--- a/src/qmicli/qmicli-qos.c
+++ b/src/qmicli/qmicli-qos.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_QOS
+
 #undef VALIDATE_UNKNOWN
 #define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
 
@@ -52,22 +54,30 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_QOS_GET_FLOW_STATUS
     { "qos-get-flow-status", 0, 0, G_OPTION_ARG_INT, &get_flow_status_int,
       "Get QoS flow status",
       "[QoS ID]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_QOS_GET_NETWORK_STATUS
     { "qos-get-network-status", 0, 0, G_OPTION_ARG_NONE, &get_network_status_flag,
       "Gets the network status",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_QOS_SWI_READ_DATA_STATS
     { "qos-swi-read-data-stats", 0, 0, G_OPTION_ARG_INT, &swi_read_data_stats_int,
       "Read data stats (Sierra Wireless specific)",
       "[APN ID]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_QOS_RESET
     { "qos-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
     { "qos-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a QOS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -81,7 +91,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("qos",
-                                "QoS options",
+                                "QoS options:",
                                 "Show Quality of Service options",
                                 NULL,
                                 NULL);
@@ -137,6 +147,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_QOS_GET_FLOW_STATUS
+
 static void
 get_flow_status_ready (QmiClientQos *client,
                        GAsyncResult *res)
@@ -171,6 +183,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_QOS_GET_FLOW_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_QOS_GET_NETWORK_STATUS
+
 static void
 get_network_status_ready (QmiClientQos *client,
                           GAsyncResult *res)
@@ -205,6 +221,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_QOS_GET_NETWORK_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_QOS_SWI_READ_DATA_STATS
+
 static void
 swi_read_data_stats_ready (QmiClientQos *client,
                            GAsyncResult *res)
@@ -282,6 +302,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_QOS_SWI_READ_DATA_STATS */
+
+#if defined HAVE_QMI_MESSAGE_QOS_RESET
+
 static void
 reset_ready (QmiClientQos *client,
              GAsyncResult *res)
@@ -312,6 +336,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_QOS_RESET */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -330,7 +356,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get QoS flow status? */
+#if defined HAVE_QMI_MESSAGE_QOS_GET_FLOW_STATUS
     if (get_flow_status_int >= 0) {
         QmiMessageQosGetFlowStatusInput *input;
 
@@ -346,8 +372,9 @@
         qmi_message_qos_get_flow_status_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get network status? */
+#if defined HAVE_QMI_MESSAGE_QOS_GET_NETWORK_STATUS
     if (get_network_status_flag) {
         g_debug ("Asynchronously getting network status...");
         qmi_client_qos_get_network_status (ctx->client,
@@ -358,8 +385,9 @@
                                            NULL);
         return;
     }
+#endif
 
-    /* Request to read data stats? */
+#if defined HAVE_QMI_MESSAGE_QOS_SWI_READ_DATA_STATS
     if (swi_read_data_stats_int >= 0) {
         QmiMessageQosSwiReadDataStatsInput *input;
 
@@ -375,8 +403,9 @@
         qmi_message_qos_swi_read_data_stats_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to reset QoS service? */
+#if defined HAVE_QMI_MESSAGE_QOS_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting QoS service...");
         qmi_client_qos_reset (ctx->client,
@@ -387,6 +416,7 @@
                               NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -396,3 +426,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_QOS */
diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c
index e636888..3a4fcab 100644
--- a/src/qmicli/qmicli-uim.c
+++ b/src/qmicli/qmicli-uim.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_UIM
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -58,58 +60,84 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION
     { "uim-set-pin-protection", 0, 0, G_OPTION_ARG_STRING, &set_pin_protection_str,
       "Set PIN protection",
       "[(PIN1|PIN2|UPIN),(disable|enable),(current PIN)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_VERIFY_PIN
     { "uim-verify-pin", 0, 0, G_OPTION_ARG_STRING, &verify_pin_str,
       "Verify PIN",
       "[(PIN1|PIN2|UPIN),(current PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN
     { "uim-unblock-pin", 0, 0, G_OPTION_ARG_STRING, &unblock_pin_str,
       "Unblock PIN",
       "[(PIN1|PIN2|UPIN),(PUK),(new PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PIN
     { "uim-change-pin", 0, 0, G_OPTION_ARG_STRING, &change_pin_str,
       "Change PIN",
       "[(PIN1|PIN2|UPIN),(old PIN),(new PIN)]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
     { "uim-read-transparent", 0, 0, G_OPTION_ARG_STRING, &read_transparent_str,
       "Read a transparent file given the file path",
       "[0xNNNN,0xNNNN,...]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
     { "uim-get-file-attributes", 0, 0, G_OPTION_ARG_STRING, &get_file_attributes_str,
       "Get the attributes of a given file",
       "[0xNNNN,0xNNNN,...]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_READ_RECORD
     { "uim-read-record", 0, 0, G_OPTION_ARG_STRING, &read_record_str,
       "Read a record from given file (allowed keys: record-number, record-length, file ([0xNNNN-0xNNNN,...])",
       "[\"key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CARD_STATUS
     { "uim-get-card-status", 0, 0, G_OPTION_ARG_NONE, &get_card_status_flag,
       "Get card status",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_SUPPORTED_MESSAGES
     { "uim-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_ON_SIM
     { "uim-sim-power-on", 0, 0, G_OPTION_ARG_STRING, &sim_power_on_str,
       "Power on SIM card",
       "[(slot number)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_OFF_SIM
     { "uim-sim-power-off", 0, 0, G_OPTION_ARG_STRING, &sim_power_off_str,
       "Power off SIM card",
       "[(slot number)]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PROVISIONING_SESSION
     { "uim-change-provisioning-session", 0, 0, G_OPTION_ARG_STRING, &change_provisioning_session_str,
       "Change provisioning session (allowed keys: session-type, activate, slot, aid)",
       "[\"key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_RESET
     { "uim-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
     { "uim-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a UIM client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -123,7 +151,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("uim",
-                                "UIM options",
+                                "UIM options:",
                                 "Show User Identity Module options",
                                 NULL,
                                 NULL);
@@ -186,6 +214,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION
+
 static QmiMessageUimSetPinProtectionInput *
 set_pin_protection_input_create (const gchar *str)
 {
@@ -280,6 +310,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION */
+
+#if defined HAVE_QMI_MESSAGE_UIM_VERIFY_PIN
+
 static QmiMessageUimVerifyPinInput *
 verify_pin_input_create (const gchar *str)
 {
@@ -371,6 +405,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_VERIFY_PIN */
+
+#if defined HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN
+
 static QmiMessageUimUnblockPinInput *
 unblock_pin_input_create (const gchar *str)
 {
@@ -465,6 +503,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN */
+
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PIN
+
 static QmiMessageUimChangePinInput *
 change_pin_input_create (const gchar *str)
 {
@@ -559,6 +601,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_CHANGE_PIN */
+
+#if defined HAVE_QMI_MESSAGE_UIM_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientUim *client,
                               GAsyncResult *res)
@@ -597,6 +643,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_GET_SUPPORTED_MESSAGES */
+
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_ON_SIM
+
 static QmiMessageUimPowerOnSimInput *
 power_on_sim_input_create (const gchar *slot_str)
 {
@@ -606,7 +656,7 @@
 
     input = qmi_message_uim_power_on_sim_input_new ();
 
-    if (!qmicli_read_uint_from_string (sim_power_on_str, &slot) || (slot > G_MAXUINT8)) {
+    if (!qmicli_read_uint_from_string (slot_str, &slot) || (slot > G_MAXUINT8)) {
         g_printerr ("error: invalid slot number\n");
         return NULL;
     }
@@ -651,6 +701,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_POWER_ON_SIM */
+
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_OFF_SIM
+
 static QmiMessageUimPowerOffSimInput *
 power_off_sim_input_create (const gchar *slot_str)
 {
@@ -660,7 +714,7 @@
 
     input = qmi_message_uim_power_off_sim_input_new ();
 
-    if (!qmicli_read_uint_from_string (sim_power_off_str, &slot) || (slot > G_MAXUINT8)) {
+    if (!qmicli_read_uint_from_string (slot_str, &slot) || (slot > G_MAXUINT8)) {
         g_printerr ("error: invalid slot number\n");
         return NULL;
     }
@@ -705,6 +759,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_POWER_OFF_SIM */
+
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PROVISIONING_SESSION
+
 typedef struct {
     QmiUimSessionType  session_type;
     gboolean           session_type_set;
@@ -853,6 +911,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_CHANGE_PROVISIONING_SESSION */
+
+#if defined HAVE_QMI_MESSAGE_UIM_RESET
+
 static void
 reset_ready (QmiClientUim *client,
              GAsyncResult *res)
@@ -883,6 +945,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -890,6 +954,8 @@
     return FALSE;
 }
 
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CARD_STATUS
+
 static void
 get_card_status_ready (QmiClientUim *client,
                        GAsyncResult *res)
@@ -1040,6 +1106,12 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* defined HAVE_QMI_MESSAGE_UIM_GET_CARD_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT || \
+    defined HAVE_QMI_MESSAGE_UIM_READ_RECORD || \
+    defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
+
 static gboolean
 get_sim_file_id_and_path_with_separator (const gchar *file_path_str,
                                          guint16 *file_id,
@@ -1091,6 +1163,13 @@
     return TRUE;
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
+        * HAVE_QMI_MESSAGE_UIM_READ_RECORD
+        * HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES */
+
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT || \
+    defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
+
 static gboolean
 get_sim_file_id_and_path (const gchar *file_path_str,
                           guint16 *file_id,
@@ -1099,6 +1178,11 @@
     return get_sim_file_id_and_path_with_separator (file_path_str, file_id, file_path, ",");
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
+        * HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES */
+
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
+
 static void
 read_transparent_ready (QmiClientUim *client,
                         GAsyncResult *res)
@@ -1201,6 +1285,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT */
+
+#if defined HAVE_QMI_MESSAGE_UIM_READ_RECORD
+
 static void
 read_record_ready (QmiClientUim *client,
                    GAsyncResult *res)
@@ -1389,6 +1477,10 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_READ_RECORD */
+
+#if defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
+
 static void
 get_file_attributes_ready (QmiClientUim *client,
                            GAsyncResult *res,
@@ -1561,6 +1653,8 @@
     return input;
 }
 
+#endif /* HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES */
+
 void
 qmicli_uim_run (QmiDevice *device,
                 QmiClientUim *client,
@@ -1572,7 +1666,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Set PIN protection */
+#if defined HAVE_QMI_MESSAGE_UIM_SET_PIN_PROTECTION
     if (set_pin_protection_str) {
         QmiMessageUimSetPinProtectionInput *input;
 
@@ -1591,8 +1685,9 @@
         qmi_message_uim_set_pin_protection_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to verify PIN? */
+#if defined HAVE_QMI_MESSAGE_UIM_VERIFY_PIN
     if (verify_pin_str) {
         QmiMessageUimVerifyPinInput *input;
 
@@ -1611,8 +1706,9 @@
         qmi_message_uim_verify_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to unblock PIN? */
+#if defined HAVE_QMI_MESSAGE_UIM_UNBLOCK_PIN
     if (unblock_pin_str) {
         QmiMessageUimUnblockPinInput *input;
 
@@ -1631,8 +1727,9 @@
         qmi_message_uim_unblock_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to change the PIN? */
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PIN
     if (change_pin_str) {
         QmiMessageUimChangePinInput *input;
 
@@ -1651,8 +1748,9 @@
         qmi_message_uim_change_pin_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read a transparent file? */
+#if defined HAVE_QMI_MESSAGE_UIM_READ_TRANSPARENT
     if (read_transparent_str) {
         QmiMessageUimReadTransparentInput *input;
 
@@ -1673,8 +1771,9 @@
         qmi_message_uim_read_transparent_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read a transparent file? */
+#if defined HAVE_QMI_MESSAGE_UIM_READ_RECORD
     if (read_record_str) {
         QmiMessageUimReadRecordInput *input;
 
@@ -1695,8 +1794,9 @@
         qmi_message_uim_read_record_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get file attributes? */
+#if defined HAVE_QMI_MESSAGE_UIM_GET_FILE_ATTRIBUTES
     if (get_file_attributes_str) {
         QmiMessageUimGetFileAttributesInput *input;
 
@@ -1717,8 +1817,9 @@
         qmi_message_uim_get_file_attributes_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read card status? */
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CARD_STATUS
     if (get_card_status_flag) {
         g_debug ("Asynchronously getting card status...");
         qmi_client_uim_get_card_status (ctx->client,
@@ -1729,8 +1830,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_UIM_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported UIM messages...");
         qmi_client_uim_get_supported_messages (ctx->client,
@@ -1741,8 +1843,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to power on SIM card? */
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_ON_SIM
     if (sim_power_on_str) {
         QmiMessageUimPowerOnSimInput *input;
 
@@ -1762,8 +1865,9 @@
         qmi_message_uim_power_on_sim_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to power off SIM card? */
+#if defined HAVE_QMI_MESSAGE_UIM_POWER_OFF_SIM
     if (sim_power_off_str) {
         QmiMessageUimPowerOffSimInput *input;
 
@@ -1783,8 +1887,9 @@
         qmi_message_uim_power_off_sim_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to change provisioning session? */
+#if defined HAVE_QMI_MESSAGE_UIM_CHANGE_PROVISIONING_SESSION
     if (change_provisioning_session_str) {
         QmiMessageUimChangeProvisioningSessionInput *input;
 
@@ -1804,8 +1909,9 @@
         qmi_message_uim_change_provisioning_session_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to reset UIM service? */
+#if defined HAVE_QMI_MESSAGE_UIM_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting UIM service...");
         qmi_client_uim_reset (ctx->client,
@@ -1816,6 +1922,7 @@
                               NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -1825,3 +1932,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_UIM */
diff --git a/src/qmicli/qmicli-voice.c b/src/qmicli/qmicli-voice.c
index efb053e..0b51a02 100644
--- a/src/qmicli/qmicli-voice.c
+++ b/src/qmicli/qmicli-voice.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_VOICE
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -47,14 +49,18 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_CONFIG
     { "voice-get-config", 0, 0, G_OPTION_ARG_NONE, &get_config_flag,
       "Get Voice service configuration",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_SUPPORTED_MESSAGES
     { "voice-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
     { "voice-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a VOICE client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -68,7 +74,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("voice",
-                                "VOICE options",
+                                "VOICE options:",
                                 "Show Voice Service options",
                                 NULL,
                                 NULL);
@@ -120,6 +126,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_CONFIG
+
 static void
 get_config_ready (QmiClientVoice *client,
                   GAsyncResult *res)
@@ -252,6 +260,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_VOICE_GET_CONFIG */
+
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientVoice *client,
                               GAsyncResult *res)
@@ -290,6 +302,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_VOICE_GET_SUPPORTED_MESSAGES */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -308,7 +322,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to get voice configuration? */
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_CONFIG
     if (get_config_flag) {
         QmiMessageVoiceGetConfigInput *input;
 
@@ -335,8 +349,9 @@
         qmi_message_voice_get_config_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_VOICE_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported voice messages...");
         qmi_client_voice_get_supported_messages (ctx->client,
@@ -347,6 +362,7 @@
                                                  NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -356,3 +372,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_VOICE */
diff --git a/src/qmicli/qmicli-wda.c b/src/qmicli/qmicli-wda.c
index f8fdb82..d6f25ec 100644
--- a/src/qmicli/qmicli-wda.c
+++ b/src/qmicli/qmicli-wda.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_WDA
+
 #define QMI_WDA_DL_AGGREGATION_PROTOCOL_MAX_DATAGRAMS_UNDEFINED 0xFFFFFFFF
 #define QMI_WDA_DL_AGGREGATION_PROTOCOL_MAX_DATAGRAM_SIZE_UNDEFINED 0xFFFFFFFF
 #define QMI_WDA_ENDPOINT_INTERFACE_NUMBER_UNDEFINED -1
@@ -52,6 +54,8 @@
 static gboolean  get_supported_messages_flag;
 static gboolean  noop_flag;
 
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
+
 static gboolean
 parse_get_data_format (const gchar  *option_name,
                        const gchar  *value,
@@ -64,19 +68,27 @@
     return TRUE;
 }
 
+#endif
+
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_WDA_SET_DATA_FORMAT
     { "wda-set-data-format", 0, 0, G_OPTION_ARG_STRING, &set_data_format_str,
       "Set data format (allowed keys: link-layer-protocol (802-3|raw-ip), ul-protocol (tlp|qc-ncm|mbim|rndis|qmap), dl-protocol (tlp|qc-ncm|mbim|rndis|qmap), dl-datagram-max-size, dl-max-datagrams, ep-type (undefined|hsusb), ep-iface-number)",
       "[\"key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
     { "wda-get-data-format", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, parse_get_data_format,
       "Get data format (allowed keys: ep-type (undefined|hsusb), ep-iface-number); also allows empty key list",
       "[\"key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDA_GET_SUPPORTED_MESSAGES
     { "wda-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
     { "wda-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a WDA client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -90,7 +102,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("wda",
-                                "WDA options",
+                                "WDA options:",
                                 "Show Wireless Data Administrative options",
                                 NULL,
                                 NULL);
@@ -150,6 +162,8 @@
     return FALSE;
 }
 
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
+
 typedef struct {
     QmiDataEndpointType endpoint_type;
     gint                endpoint_iface_number;
@@ -327,6 +341,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT */
+
+#if defined HAVE_QMI_MESSAGE_WDA_SET_DATA_FORMAT
+
 static void
 set_data_format_ready (QmiClientWda *client,
                        GAsyncResult *res)
@@ -408,7 +426,6 @@
     operation_shutdown (TRUE);
 }
 
-
 typedef struct {
     QmiWdaLinkLayerProtocol link_layer_protocol;
     QmiWdaDataAggregationProtocol ul_protocol;
@@ -643,6 +660,10 @@
     return NULL;
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDA_SET_DATA_FORMAT */
+
+#if defined HAVE_QMI_MESSAGE_WDA_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientWda *client,
                               GAsyncResult *res)
@@ -681,6 +702,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDA_GET_SUPPORTED_MESSAGES */
+
 void
 qmicli_wda_run (QmiDevice *device,
                 QmiClientWda *client,
@@ -692,7 +715,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to set data format? */
+#if defined HAVE_QMI_MESSAGE_WDA_SET_DATA_FORMAT
     if (set_data_format_str) {
         QmiMessageWdaSetDataFormatInput *input;
 
@@ -712,8 +735,9 @@
         qmi_message_wda_set_data_format_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to read data format? */
+#if defined HAVE_QMI_MESSAGE_WDA_GET_DATA_FORMAT
     if (get_data_format_flag) {
         g_autoptr(QmiMessageWdaGetDataFormatInput) input = NULL;
 
@@ -734,8 +758,9 @@
                                         NULL);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_WDA_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported WDA messages...");
         qmi_client_wda_get_supported_messages (ctx->client,
@@ -746,6 +771,7 @@
                                                NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -755,3 +781,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_WDA */
diff --git a/src/qmicli/qmicli-wds.c b/src/qmicli/qmicli-wds.c
index 4a15d31..dddebd4 100644
--- a/src/qmicli/qmicli-wds.c
+++ b/src/qmicli/qmicli-wds.c
@@ -35,6 +35,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_WDS
+
 #define QMI_WDS_MUX_ID_UNDEFINED 0xFF
 #define QMI_WDS_ENDPOINT_INTERFACE_NUMBER_UNDEFINED -1
 
@@ -81,110 +83,162 @@
 static gboolean get_channel_rates_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_WDS_START_NETWORK
     { "wds-start-network", 0, 0, G_OPTION_ARG_STRING, &start_network_str,
       "Start network (allowed keys: apn, 3gpp-profile, 3gpp2-profile, auth (PAP|CHAP|BOTH), username, password, autoconnect=yes, ip-type (4|6))",
       "[\"key=value,...\"]"
     },
+# if defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK && defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
     { "wds-follow-network", 0, 0, G_OPTION_ARG_NONE, &follow_network_flag,
       "Follow the network status until disconnected. Use with `--wds-start-network'",
       NULL
     },
+# endif
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK
     { "wds-stop-network", 0, 0, G_OPTION_ARG_STRING, &stop_network_str,
       "Stop network",
       "[Packet data handle] OR [disable-autoconnect]",
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS
     { "wds-get-current-settings", 0, 0, G_OPTION_ARG_NONE, &get_current_settings_flag,
       "Get current settings",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
     { "wds-get-packet-service-status", 0, 0, G_OPTION_ARG_NONE, &get_packet_service_status_flag,
       "Get packet service status",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_STATISTICS
     { "wds-get-packet-statistics", 0, 0, G_OPTION_ARG_NONE, &get_packet_statistics_flag,
       "Get packet statistics",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DATA_BEARER_TECHNOLOGY
     { "wds-get-data-bearer-technology", 0, 0, G_OPTION_ARG_NONE, &get_data_bearer_technology_flag,
       "Get data bearer technology",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_DATA_BEARER_TECHNOLOGY
     { "wds-get-current-data-bearer-technology", 0, 0, G_OPTION_ARG_NONE, &get_current_data_bearer_technology_flag,
       "Get current data bearer technology",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GO_DORMANT
     { "wds-go-dormant", 0, 0, G_OPTION_ARG_NONE, &go_dormant_flag,
       "Make the active data connection go dormant",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GO_ACTIVE
     { "wds-go-active", 0, 0, G_OPTION_ARG_NONE, &go_active_flag,
       "Make the active data connection go active",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DORMANCY_STATUS
     { "wds-get-dormancy-status", 0, 0, G_OPTION_ARG_NONE, &get_dormancy_status_flag,
       "Get the dormancy status of the active data connection",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE
     { "wds-create-profile", 0, 0, G_OPTION_ARG_STRING, &create_profile_str,
       "Create new profile using first available profile index (optional keys: name, apn, pdp-type (IP|PPP|IPV6|IPV4V6), auth (NONE|PAP|CHAP|BOTH), username, password, context-num, no-roaming=yes, disabled=yes)",
       "[\"(3gpp|3gpp2)[,key=value,...]\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED
     { "wds-swi-create-profile-indexed", 0, 0, G_OPTION_ARG_STRING, &swi_create_profile_indexed_str,
       "Create new profile at specified profile index [Sierra Wireless specific] (optional keys: name, apn, pdp-type (IP|PPP|IPV6|IPV4V6), auth (NONE|PAP|CHAP|BOTH), username, password, context-num, no-roaming=yes, disabled=yes)",
       "[\"(3gpp|3gpp2),#[,key=value,...]\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE
     { "wds-modify-profile", 0, 0, G_OPTION_ARG_STRING, &modify_profile_str,
       "Modify existing profile (optional keys: name, apn, pdp-type (IP|PPP|IPV6|IPV4V6), auth (NONE|PAP|CHAP|BOTH), username, password, context-num, no-roaming=yes, disabled=yes)",
       "[\"(3gpp|3gpp2),#,key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_DELETE_PROFILE
     { "wds-delete-profile", 0, 0, G_OPTION_ARG_STRING, &delete_profile_str,
       "Delete existing profile",
       "[(3gpp|3gpp2),#]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_LIST && defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_SETTINGS
     { "wds-get-profile-list", 0, 0, G_OPTION_ARG_STRING, &get_profile_list_str,
       "Get profile list",
       "[3gpp|3gpp2]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_PROFILE_NUM
     { "wds-get-default-profile-num", 0, 0, G_OPTION_ARG_STRING, &get_default_profile_num_str,
       "Get default profile number",
       "[3gpp|3gpp2]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_SET_DEFAULT_PROFILE_NUM
     { "wds-set-default-profile-num", 0, 0, G_OPTION_ARG_STRING, &set_default_profile_num_str,
       "Set default profile number",
       "[(3gpp|3gpp2),#]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_SETTINGS
     { "wds-get-default-settings", 0, 0, G_OPTION_ARG_STRING, &get_default_settings_str,
       "Get default settings",
       "[3gpp|3gpp2]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_AUTOCONNECT_SETTINGS
     { "wds-get-autoconnect-settings", 0, 0, G_OPTION_ARG_NONE, &get_autoconnect_settings_flag,
       "Get autoconnect settings",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_SET_AUTOCONNECT_SETTINGS
     { "wds-set-autoconnect-settings", 0, 0, G_OPTION_ARG_STRING, &set_autoconnect_settings_str,
       "Set autoconnect settings (roaming settings optional)",
       "[(enabled|disabled|paused)[,(roaming-allowed|home-only)]]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_SUPPORTED_MESSAGES
     { "wds-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_RESET
     { "wds-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_BIND_MUX_DATA_PORT
     { "wds-bind-mux-data-port", 0, 0, G_OPTION_ARG_STRING, &bind_mux_str,
       "Bind qmux data port to controller device (allowed keys: mux-id, ep-iface-number) to be used with `--client-no-release-cid'",
       "[\"key=value,...\"]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_SET_IP_FAMILY
     { "wds-set-ip-family", 0, 0, G_OPTION_ARG_STRING, &set_ip_family_str,
       "Set IP family",
       "[4|6]"
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CHANNEL_RATES
     { "wds-get-channel-rates", 0, 0, G_OPTION_ARG_NONE, &get_channel_rates_flag,
       "Get channel data rates",
       NULL
     },
+#endif
     { "wds-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a WDS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -198,7 +252,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("wds",
-                                "WDS options",
+                                "WDS options:",
                                 "Show Wireless Data Service options",
                                 NULL,
                                 NULL);
@@ -281,6 +335,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_WDS_START_NETWORK || defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK
+
 static void
 stop_network_ready (QmiClientWds *client,
                     GAsyncResult *res)
@@ -336,6 +392,13 @@
     qmi_message_wds_stop_network_input_unref (input);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_START_NETWORK
+        * HAVE_QMI_MESSAGE_WDS_STOP_NETWORK */
+
+#if defined HAVE_QMI_MESSAGE_WDS_START_NETWORK
+
+#if defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK && defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
+
 static void
 network_cancelled (GCancellable *cancellable)
 {
@@ -405,6 +468,9 @@
     return TRUE;
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_STOP_NETWORK
+        * HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS */
+
 typedef struct {
     gchar                *apn;
     guint8                profile_index_3gpp;
@@ -701,6 +767,7 @@
              qmi_device_get_path_display (ctx->device),
              (guint)ctx->packet_data_handle);
 
+#if defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK && defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
     if (follow_network_flag) {
         g_print ("\nCtrl+C will stop the network\n");
         ctx->network_started_id = g_cancellable_connect (ctx->cancellable,
@@ -713,11 +780,16 @@
                                                                NULL);
         return;
     }
+#endif
 
     /* Nothing else to do */
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_START_NETWORK */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS
+
 static void
 get_current_settings_ready (QmiClientWds *client,
                             GAsyncResult *res)
@@ -859,6 +931,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
+
 static void
 get_packet_service_status_ready (QmiClientWds *client,
                                  GAsyncResult *res)
@@ -897,6 +973,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_STATISTICS
+
 static void
 get_packet_statistics_ready (QmiClientWds *client,
                              GAsyncResult *res)
@@ -964,6 +1044,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_PACKET_STATISTICS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DATA_BEARER_TECHNOLOGY
+
 static void
 get_data_bearer_technology_ready (QmiClientWds *client,
                                   GAsyncResult *res)
@@ -1015,6 +1099,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_DATA_BEARER_TECHNOLOGY */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_DATA_BEARER_TECHNOLOGY
+
 static void
 print_current_data_bearer_technology_results (const gchar *which,
                                               QmiWdsNetworkType network_type,
@@ -1112,6 +1200,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_CURRENT_DATA_BEARER_TECHNOLOGY */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GO_DORMANT
+
 static void
 go_dormant_ready (QmiClientWds *client,
                   GAsyncResult *res)
@@ -1140,6 +1232,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GO_DORMANT */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GO_ACTIVE
+
 static void
 go_active_ready (QmiClientWds *client,
                  GAsyncResult *res)
@@ -1168,6 +1264,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GO_ACTIVE */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DORMANCY_STATUS
+
 static void
 get_dormancy_status_ready (QmiClientWds *client,
                            GAsyncResult *res)
@@ -1206,6 +1306,11 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_DORMANCY_STATUS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE || \
+    defined HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED || \
+    defined HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE
 
 typedef struct {
     QmiWdsProfileType     profile_type;
@@ -1339,6 +1444,12 @@
     return FALSE;
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE
+        * HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED
+        * HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE */
+
+#if defined HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE
+
 static gboolean
 create_profile_input_create (const gchar                      *str,
                              QmiMessageWdsCreateProfileInput **input,
@@ -1484,6 +1595,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /*  HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE */
+
+#if defined HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED
+
 static gboolean
 swi_create_profile_indexed_input_create (const gchar                                *str,
                                          QmiMessageWdsSwiCreateProfileIndexedInput **input,
@@ -1630,6 +1745,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED */
+
+#if defined HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE
+
 static gboolean
 modify_profile_input_create (const gchar                      *str,
                              QmiMessageWdsModifyProfileInput **input,
@@ -1779,6 +1898,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE */
+
+#if defined HAVE_QMI_MESSAGE_WDS_DELETE_PROFILE
+
 static void
 delete_profile_ready (QmiClientWds *client,
                       GAsyncResult *res)
@@ -1820,6 +1943,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_DELETE_PROFILE */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_LIST && defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_SETTINGS
+
 typedef struct {
     guint i;
     GArray *profile_list;
@@ -1986,6 +2113,11 @@
     get_next_profile_settings (inner_ctx);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_PROFILE_LIST
+        * HAVE_QMI_MESSAGE_WDS_GET_PROFILE_SETTINGS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_SETTINGS
+
 static void
 get_default_settings_ready (QmiClientWds *client,
                             GAsyncResult *res)
@@ -2048,9 +2180,13 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_SETTINGS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_PROFILE_NUM
+
 static void
 get_default_profile_num_ready (QmiClientWds *client,
-                            GAsyncResult *res)
+                               GAsyncResult *res)
 {
     QmiMessageWdsGetDefaultProfileNumOutput *output;
     GError *error = NULL;
@@ -2095,6 +2231,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_PROFILE_NUM */
+
+#if defined HAVE_QMI_MESSAGE_WDS_SET_DEFAULT_PROFILE_NUM
+
 static void
 set_default_profile_num_ready (QmiClientWds *client,
                                GAsyncResult *res)
@@ -2195,6 +2335,9 @@
     return NULL;
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_SET_DEFAULT_PROFILE_NUM */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_AUTOCONNECT_SETTINGS
 
 static void
 get_autoconnect_settings_ready (QmiClientWds *client,
@@ -2234,6 +2377,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_AUTOCONNECT_SETTINGS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_SET_AUTOCONNECT_SETTINGS
+
 static QmiMessageWdsSetAutoconnectSettingsInput *
 set_autoconnect_settings_input_create (const gchar *str)
 {
@@ -2315,6 +2462,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_SET_AUTOCONNECT_SETTINGS */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientWds *client,
                               GAsyncResult *res)
@@ -2353,6 +2504,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_SUPPORTED_MESSAGES */
+
+#if defined HAVE_QMI_MESSAGE_WDS_RESET
+
 static void
 reset_ready (QmiClientWds *client,
              GAsyncResult *res)
@@ -2383,6 +2538,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_RESET */
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -2390,6 +2547,8 @@
     return FALSE;
 }
 
+#if defined HAVE_QMI_MESSAGE_WDS_BIND_MUX_DATA_PORT
+
 typedef struct {
     guint8 mux_id;
     guint8 ep_type;
@@ -2537,6 +2696,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_BIND_MUX_DATA_PORT */
+
+#if defined HAVE_QMI_MESSAGE_WDS_SET_IP_FAMILY
+
 static void
 set_ip_family_ready (QmiClientWds *client,
                      GAsyncResult *res)
@@ -2564,6 +2727,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_SET_IP_FAMILY */
+
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CHANNEL_RATES
+
 static void
 get_channel_rates_ready (QmiClientWds *client,
                          GAsyncResult *res)
@@ -2621,6 +2788,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WDS_GET_CHANNEL_RATES */
+
 void
 qmicli_wds_run (QmiDevice *device,
                 QmiClientWds *client,
@@ -2634,7 +2803,7 @@
     ctx->network_started_id = 0;
     ctx->packet_status_timeout_id = 0;
 
-    /* Request to start network? */
+#if defined HAVE_QMI_MESSAGE_WDS_START_NETWORK
     if (start_network_str) {
         QmiMessageWdsStartNetworkInput *input = NULL;
         GError *error = NULL;
@@ -2656,8 +2825,9 @@
             qmi_message_wds_start_network_input_unref (input);
         return;
     }
+#endif /* HAVE_QMI_MESSAGE_WDS_START_NETWORK */
 
-    /* Request to stop network? */
+#if defined HAVE_QMI_MESSAGE_WDS_STOP_NETWORK
     if (stop_network_str) {
         gulong packet_data_handle;
         gboolean disable_autoconnect;
@@ -2683,14 +2853,14 @@
         internal_stop_network (ctx->cancellable, (guint32)packet_data_handle, disable_autoconnect);
         return;
     }
+#endif /* HAVE_QMI_MESSAGE_WDS_STOP_NETWORK */
 
-    /* Request to bind mux port? */
+#if defined HAVE_QMI_MESSAGE_WDS_BIND_MUX_DATA_PORT
     if (bind_mux_str) {
         QmiMessageWdsBindMuxDataPortInput *input;
-        g_print ("Bind mux data port");
 
+        g_debug ("Binding mux data port..");
         input = bind_mux_data_port_input_create (bind_mux_str);
-
         qmi_client_wds_bind_mux_data_port (client,
                                            input,
                                            10,
@@ -2700,8 +2870,9 @@
         qmi_message_wds_bind_mux_data_port_input_unref (input);
         return;
     }
+#endif /* HAVE_QMI_MESSAGE_WDS_BIND_MUX_DATA_PORT */
 
-    /* Request to set IP family? */
+#if defined HAVE_QMI_MESSAGE_WDS_SET_IP_FAMILY
     if (set_ip_family_str) {
         QmiMessageWdsSetIpFamilyInput *input;
 
@@ -2729,8 +2900,9 @@
         qmi_message_wds_set_ip_family_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get current settings? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_SETTINGS
     if (get_current_settings_flag) {
         QmiMessageWdsGetCurrentSettingsInput *input;
 
@@ -2756,8 +2928,9 @@
         qmi_message_wds_get_current_settings_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get packet service status? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_SERVICE_STATUS
     if (get_packet_service_status_flag) {
         g_debug ("Asynchronously getting packet service status...");
         qmi_client_wds_get_packet_service_status (ctx->client,
@@ -2768,8 +2941,9 @@
                                                   NULL);
         return;
     }
+#endif
 
-    /* Request to get packet statistics? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PACKET_STATISTICS
     if (get_packet_statistics_flag) {
         QmiMessageWdsGetPacketStatisticsInput *input;
 
@@ -2798,8 +2972,9 @@
         qmi_message_wds_get_packet_statistics_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get data bearer technology? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DATA_BEARER_TECHNOLOGY
     if (get_data_bearer_technology_flag) {
         g_debug ("Asynchronously getting data bearer technology...");
         qmi_client_wds_get_data_bearer_technology (ctx->client,
@@ -2810,8 +2985,9 @@
                                                    NULL);
         return;
     }
+#endif
 
-    /* Request to get current data bearer technology? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CURRENT_DATA_BEARER_TECHNOLOGY
     if (get_current_data_bearer_technology_flag) {
         g_debug ("Asynchronously getting current data bearer technology...");
         qmi_client_wds_get_current_data_bearer_technology (ctx->client,
@@ -2822,8 +2998,9 @@
                                                            NULL);
         return;
     }
+#endif
 
-    /* Request to go dormant? */
+#if defined HAVE_QMI_MESSAGE_WDS_GO_DORMANT
     if (go_dormant_flag) {
         g_debug ("Asynchronously going dormant...");
         qmi_client_wds_go_dormant (ctx->client,
@@ -2834,8 +3011,9 @@
                                    NULL);
         return;
     }
+#endif
 
-    /* Request to go active? */
+#if defined HAVE_QMI_MESSAGE_WDS_GO_ACTIVE
     if (go_active_flag) {
         g_debug ("Asynchronously going active...");
         qmi_client_wds_go_active (ctx->client,
@@ -2846,8 +3024,9 @@
                                    NULL);
         return;
     }
+#endif
 
-    /* Request to get dormancy status? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DORMANCY_STATUS
     if (get_dormancy_status_flag) {
         g_debug ("Asynchronously getting dormancy status...");
         qmi_client_wds_get_dormancy_status (ctx->client,
@@ -2858,8 +3037,9 @@
                                             NULL);
         return;
     }
+#endif
 
-    /* Create a new profile using first available profile index */
+#if defined HAVE_QMI_MESSAGE_WDS_CREATE_PROFILE
     if (create_profile_str) {
         QmiMessageWdsCreateProfileInput *input = NULL;
         GError *error = NULL;
@@ -2881,8 +3061,9 @@
        qmi_message_wds_create_profile_input_unref (input);
        return;
     }
+#endif
 
-    /* Create a new profile at spedified profile index (Sierra Wireless only)*/
+#if defined HAVE_QMI_MESSAGE_WDS_SWI_CREATE_PROFILE_INDEXED
     if (swi_create_profile_indexed_str) {
         QmiMessageWdsSwiCreateProfileIndexedInput *input = NULL;
         GError *error = NULL;
@@ -2904,8 +3085,9 @@
        qmi_message_wds_swi_create_profile_indexed_input_unref (input);
        return;
     }
+#endif
 
-    /* Modify an existing profile */
+#if defined HAVE_QMI_MESSAGE_WDS_MODIFY_PROFILE
     if (modify_profile_str) {
         QmiMessageWdsModifyProfileInput *input = NULL;
         GError *error = NULL;
@@ -2927,8 +3109,9 @@
         qmi_message_wds_modify_profile_input_unref (input);
         return;
     }
+#endif
 
-    /* Delete an existing profile */
+#if defined HAVE_QMI_MESSAGE_WDS_DELETE_PROFILE
     if (delete_profile_str) {
         QmiMessageWdsDeleteProfileInput *input;
         gchar **split;
@@ -2980,8 +3163,9 @@
        qmi_message_wds_delete_profile_input_unref (input);
        return;
     }
+#endif
 
-    /* Request to list profiles? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_LIST && defined HAVE_QMI_MESSAGE_WDS_GET_PROFILE_SETTINGS
     if (get_profile_list_str) {
         QmiMessageWdsGetProfileListInput *input;
 
@@ -3007,8 +3191,9 @@
         qmi_message_wds_get_profile_list_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to get currently active profile number */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_PROFILE_NUM
     if (get_default_profile_num_str) {
         QmiMessageWdsGetDefaultProfileNumInput *input;
         QmiWdsProfileType profile_type;
@@ -3041,8 +3226,9 @@
         qmi_message_wds_get_default_profile_num_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to set currently active profile number */
+#if defined HAVE_QMI_MESSAGE_WDS_SET_DEFAULT_PROFILE_NUM
     if (set_default_profile_num_str) {
         QmiMessageWdsSetDefaultProfileNumInput *input;
 
@@ -3062,8 +3248,9 @@
         qmi_message_wds_set_default_profile_num_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to print default settings? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_DEFAULT_SETTINGS
     if (get_default_settings_str) {
         QmiMessageWdsGetDefaultSettingsInput *input;
 
@@ -3089,8 +3276,9 @@
         qmi_message_wds_get_default_settings_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to print autoconnect settings? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_AUTOCONNECT_SETTINGS
     if (get_autoconnect_settings_flag) {
         g_debug ("Asynchronously getting autoconnect settings...");
         qmi_client_wds_get_autoconnect_settings (ctx->client,
@@ -3101,8 +3289,9 @@
                                                  NULL);
         return;
     }
+#endif
 
-    /* Request to print autoconnect settings? */
+#if defined HAVE_QMI_MESSAGE_WDS_SET_AUTOCONNECT_SETTINGS
     if (set_autoconnect_settings_str) {
         QmiMessageWdsSetAutoconnectSettingsInput *input;
 
@@ -3122,8 +3311,9 @@
         qmi_message_wds_set_autoconnect_settings_input_unref (input);
         return;
     }
+#endif
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported WDS messages...");
         qmi_client_wds_get_supported_messages (ctx->client,
@@ -3134,8 +3324,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to reset WDS service? */
+#if defined HAVE_QMI_MESSAGE_WDS_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting WDS service...");
         qmi_client_wds_reset (ctx->client,
@@ -3146,8 +3337,9 @@
                               NULL);
         return;
     }
+#endif
 
-    /* Request to get channel data rates? */
+#if defined HAVE_QMI_MESSAGE_WDS_GET_CHANNEL_RATES
     if (get_channel_rates_flag) {
         g_debug ("Asynchronously getting channel data rates...");
         qmi_client_wds_get_channel_rates (client,
@@ -3158,6 +3350,7 @@
                                           NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -3167,3 +3360,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_WDS */
diff --git a/src/qmicli/qmicli-wms.c b/src/qmicli/qmicli-wms.c
index e794ec4..06a8f24 100644
--- a/src/qmicli/qmicli-wms.c
+++ b/src/qmicli/qmicli-wms.c
@@ -33,6 +33,8 @@
 #include "qmicli.h"
 #include "qmicli-helpers.h"
 
+#if defined HAVE_QMI_SERVICE_WMS
+
 /* Context */
 typedef struct {
     QmiDevice *device;
@@ -47,14 +49,18 @@
 static gboolean noop_flag;
 
 static GOptionEntry entries[] = {
+#if defined HAVE_QMI_MESSAGE_WMS_GET_SUPPORTED_MESSAGES
     { "wms-get-supported-messages", 0, 0, G_OPTION_ARG_NONE, &get_supported_messages_flag,
       "Get supported messages",
       NULL
     },
+#endif
+#if defined HAVE_QMI_MESSAGE_WMS_RESET
     { "wms-reset", 0, 0, G_OPTION_ARG_NONE, &reset_flag,
       "Reset the service state",
       NULL
     },
+#endif
     { "wms-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
       "Just allocate or release a WMS client. Use with `--client-no-release-cid' and/or `--client-cid'",
       NULL
@@ -68,7 +74,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("wms",
-                                "WMS options",
+                                "WMS options:",
                                 "Show Wireless Messaging Service options",
                                 NULL,
                                 NULL);
@@ -120,6 +126,8 @@
     qmicli_async_operation_done (operation_status, FALSE);
 }
 
+#if defined HAVE_QMI_MESSAGE_WMS_GET_SUPPORTED_MESSAGES
+
 static void
 get_supported_messages_ready (QmiClientWms *client,
                               GAsyncResult *res)
@@ -158,6 +166,10 @@
     operation_shutdown (TRUE);
 }
 
+#endif /* HAVE_QMI_MESSAGE_WMS_GET_SUPPORTED_MESSAGES */
+
+#if defined HAVE_QMI_MESSAGE_WMS_RESET
+
 static void
 reset_ready (QmiClientWms *client,
              GAsyncResult *res)
@@ -188,6 +200,8 @@
     operation_shutdown (TRUE);
 }
 
+#endif
+
 static gboolean
 noop_cb (gpointer unused)
 {
@@ -206,7 +220,7 @@
     ctx->client = g_object_ref (client);
     ctx->cancellable = g_object_ref (cancellable);
 
-    /* Request to list supported messages? */
+#if defined HAVE_QMI_MESSAGE_WMS_GET_SUPPORTED_MESSAGES
     if (get_supported_messages_flag) {
         g_debug ("Asynchronously getting supported WMS messages...");
         qmi_client_wms_get_supported_messages (ctx->client,
@@ -217,8 +231,9 @@
                                                NULL);
         return;
     }
+#endif
 
-    /* Request to reset WMS service? */
+#if defined HAVE_QMI_MESSAGE_WMS_RESET
     if (reset_flag) {
         g_debug ("Asynchronously resetting WMS service...");
         qmi_client_wms_reset (ctx->client,
@@ -229,6 +244,7 @@
                               NULL);
         return;
     }
+#endif
 
     /* Just client allocate/release? */
     if (noop_flag) {
@@ -238,3 +254,5 @@
 
     g_warn_if_reached ();
 }
+
+#endif /* HAVE_QMI_SERVICE_WMS */
diff --git a/src/qmicli/qmicli.c b/src/qmicli/qmicli.c
index f084cc3..93cb546 100644
--- a/src/qmicli/qmicli.c
+++ b/src/qmicli/qmicli.c
@@ -231,8 +231,7 @@
 static void
 print_version_and_exit (void)
 {
-    g_print ("\n"
-             PROGRAM_NAME " " PROGRAM_VERSION "\n"
+    g_print (PROGRAM_NAME " " PROGRAM_VERSION "\n"
              "Copyright (C) 2012-2020 Aleksander Morgado\n"
              "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
              "This is free software: you are free to change and redistribute it.\n"
@@ -363,44 +362,96 @@
     /* Run the service-specific action */
     switch (service) {
     case QMI_SERVICE_DMS:
+#if defined HAVE_QMI_SERVICE_DMS
         qmicli_dms_run (dev, QMI_CLIENT_DMS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_NAS:
+#if defined HAVE_QMI_SERVICE_NAS
         qmicli_nas_run (dev, QMI_CLIENT_NAS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_WDS:
+#if defined HAVE_QMI_SERVICE_WDS
         qmicli_wds_run (dev, QMI_CLIENT_WDS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_PBM:
+#if defined HAVE_QMI_SERVICE_PBM
         qmicli_pbm_run (dev, QMI_CLIENT_PBM (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_PDC:
+#if defined HAVE_QMI_SERVICE_PDC
         qmicli_pdc_run (dev, QMI_CLIENT_PDC (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_UIM:
+#if defined HAVE_QMI_SERVICE_UIM
         qmicli_uim_run (dev, QMI_CLIENT_UIM (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_WMS:
+#if defined HAVE_QMI_SERVICE_WMS
         qmicli_wms_run (dev, QMI_CLIENT_WMS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_WDA:
+#if defined HAVE_QMI_SERVICE_WDA
         qmicli_wda_run (dev, QMI_CLIENT_WDA (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_VOICE:
+#if defined HAVE_QMI_SERVICE_VOICE
         qmicli_voice_run (dev, QMI_CLIENT_VOICE (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_LOC:
+#if defined HAVE_QMI_SERVICE_LOC
         qmicli_loc_run (dev, QMI_CLIENT_LOC (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_QOS:
+#if defined HAVE_QMI_SERVICE_QOS
         qmicli_qos_run (dev, QMI_CLIENT_QOS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_GAS:
+#if defined HAVE_QMI_SERVICE_GAS
         qmicli_gas_run (dev, QMI_CLIENT_GAS (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_DSD:
+#if defined HAVE_QMI_SERVICE_DSD
         qmicli_dsd_run (dev, QMI_CLIENT_DSD (client), cancellable);
         return;
+#else
+        break;
+#endif
     case QMI_SERVICE_UNKNOWN:
     case QMI_SERVICE_CTL:
     case QMI_SERVICE_AUTH:
@@ -438,8 +489,9 @@
     case QMI_SERVICE_PDS:
     case QMI_SERVICE_OMA:
     default:
-        g_assert_not_reached ();
+        break;
     }
+    g_assert_not_reached ();
 }
 
 static void
@@ -809,83 +861,96 @@
         actions_enabled++;
     }
 
-    /* DMS options? */
+#if defined HAVE_QMI_SERVICE_DMS
     if (qmicli_dms_options_enabled ()) {
         service = QMI_SERVICE_DMS;
         actions_enabled++;
     }
+#endif
 
-    /* NAS options? */
+#if defined HAVE_QMI_SERVICE_NAS
     if (qmicli_nas_options_enabled ()) {
         service = QMI_SERVICE_NAS;
         actions_enabled++;
     }
+#endif
 
-    /* WDS options? */
+#if defined HAVE_QMI_SERVICE_WDS
     if (qmicli_wds_options_enabled ()) {
         service = QMI_SERVICE_WDS;
         actions_enabled++;
     }
+#endif
 
-    /* PBM options? */
+#if defined HAVE_QMI_SERVICE_PBM
     if (qmicli_pbm_options_enabled ()) {
         service = QMI_SERVICE_PBM;
         actions_enabled++;
     }
+#endif
 
-    /* PDC options? */
+#if defined HAVE_QMI_SERVICE_PDC
     if (qmicli_pdc_options_enabled ()) {
         service = QMI_SERVICE_PDC;
         actions_enabled++;
     }
+#endif
 
-    /* UIM options? */
+#if defined HAVE_QMI_SERVICE_UIM
     if (qmicli_uim_options_enabled ()) {
         service = QMI_SERVICE_UIM;
         actions_enabled++;
     }
+#endif
 
-    /* WMS options? */
+#if defined HAVE_QMI_SERVICE_WMS
     if (qmicli_wms_options_enabled ()) {
         service = QMI_SERVICE_WMS;
         actions_enabled++;
     }
+#endif
 
-    /* WDA options? */
+#if defined HAVE_QMI_SERVICE_WDA
     if (qmicli_wda_options_enabled ()) {
         service = QMI_SERVICE_WDA;
         actions_enabled++;
     }
+#endif
 
-    /* VOICE options? */
+#if defined HAVE_QMI_SERVICE_VOICE
     if (qmicli_voice_options_enabled ()) {
         service = QMI_SERVICE_VOICE;
         actions_enabled++;
     }
+#endif
 
-    /* LOC options? */
+#if defined HAVE_QMI_SERVICE_LOC
     if (qmicli_loc_options_enabled ()) {
         service = QMI_SERVICE_LOC;
         actions_enabled++;
     }
+#endif
 
-    /* QOS options? */
+#if defined HAVE_QMI_SERVICE_QOS
     if (qmicli_qos_options_enabled ()) {
         service = QMI_SERVICE_QOS;
         actions_enabled++;
     }
+#endif
 
-    /* GAS options? */
+#if defined HAVE_QMI_SERVICE_GAS
     if (qmicli_gas_options_enabled ()) {
         service = QMI_SERVICE_GAS;
         actions_enabled++;
     }
+#endif
 
-    /* DSD options? */
+#if defined HAVE_QMI_SERVICE_DSD
     if (qmicli_dsd_options_enabled ()) {
         service = QMI_SERVICE_DSD;
         actions_enabled++;
     }
+#endif
 
     /* Cannot mix actions from different services */
     if (actions_enabled > 1) {
@@ -912,32 +977,45 @@
 
     /* Setup option context, process it and destroy it */
     context = g_option_context_new ("- Control QMI devices");
-    g_option_context_add_group (context,
-                                qmicli_dms_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_nas_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_wds_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_pbm_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_pdc_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_uim_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_wms_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_wda_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_voice_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_loc_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_qos_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_gas_get_option_group ());
-    g_option_context_add_group (context,
-                                qmicli_dsd_get_option_group ());
+#if defined HAVE_QMI_SERVICE_DMS
+    g_option_context_add_group (context, qmicli_dms_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_NAS
+    g_option_context_add_group (context, qmicli_nas_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_WDS
+    g_option_context_add_group (context, qmicli_wds_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_PBM
+    g_option_context_add_group (context, qmicli_pbm_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_PDC
+    g_option_context_add_group (context, qmicli_pdc_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_UIM
+    g_option_context_add_group (context, qmicli_uim_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_WMS
+    g_option_context_add_group (context, qmicli_wms_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_WDA
+    g_option_context_add_group (context, qmicli_wda_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_VOICE
+    g_option_context_add_group (context, qmicli_voice_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_LOC
+    g_option_context_add_group (context, qmicli_loc_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_QOS
+    g_option_context_add_group (context, qmicli_qos_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_GAS
+    g_option_context_add_group (context, qmicli_gas_get_option_group ());
+#endif
+#if defined HAVE_QMI_SERVICE_DSD
+    g_option_context_add_group (context, qmicli_dsd_get_option_group ());
+#endif
     g_option_context_add_main_entries (context, main_entries, NULL);
     if (!g_option_context_parse (context, &argc, &argv, &error)) {
         g_printerr ("error: %s\n",
diff --git a/src/qmicli/qmicli.h b/src/qmicli/qmicli.h
index 43926fe..5b31860 100644
--- a/src/qmicli/qmicli.h
+++ b/src/qmicli/qmicli.h
@@ -19,6 +19,7 @@
  */
 
 #include <glib.h>
+#include <libqmi-glib.h>
 
 #ifndef __QMICLI_H__
 #define __QMICLI_H__
@@ -28,95 +29,108 @@
                                            gboolean skip_cid_release);
 void          qmicli_expect_indications   (void);
 
-/* DMS group */
+#if defined HAVE_QMI_SERVICE_DMS
 GOptionGroup *qmicli_dms_get_option_group (void);
 gboolean      qmicli_dms_options_enabled  (void);
 void          qmicli_dms_run              (QmiDevice *device,
                                            QmiClientDms *client,
                                            GCancellable *cancellable);
+#endif
 
-/* WDS group */
+#if defined HAVE_QMI_SERVICE_WDS
 GOptionGroup *qmicli_wds_get_option_group (void);
 gboolean      qmicli_wds_options_enabled  (void);
 void          qmicli_wds_run              (QmiDevice *device,
                                            QmiClientWds *client,
                                            GCancellable *cancellable);
+#endif
 
-/* NAS group */
+#if defined HAVE_QMI_SERVICE_NAS
 GOptionGroup *qmicli_nas_get_option_group (void);
 gboolean      qmicli_nas_options_enabled  (void);
 void          qmicli_nas_run              (QmiDevice *device,
                                            QmiClientNas *client,
                                            GCancellable *cancellable);
+#endif
 
-/* PBM group */
+#if defined HAVE_QMI_SERVICE_PBM
 GOptionGroup *qmicli_pbm_get_option_group (void);
 gboolean      qmicli_pbm_options_enabled  (void);
 void          qmicli_pbm_run              (QmiDevice *device,
                                            QmiClientPbm *client,
                                            GCancellable *cancellable);
+#endif
 
-/* PDC group */
+#if defined HAVE_QMI_SERVICE_PDC
 GOptionGroup *qmicli_pdc_get_option_group (void);
 gboolean      qmicli_pdc_options_enabled  (void);
 void          qmicli_pdc_run              (QmiDevice *device,
                                            QmiClientPdc *client,
                                            GCancellable *cancellable);
+#endif
 
-/* UIM group */
+#if defined HAVE_QMI_SERVICE_UIM
 GOptionGroup *qmicli_uim_get_option_group (void);
 gboolean      qmicli_uim_options_enabled  (void);
 void          qmicli_uim_run              (QmiDevice *device,
                                            QmiClientUim *client,
                                            GCancellable *cancellable);
+#endif
 
-/* WMS group */
+#if defined HAVE_QMI_SERVICE_WMS
 GOptionGroup *qmicli_wms_get_option_group (void);
 gboolean      qmicli_wms_options_enabled  (void);
 void          qmicli_wms_run              (QmiDevice *device,
                                            QmiClientWms *client,
                                            GCancellable *cancellable);
+#endif
 
-/* WDA group */
+#if defined HAVE_QMI_SERVICE_WDA
 GOptionGroup *qmicli_wda_get_option_group (void);
 gboolean      qmicli_wda_options_enabled  (void);
 void          qmicli_wda_run              (QmiDevice *device,
                                            QmiClientWda *client,
                                            GCancellable *cancellable);
+#endif
 
-/* Voice group */
+#if defined HAVE_QMI_SERVICE_VOICE
 GOptionGroup *qmicli_voice_get_option_group (void);
 gboolean      qmicli_voice_options_enabled  (void);
 void          qmicli_voice_run              (QmiDevice *device,
                                              QmiClientVoice *client,
                                              GCancellable *cancellable);
+#endif
 
-/* Location group */
+#if defined HAVE_QMI_SERVICE_LOC
 GOptionGroup *qmicli_loc_get_option_group (void);
 gboolean      qmicli_loc_options_enabled  (void);
 void          qmicli_loc_run              (QmiDevice *device,
                                            QmiClientLoc *client,
                                            GCancellable *cancellable);
+#endif
 
-/* QoS group */
+#if defined HAVE_QMI_SERVICE_QOS
 GOptionGroup *qmicli_qos_get_option_group (void);
 gboolean      qmicli_qos_options_enabled  (void);
 void          qmicli_qos_run              (QmiDevice *device,
                                            QmiClientQos *client,
                                            GCancellable *cancellable);
+#endif
 
-/* GAS group */
+#if defined HAVE_QMI_SERVICE_GAS
 GOptionGroup *qmicli_gas_get_option_group (void);
 gboolean      qmicli_gas_options_enabled  (void);
 void          qmicli_gas_run              (QmiDevice *device,
                                            QmiClientGas *client,
                                            GCancellable *cancellable);
+#endif
 
-/* DSD group */
+#if defined HAVE_QMI_SERVICE_DSD
 GOptionGroup *qmicli_dsd_get_option_group (void);
 gboolean      qmicli_dsd_options_enabled  (void);
 void          qmicli_dsd_run              (QmiDevice *device,
                                            QmiClientDsd *client,
                                            GCancellable *cancellable);
+#endif
 
 #endif /* __QMICLI_H__ */
diff --git a/src/qmicli/test/test-helpers.c b/src/qmicli/test/test-helpers.c
index 7523c0a..84a98ea 100644
--- a/src/qmicli/test/test-helpers.c
+++ b/src/qmicli/test/test-helpers.c
@@ -118,6 +118,21 @@
 /******************************************************************************/
 
 static void
+test_helpers_binary_array_from_string_0 (void)
+{
+    const guint8 expected[] = {
+        0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0xAB, 0xCD, 0xEF
+    };
+    const gchar *str = "12:34:56:78:9A:BC:DE:F0:ab:cd:ef";
+    GArray *out = NULL;
+
+    g_assert (qmicli_read_binary_array_from_string (str, &out));
+    g_assert (out != NULL);
+    g_assert_cmpmem ((guint8 *)(out->data), out->len, expected, G_N_ELEMENTS (expected));
+    g_array_unref (out);
+}
+
+static void
 test_helpers_binary_array_from_string_1 (void)
 {
     const guint8 expected[] = {
@@ -128,9 +143,7 @@
 
     g_assert (qmicli_read_binary_array_from_string (str, &out));
     g_assert (out != NULL);
-    g_assert_cmpuint (out->len, ==, strlen (str) / 2);
-    g_assert (memcmp ((guint8 *)(out->data), expected, out->len) == 0);
-
+    g_assert_cmpmem ((guint8 *)(out->data), out->len, expected, G_N_ELEMENTS (expected));
     g_array_unref (out);
 }
 
@@ -292,6 +305,7 @@
     g_test_add_func ("/qmicli/helpers/raw-printable/3",  test_helpers_raw_printable_3);
     g_test_add_func ("/qmicli/helpers/raw-printable/4",  test_helpers_raw_printable_4);
 
+    g_test_add_func ("/qmicli/helpers/binary-array-from-string/0", test_helpers_binary_array_from_string_0);
     g_test_add_func ("/qmicli/helpers/binary-array-from-string/1", test_helpers_binary_array_from_string_1);
     g_test_add_func ("/qmicli/helpers/binary-array-from-string/2", test_helpers_binary_array_from_string_2);
     g_test_add_func ("/qmicli/helpers/binary-array-from-string/3", test_helpers_binary_array_from_string_3);