diff options
author | Dylan Van Assche <me@dylanvanassche.be> | 2023-01-08 21:11:05 +0100 |
---|---|---|
committer | Dylan Van Assche <me@dylanvanassche.be> | 2023-08-12 17:20:48 +0200 |
commit | fdd16d4c4a3deae6b5e0a3d9fc3b1b39479381a9 (patch) | |
tree | 16a0da717d48603881457275583b726397095498 | |
parent | 9caad8a1ebcaf5e8ac5ad3ca2dfe1b9aacb249cd (diff) |
libqmi-glib,qmicli: implement IMS service
IMS is the IMS Settings service which exposes the settings of various
IMS services such as IMS SMS, IMS Voice, IMS Video Telephony, IMS UE to
TAS, and IMS Video Share. Implement the setting indicators for those
services so we know which services are enabled and which not.
-rw-r--r-- | build-aux/qmi-codegen/utils.py | 4 | ||||
-rw-r--r-- | data/qmi-service-ims.json | 71 | ||||
-rw-r--r-- | docs/reference/libqmi-glib/libqmi-glib-common.sections | 1 | ||||
-rw-r--r-- | docs/reference/libqmi-glib/libqmi-glib-docs.xml | 9 | ||||
-rw-r--r-- | src/libqmi-glib/generated/meson.build | 1 | ||||
-rw-r--r-- | src/libqmi-glib/libqmi-glib.h | 2 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-device.c | 7 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-message.c | 6 | ||||
-rw-r--r-- | src/qmicli/meson.build | 1 | ||||
-rw-r--r-- | src/qmicli/qmicli-ims.c | 227 | ||||
-rw-r--r-- | src/qmicli/qmicli.c | 18 | ||||
-rw-r--r-- | src/qmicli/qmicli.h | 8 |
12 files changed, 350 insertions, 5 deletions
diff --git a/build-aux/qmi-codegen/utils.py b/build-aux/qmi-codegen/utils.py index c14382b..b4313a5 100644 --- a/build-aux/qmi-codegen/utils.py +++ b/build-aux/qmi-codegen/utils.py @@ -70,8 +70,8 @@ def add_header_start(f, output_name, service): "#include <gio/gio.h>\n" "\n" "#include \"qmi-enums.h\"\n") - # CTL, DPM, GMS and ATR don't have enums - if service not in ('CTL', 'DPM', 'GMS', 'ATR'): + # CTL, DPM, GMS, ATR and IMS don't have enums + if service not in ('CTL', 'DPM', 'GMS', 'ATR', 'IMS'): template += ( "#include \"qmi-enums-${service}.h\"\n") if service == 'CTL': diff --git a/data/qmi-service-ims.json b/data/qmi-service-ims.json new file mode 100644 index 0000000..cfbeeb8 --- /dev/null +++ b/data/qmi-service-ims.json @@ -0,0 +1,71 @@ +[ + // ********************************************************************************* + { "name" : "IMS", + "type" : "Service" }, + + // ********************************************************************************* + { "name" : "QMI Client IMS", + "type" : "Client", + "since" : "1.34" }, + + // ********************************************************************************* + { "name" : "QMI Message IMS", + "type" : "Message-ID-Enum" }, + + // ********************************************************************************* + { "name" : "Get IMS Services Enabled Setting", + "type" : "Message", + "service" : "IMS", + "id" : "0x0090", + "since" : "1.34", + "output" : [ { "common-ref" : "Operation Result" }, + { "name" : "IMS Voice Service Enabled", + "id" : "0x11", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS Video Telephony Service Enabled", + "id" : "0x12", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS Voice WiFi Service Enabled", + "id" : "0x15", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS Registration Service Enabled", + "id" : "0x18", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS UT Service Enabled", + "id" : "0x19", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS SMS Service Enabled", + "id" : "0x1A", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "IMS USSD Service Enabled", + "id" : "0x1C", + "type" : "TLV", + "since" : "1.34", + "format" : "guint8", + "public-format" : "gboolean", + "prerequisites" : [ { "common-ref" : "Success" } ] } ] } +] diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections index 699ba95..7a6cbb4 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-common.sections +++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections @@ -33,6 +33,7 @@ HAVE_QMI_SERVICE_DPM HAVE_QMI_SERVICE_FOX HAVE_QMI_SERVICE_IMSP HAVE_QMI_SERVICE_IMSA +HAVE_QMI_SERVICE_IMS </SECTION> <SECTION> diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml index 6a6dd3f..e8c724d 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml +++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml @@ -609,6 +609,15 @@ </chapter> <chapter> + <title>IP Multimedia Subsystem Settings Service (IMS)</title> + <xi:include href="xml/qmi-client-ims.xml"/> + <section> + <title>IMS Requests</title> + <xi:include href="xml/qmi-message-ims-get-ims-services-enabled-setting.xml"/> + </section> + </chapter> + + <chapter> <title>Compatibility with older versions</title> <xi:include href="xml/qmi-compat.xml"/> </chapter> diff --git a/src/libqmi-glib/generated/meson.build b/src/libqmi-glib/generated/meson.build index 7869e08..235814d 100644 --- a/src/libqmi-glib/generated/meson.build +++ b/src/libqmi-glib/generated/meson.build @@ -240,6 +240,7 @@ services = [ 'dms', 'dpm', 'dsd', + 'ims', 'imsa', 'imsp', 'fox', diff --git a/src/libqmi-glib/libqmi-glib.h b/src/libqmi-glib/libqmi-glib.h index c655749..a097812 100644 --- a/src/libqmi-glib/libqmi-glib.h +++ b/src/libqmi-glib/libqmi-glib.h @@ -107,6 +107,8 @@ #include "qmi-enums-imsa.h" #include "qmi-imsa.h" +#include "qmi-ims.h" + /* generated */ #include "qmi-error-types.h" #include "qmi-enum-types.h" diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 6b1075c..6a9acda 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -58,6 +58,7 @@ #include "qmi-dpm.h" #include "qmi-fox.h" #include "qmi-atr.h" +#include "qmi-ims.h" #include "qmi-imsp.h" #include "qmi-imsa.h" #include "qmi-utils.h" @@ -1331,6 +1332,11 @@ qmi_device_allocate_client (QmiDevice *self, ctx->client_type = QMI_TYPE_CLIENT_IMSA; #endif break; + case QMI_SERVICE_IMS: +#if defined HAVE_QMI_SERVICE_IMS + ctx->client_type = QMI_TYPE_CLIENT_IMS; +#endif + break; case QMI_SERVICE_UNKNOWN: g_assert_not_reached (); @@ -1341,7 +1347,6 @@ qmi_device_allocate_client (QmiDevice *self, case QMI_SERVICE_QCHAT: case QMI_SERVICE_RMTFS: case QMI_SERVICE_TEST: - case QMI_SERVICE_IMS: case QMI_SERVICE_ADC: case QMI_SERVICE_CSD: case QMI_SERVICE_MFS: diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c index 4c00c5d..0515373 100644 --- a/src/libqmi-glib/qmi-message.c +++ b/src/libqmi-glib/qmi-message.c @@ -1747,6 +1747,11 @@ qmi_message_get_printable_full (QmiMessage *self, contents = __qmi_message_imsa_get_printable (self, context, line_prefix); #endif break; + case QMI_SERVICE_IMS: +#if defined HAVE_QMI_SERVICE_IMS + contents = __qmi_message_ims_get_printable (self, context, line_prefix); +#endif + break; case QMI_SERVICE_UNKNOWN: g_assert_not_reached (); @@ -1758,7 +1763,6 @@ qmi_message_get_printable_full (QmiMessage *self, case QMI_SERVICE_RMTFS: case QMI_SERVICE_TEST: case QMI_SERVICE_SAR: - case QMI_SERVICE_IMS: case QMI_SERVICE_ADC: case QMI_SERVICE_CSD: case QMI_SERVICE_MFS: diff --git a/src/qmicli/meson.build b/src/qmicli/meson.build index 23de684..19a6b02 100644 --- a/src/qmicli/meson.build +++ b/src/qmicli/meson.build @@ -19,6 +19,7 @@ sources = files( 'qmicli-dms.c', 'qmicli-dpm.c', 'qmicli-dsd.c', + 'qmicli-ims.c', 'qmicli-imsa.c', 'qmicli-imsp.c', 'qmicli-fox.c', diff --git a/src/qmicli/qmicli-ims.c b/src/qmicli/qmicli-ims.c new file mode 100644 index 0000000..97cf0e7 --- /dev/null +++ b/src/qmicli/qmicli-ims.c @@ -0,0 +1,227 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * qmicli -- Command line interface to control QMI devices + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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) 2023 Dylan Van Assche <me@dylanvanassche.be> + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <string.h> +#include <assert.h> + +#include <glib.h> +#include <gio/gio.h> + +#include <libqmi-glib.h> + +#include "qmicli.h" +#include "qmicli-helpers.h" + +#if defined HAVE_QMI_SERVICE_IMS + +/* Context */ +typedef struct { + QmiDevice *device; + QmiClientIms *client; + GCancellable *cancellable; +} Context; +static Context *ctx; + +/* Options */ +static gboolean get_services_enabled_flag; +static gboolean noop_flag; + +static GOptionEntry entries[] = { +#if defined HAVE_QMI_MESSAGE_IMS_GET_IMS_SERVICES_ENABLED_SETTING + { "ims-get-ims-services-enabled-setting", 0, 0, G_OPTION_ARG_NONE, &get_services_enabled_flag, + "Get IMS Services Enabled Setting", + NULL + }, +#endif + { "ims-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag, + "Just allocate or release a IMS client. Use with `--client-no-release-cid' and/or `--client-cid'", + NULL + }, + { NULL } +}; + +GOptionGroup * +qmicli_ims_get_option_group (void) +{ + GOptionGroup *group; + + group = g_option_group_new ("ims", + "IMS options:", + "Show IP Multimedia Subsystem Settings Service options", + NULL, + NULL); + g_option_group_add_entries (group, entries); + + return group; +} + +gboolean +qmicli_ims_options_enabled (void) +{ + static guint n_actions = 0; + static gboolean checked = FALSE; + + if (checked) + return !!n_actions; + + n_actions = (get_services_enabled_flag + + noop_flag); + + if (n_actions > 1) { + g_printerr ("error: too many IMS actions requested\n"); + exit (EXIT_FAILURE); + } + + checked = TRUE; + return !!n_actions; +} + +static void +context_free (Context *context) +{ + if (!context) + return; + + if (context->cancellable) + g_object_unref (context->cancellable); + if (context->device) + g_object_unref (context->device); + if (context->client) + g_object_unref (context->client); + g_slice_free (Context, context); +} + +static void +operation_shutdown (gboolean operation_status) +{ + /* Cleanup context and finish async operation */ + context_free (ctx); + qmicli_async_operation_done (operation_status, FALSE); +} + +#if defined HAVE_QMI_MESSAGE_IMS_GET_IMS_SERVICES_ENABLED_SETTING + +static void +get_services_enabled_ready (QmiClientIms *client, + GAsyncResult *res) +{ + QmiMessageImsGetImsServicesEnabledSettingOutput *output; + gboolean service_voice_enabled; + gboolean service_vt_enabled; + gboolean service_voice_wifi_enabled; + gboolean service_ims_registration_enabled; + gboolean service_ut_enabled; + gboolean service_sms_enabled; + gboolean service_ussd_enabled; + GError *error = NULL; + + output = qmi_client_ims_get_ims_services_enabled_setting_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_ims_get_ims_services_enabled_setting_output_get_result (output, &error)) { + g_printerr ("error: couldn't get IMS services enabled setting: %s\n", error->message); + g_error_free (error); + qmi_message_ims_get_ims_services_enabled_setting_output_unref (output); + operation_shutdown (FALSE); + return; + } + + g_print ("[%s] IMS services:\n", qmi_device_get_path_display (ctx->device)); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_voice_service_enabled (output, &service_voice_enabled, NULL)) + g_print ("\t IMS registration enabled: %s\n", service_ims_registration_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_video_telephony_service_enabled (output, &service_vt_enabled, NULL)) + g_print ("\t Voice service enabled: %s\n", service_voice_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_voice_wifi_service_enabled (output, &service_voice_wifi_enabled, NULL)) + g_print ("\t Voice WiFi service enabled: %s\n", service_voice_wifi_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_registration_service_enabled (output, &service_ims_registration_enabled, NULL)) + g_print ("\tVideo Telephony service enabled: %s\n", service_vt_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_ut_service_enabled (output, &service_ut_enabled, NULL)) + g_print ("\t UE to TAS service enabled: %s\n", service_ut_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_sms_service_enabled (output, &service_sms_enabled, NULL)) + g_print ("\t SMS service enabled: %s\n", service_sms_enabled? "yes" : "no"); + + if (qmi_message_ims_get_ims_services_enabled_setting_output_get_ims_ussd_service_enabled (output, &service_ussd_enabled, NULL)) + g_print ("\t USSD service enabled: %s\n", service_ut_enabled? "yes" : "no"); + + qmi_message_ims_get_ims_services_enabled_setting_output_unref (output); + operation_shutdown (TRUE); +} + +#endif /* HAVE_QMI_MESSAGE_IMS_GET_IMS_SERVICES_ENABLED_SETTING */ + +static gboolean +noop_cb (gpointer unused) +{ + operation_shutdown (TRUE); + return FALSE; +} + +void +qmicli_ims_run (QmiDevice *device, + QmiClientIms *client, + GCancellable *cancellable) +{ + /* Initialize context */ + ctx = g_slice_new (Context); + ctx->device = g_object_ref (device); + ctx->client = g_object_ref (client); + ctx->cancellable = g_object_ref (cancellable); + +#if defined HAVE_QMI_MESSAGE_IMS_GET_IMS_SERVICES_ENABLED_SETTING + if (get_services_enabled_flag) { + g_debug ("Asynchronously getting services enabled setting..."); + + qmi_client_ims_get_ims_services_enabled_setting (ctx->client, + NULL, + 10, + ctx->cancellable, + (GAsyncReadyCallback)get_services_enabled_ready, + NULL); + return; + } +#endif /* HAVE_QMI_MESSAGE_IMS_GET_IMS_SERVICES_ENABLED_SETTING */ + + /* Just client allocate/release? */ + if (noop_flag) { + g_idle_add (noop_cb, NULL); + return; + } + + g_warn_if_reached (); +} + +#endif /* HAVE_QMI_SERVICE_IMS */ + diff --git a/src/qmicli/qmicli.c b/src/qmicli/qmicli.c index 7e8de5c..e227244 100644 --- a/src/qmicli/qmicli.c +++ b/src/qmicli/qmicli.c @@ -497,6 +497,13 @@ allocate_client_ready (QmiDevice *dev, #else break; #endif + case QMI_SERVICE_IMS: +#if defined HAVE_QMI_SERVICE_IMS + qmicli_ims_run (dev, QMI_CLIENT_IMS (client), cancellable); + return; +#else + break; +#endif case QMI_SERVICE_UNKNOWN: case QMI_SERVICE_CTL: case QMI_SERVICE_AUTH: @@ -505,7 +512,6 @@ allocate_client_ready (QmiDevice *dev, case QMI_SERVICE_QCHAT: case QMI_SERVICE_RMTFS: case QMI_SERVICE_TEST: - case QMI_SERVICE_IMS: case QMI_SERVICE_ADC: case QMI_SERVICE_CSD: case QMI_SERVICE_MFS: @@ -973,6 +979,13 @@ parse_actions (void) } #endif +#if defined HAVE_QMI_SERVICE_IMS + if (qmicli_ims_options_enabled ()) { + service = QMI_SERVICE_IMS; + actions_enabled++; + } +#endif + /* Cannot mix actions from different services */ if (actions_enabled > 1) { g_printerr ("error: cannot execute multiple actions of different services\n"); @@ -1058,6 +1071,9 @@ int main (int argc, char **argv) #if defined HAVE_QMI_SERVICE_IMSA g_option_context_add_group (context, qmicli_imsa_get_option_group ()); #endif +#if defined HAVE_QMI_SERVICE_IMS + g_option_context_add_group (context, qmicli_ims_get_option_group ()); +#endif g_option_context_add_group (context, qmicli_link_management_get_option_group ()); g_option_context_add_group (context, qmicli_qmiwwan_get_option_group ()); g_option_context_add_main_entries (context, main_entries, NULL); diff --git a/src/qmicli/qmicli.h b/src/qmicli/qmicli.h index 9b8f41e..0a5fa97 100644 --- a/src/qmicli/qmicli.h +++ b/src/qmicli/qmicli.h @@ -201,4 +201,12 @@ void qmicli_imsa_run (QmiDevice *device, GCancellable *cancellable); #endif +#if defined HAVE_QMI_SERVICE_IMS +GOptionGroup *qmicli_ims_get_option_group (void); +gboolean qmicli_ims_options_enabled (void); +void qmicli_ims_run (QmiDevice *device, + QmiClientIms *client, + GCancellable *cancellable); +#endif + #endif /* __QMICLI_H__ */ |