[PATCH 1/2] modem-3gpp: allow loading and changing EPS UE mode of operation

Aleksander Morgado aleksander at aleksander.es
Sat Jan 20 14:43:49 UTC 2018


On 28/12/17 18:41, Aleksander Morgado wrote:
> The UE modes of operation for LTE are defined in 3GPP TS 24.301 (e.g.
> section 4.3 in v10.3.0):
>   * PS mode 1: EPS only, 'voice centric'
>   * PS mode 2: EPS only, 'data centric'
>   * CS/PS mode 1: EPS and non-EPS, 'voice centric'
>   * CS/PS mode 2: EPS and non-EPS, 'data centric'
> 
> The mode specifies, among other things, how the UE should behave w.r.t
> CS fallback depending on the capabilities reported by the network.

Pushed to git master.

> ---
>  cli/mmcli-modem-3gpp.c                             |  76 +++++++++
>  cli/mmcli-modem.c                                  |   9 +-
>  docs/reference/api/ModemManager-sections.txt       |   1 +
>  docs/reference/libmm-glib/libmm-glib-sections.txt  |  13 ++
>  include/ModemManager-enums.h                       |  18 +++
>  ...g.freedesktop.ModemManager1.Modem.Modem3gpp.xml |  19 +++
>  libmm-glib/mm-common-helpers.c                     |  22 +++
>  libmm-glib/mm-common-helpers.h                     |   3 +
>  libmm-glib/mm-modem-3gpp.c                         |  53 ++++++
>  libmm-glib/mm-modem-3gpp.h                         |  14 ++
>  src/mm-iface-modem-3gpp.c                          | 177 ++++++++++++++++++++-
>  src/mm-iface-modem-3gpp.h                          |  17 ++
>  12 files changed, 418 insertions(+), 4 deletions(-)
> 
> diff --git a/cli/mmcli-modem-3gpp.c b/cli/mmcli-modem-3gpp.c
> index a785d025..b687d88d 100644
> --- a/cli/mmcli-modem-3gpp.c
> +++ b/cli/mmcli-modem-3gpp.c
> @@ -49,6 +49,7 @@ static Context *ctx;
>  static gboolean scan_flag;
>  static gboolean register_home_flag;
>  static gchar *register_in_operator_str;
> +static gchar *set_eps_ue_mode_operation_str;
>  static gboolean ussd_status_flag;
>  static gchar *ussd_initiate_str;
>  static gchar *ussd_respond_str;
> @@ -67,6 +68,10 @@ static GOptionEntry entries[] = {
>        "Request a given modem to register in the network of the given operator",
>        "[MCCMNC]"
>      },
> +    { "3gpp-set-eps-ue-mode-operation", 0, 0, G_OPTION_ARG_STRING, &set_eps_ue_mode_operation_str,
> +      "Set the UE mode of operation for EPS",
> +      "[ps-1|ps-2|csps-1|csps-2]"
> +    },
>      { "3gpp-ussd-status", 0, 0, G_OPTION_ARG_NONE, &ussd_status_flag,
>        "Show status of any ongoing USSD session",
>        NULL
> @@ -113,6 +118,7 @@ mmcli_modem_3gpp_options_enabled (void)
>      n_actions = (scan_flag +
>                   register_home_flag +
>                   !!register_in_operator_str +
> +                 !!set_eps_ue_mode_operation_str +
>                   ussd_status_flag +
>                   !!ussd_initiate_str +
>                   !!ussd_respond_str +
> @@ -291,6 +297,45 @@ register_ready (MMModem3gpp  *modem_3gpp,
>      mmcli_async_operation_done ();
>  }
>  
> +static void
> +set_eps_ue_mode_operation_process_reply (gboolean      result,
> +                                         const GError *error)
> +{
> +    if (!result) {
> +        g_printerr ("error: couldn't set UE mode of operation for EPS: '%s'\n",
> +                    error ? error->message : "unknown error");
> +        exit (EXIT_FAILURE);
> +    }
> +
> +    g_print ("successfully set UE mode of operation for EPS\n");
> +}
> +
> +static void
> +set_eps_ue_mode_operation_ready (MMModem3gpp  *modem,
> +                                 GAsyncResult *result)
> +{
> +    gboolean operation_result;
> +    GError *error = NULL;
> +
> +    operation_result = mm_modem_3gpp_set_eps_ue_mode_operation_finish (modem, result, &error);
> +    set_eps_ue_mode_operation_process_reply (operation_result, error);
> +
> +    mmcli_async_operation_done ();
> +}
> +
> +static void
> +parse_eps_ue_mode_operation (MMModem3gppEpsUeModeOperation *uemode)
> +{
> +    GError *error = NULL;
> +
> +    *uemode = mm_common_get_eps_ue_mode_operation_from_string (set_eps_ue_mode_operation_str, &error);
> +    if (error) {
> +        g_printerr ("error: couldn't parse UE mode of operation for EPS: '%s'\n",
> +                    error->message);
> +        exit (EXIT_FAILURE);
> +    }
> +}
> +
>  static void
>  print_ussd_status (void)
>  {
> @@ -438,6 +483,21 @@ get_modem_ready (GObject      *source,
>          return;
>      }
>  
> +    /* Request to set UE mode of operation for EPS? */
> +    if (set_eps_ue_mode_operation_str) {
> +        MMModem3gppEpsUeModeOperation uemode;
> +
> +        parse_eps_ue_mode_operation (&uemode);
> +
> +        g_debug ("Asynchronously setting UE mode of operation for EPS...");
> +        mm_modem_3gpp_set_eps_ue_mode_operation (ctx->modem_3gpp,
> +                                                 uemode,
> +                                                 ctx->cancellable,
> +                                                 (GAsyncReadyCallback)set_eps_ue_mode_operation_ready,
> +                                                 NULL);
> +        return;
> +    }
> +
>      /* Request to initiate USSD session? */
>      if (ussd_initiate_str) {
>          ensure_modem_3gpp_ussd ();
> @@ -538,6 +598,22 @@ mmcli_modem_3gpp_run_synchronous (GDBusConnection *connection)
>          return;
>      }
>  
> +    /* Request to set UE mode of operation for EPS? */
> +    if (set_eps_ue_mode_operation_str) {
> +        MMModem3gppEpsUeModeOperation uemode;
> +        gboolean                      result;
> +
> +        parse_eps_ue_mode_operation (&uemode);
> +
> +        g_debug ("Synchronously setting UE mode of operation for EPS...");
> +        result = mm_modem_3gpp_set_eps_ue_mode_operation_sync (ctx->modem_3gpp,
> +                                                               uemode,
> +                                                               NULL,
> +                                                               &error);
> +        set_eps_ue_mode_operation_process_reply (result, error);
> +        return;
> +    }
> +
>      /* Request to show USSD status? */
>      if (ussd_status_flag) {
>          ensure_modem_3gpp_ussd ();
> diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c
> index a3c1152c..0f220f25 100644
> --- a/cli/mmcli-modem.c
> +++ b/cli/mmcli-modem.c
> @@ -470,15 +470,18 @@ print_modem_info (void)
>                   "           |    operator id: '%s'\n"
>                   "           |  operator name: '%s'\n"
>                   "           |   subscription: '%s'\n"
> -                 "           |   registration: '%s'\n",
> +                 "           |   registration: '%s'\n"
> +                 "           |    EPS UE mode: '%s'\n",
>                   VALIDATE_UNKNOWN (mm_modem_3gpp_get_imei (ctx->modem_3gpp)),
>                   facility_locks,
>                   VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_code (ctx->modem_3gpp)),
>                   VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_name (ctx->modem_3gpp)),
>                   mm_modem_3gpp_subscription_state_get_string (
> -                     mm_modem_3gpp_get_subscription_state ((ctx->modem_3gpp))),
> +                     mm_modem_3gpp_get_subscription_state (ctx->modem_3gpp)),
>                   mm_modem_3gpp_registration_state_get_string (
> -                     mm_modem_3gpp_get_registration_state ((ctx->modem_3gpp))));
> +                     mm_modem_3gpp_get_registration_state (ctx->modem_3gpp)),
> +                 mm_modem_3gpp_eps_ue_mode_operation_get_string (
> +                     mm_modem_3gpp_get_eps_ue_mode_operation (ctx->modem_3gpp)));
>  
>          g_free (facility_locks);
>      }
> diff --git a/docs/reference/api/ModemManager-sections.txt b/docs/reference/api/ModemManager-sections.txt
> index a60c3a41..497f6e38 100644
> --- a/docs/reference/api/ModemManager-sections.txt
> +++ b/docs/reference/api/ModemManager-sections.txt
> @@ -22,6 +22,7 @@ MMModem3gppNetworkAvailability
>  MMModem3gppSubscriptionState
>  MMModem3gppRegistrationState
>  MMModem3gppUssdSessionState
> +MMModem3gppEpsUeModeOperation
>  MMModemAccessTechnology
>  MMModemBand
>  MMModemCapability
> diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt
> index fd790475..77df5a79 100644
> --- a/docs/reference/libmm-glib/libmm-glib-sections.txt
> +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt
> @@ -283,6 +283,9 @@ mm_modem_3gpp_register_sync
>  mm_modem_3gpp_scan
>  mm_modem_3gpp_scan_finish
>  mm_modem_3gpp_scan_sync
> +mm_modem_3gpp_set_eps_ue_mode_operation
> +mm_modem_3gpp_set_eps_ue_mode_operation_finish
> +mm_modem_3gpp_set_eps_ue_mode_operation_sync
>  <SUBSECTION Standard>
>  MMModem3gppClass
>  MM_IS_MODEM_3GPP
> @@ -1325,6 +1328,7 @@ mm_modem_3gpp_subscription_state_get_string
>  mm_modem_3gpp_facility_build_string_from_mask
>  mm_modem_3gpp_network_availability_get_string
>  mm_modem_3gpp_ussd_session_state_get_string
> +mm_modem_3gpp_eps_ue_mode_operation_get_string
>  mm_modem_cdma_registration_state_get_string
>  mm_modem_cdma_activation_state_get_string
>  mm_modem_cdma_rm_protocol_get_string
> @@ -1375,6 +1379,7 @@ mm_modem_3gpp_subscription_state_build_string_from_mask
>  mm_modem_3gpp_facility_get_string
>  mm_modem_3gpp_network_availability_build_string_from_mask
>  mm_modem_3gpp_ussd_session_state_build_string_from_mask
> +mm_modem_3gpp_eps_ue_mode_operation_build_string_from_mask
>  mm_firmware_image_type_build_string_from_mask
>  mm_modem_port_type_build_string_from_mask
>  mm_oma_feature_get_string
> @@ -1394,6 +1399,7 @@ MM_TYPE_MODEM_3GPP_NETWORK_AVAILABILITY
>  MM_TYPE_MODEM_3GPP_REGISTRATION_STATE
>  MM_TYPE_MODEM_3GPP_SUBSCRIPTION_STATE
>  MM_TYPE_MODEM_3GPP_USSD_SESSION_STATE
> +MM_TYPE_MODEM_3GPP_EPS_UE_MODE_OPERATION
>  MM_TYPE_MODEM_ACCESS_TECHNOLOGY
>  MM_TYPE_MODEM_BAND
>  MM_TYPE_MODEM_CAPABILITY
> @@ -1432,6 +1438,7 @@ mm_modem_3gpp_network_availability_get_type
>  mm_modem_3gpp_registration_state_get_type
>  mm_modem_3gpp_subscription_state_get_type
>  mm_modem_3gpp_ussd_session_state_get_type
> +mm_modem_3gpp_eps_ue_mode_operation_get_type
>  mm_modem_access_technology_get_type
>  mm_modem_band_get_type
>  mm_modem_capability_get_type
> @@ -1666,6 +1673,7 @@ mm_gdbus_modem3gpp_get_operator_name
>  mm_gdbus_modem3gpp_dup_operator_name
>  mm_gdbus_modem3gpp_get_enabled_facility_locks
>  mm_gdbus_modem3gpp_get_subscription_state
> +mm_gdbus_modem3gpp_get_eps_ue_mode_operation
>  <SUBSECTION Methods>
>  mm_gdbus_modem3gpp_call_register
>  mm_gdbus_modem3gpp_call_register_finish
> @@ -1673,9 +1681,13 @@ mm_gdbus_modem3gpp_call_register_sync
>  mm_gdbus_modem3gpp_call_scan
>  mm_gdbus_modem3gpp_call_scan_finish
>  mm_gdbus_modem3gpp_call_scan_sync
> +mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation
> +mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_finish
> +mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_sync
>  <SUBSECTION Private>
>  mm_gdbus_modem3gpp_complete_register
>  mm_gdbus_modem3gpp_complete_scan
> +mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation
>  mm_gdbus_modem3gpp_interface_info
>  mm_gdbus_modem3gpp_override_properties
>  mm_gdbus_modem3gpp_set_enabled_facility_locks
> @@ -1684,6 +1696,7 @@ mm_gdbus_modem3gpp_set_operator_code
>  mm_gdbus_modem3gpp_set_operator_name
>  mm_gdbus_modem3gpp_set_registration_state
>  mm_gdbus_modem3gpp_set_subscription_state
> +mm_gdbus_modem3gpp_set_eps_ue_mode_operation
>  <SUBSECTION Standard>
>  MM_GDBUS_IS_MODEM3GPP
>  MM_GDBUS_MODEM3GPP
> diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h
> index ff4779fd..8f05ec00 100644
> --- a/include/ModemManager-enums.h
> +++ b/include/ModemManager-enums.h
> @@ -1155,6 +1155,24 @@ typedef enum { /*< underscore_name=mm_modem_3gpp_ussd_session_state >*/
>      MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE = 3,
>  } MMModem3gppUssdSessionState;
>  
> +/**
> + * MMModem3gppEpsUeModeOperation:
> + * @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN: Unknown or not applicable.
> + * @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1: PS mode 1 of operation: EPS only, voice-centric.
> + * @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2: PS mode 2 of operation: EPS only, data-centric.
> + * @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1: CS/PS mode 1 of operation: EPS and non-EPS, voice-centric.
> + * @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2: CS/PS mode 2 of operation: EPS and non-EPS, data-centric.
> + *
> + * UE mode of operation for EPS, as per 3GPP TS 24.301.
> + */
> +typedef enum { /*< underscore_name=mm_modem_3gpp_eps_ue_mode_operation >*/
> +    MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN = 0,
> +    MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1    = 1,
> +    MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2    = 2,
> +    MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1  = 3,
> +    MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2  = 4,
> +} MMModem3gppEpsUeModeOperation;
> +
>  /**
>   * MMFirmwareImageType:
>   * @MM_FIRMWARE_IMAGE_TYPE_UNKNOWN: Unknown firmware type.
> diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
> index 6d082f70..1aaba4c0 100644
> --- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
> +++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
> @@ -85,6 +85,16 @@
>        <arg name="results" type="aa{sv}" direction="out" />
>      </method>
>  
> +    <!--
> +        SetEpsUeModeOperation:
> +        @mode: a <link linkend="MMModem3gppEpsUeModeOperation">MMModem3gppEpsUeModeOperation</link>.
> +
> +        Sets the UE mode of operation for EPS.
> +    -->
> +    <method name="SetEpsUeModeOperation">
> +      <arg name="mode" type="u" direction="in" />
> +    </method>
> +
>      <!--
>          Imei:
>  
> @@ -145,5 +155,14 @@
>      -->
>      <property name="SubscriptionState" type="u" access="read" />
>  
> +    <!--
> +        EpsUeModeOperation:
> +
> +        A <link linkend="MMModem3gppEpsUeModeOperation">MMModem3gppEpsUeModeOperation</link>
> +        value representing the UE mode of operation for EPS, given as an unsigned integer
> +        (signature <literal>"u"</literal>).
> +    -->
> +    <property name="EpsUeModeOperation" type="u" access="read" />
> +
>    </interface>
>  </node>
> diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c
> index f99e58d8..3a009ad3 100644
> --- a/libmm-glib/mm-common-helpers.c
> +++ b/libmm-glib/mm-common-helpers.c
> @@ -758,6 +758,28 @@ mm_common_build_mode_combinations_default (void)
>      return g_variant_builder_end (&builder);
>  }
>  
> +MMModem3gppEpsUeModeOperation
> +mm_common_get_eps_ue_mode_operation_from_string (const gchar  *str,
> +                                                 GError      **error)
> +{
> +    GEnumClass *enum_class;
> +    guint       i;
> +
> +    enum_class = G_ENUM_CLASS (g_type_class_ref (MM_TYPE_MODEM_3GPP_EPS_UE_MODE_OPERATION));
> +
> +    for (i = 0; enum_class->values[i].value_nick; i++) {
> +        if (!g_ascii_strcasecmp (str, enum_class->values[i].value_nick))
> +            return enum_class->values[i].value;
> +    }
> +
> +    g_set_error (error,
> +                 MM_CORE_ERROR,
> +                 MM_CORE_ERROR_INVALID_ARGS,
> +                 "Couldn't match '%s' with a valid MMModem3gppEpsUeModeOperation value",
> +                 str);
> +    return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN;
> +}
> +
>  GArray *
>  mm_common_oma_pending_network_initiated_sessions_variant_to_garray (GVariant *variant)
>  {
> diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h
> index 772068e9..229186ce 100644
> --- a/libmm-glib/mm-common-helpers.h
> +++ b/libmm-glib/mm-common-helpers.h
> @@ -76,6 +76,9 @@ MMOmaFeature          mm_common_get_oma_features_from_string (const gchar *str,
>  MMOmaSessionType      mm_common_get_oma_session_type_from_string (const gchar *str,
>                                                                    GError **error);
>  
> +MMModem3gppEpsUeModeOperation mm_common_get_eps_ue_mode_operation_from_string (const gchar  *str,
> +                                                                               GError      **error);
> +
>  GArray          *mm_common_ports_variant_to_garray (GVariant *variant);
>  MMModemPortInfo *mm_common_ports_variant_to_array  (GVariant *variant,
>                                                   guint *n_ports);
> diff --git a/libmm-glib/mm-modem-3gpp.c b/libmm-glib/mm-modem-3gpp.c
> index a926acc1..69edc276 100644
> --- a/libmm-glib/mm-modem-3gpp.c
> +++ b/libmm-glib/mm-modem-3gpp.c
> @@ -280,6 +280,22 @@ mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self)
>      return mm_gdbus_modem3gpp_get_enabled_facility_locks (MM_GDBUS_MODEM3GPP (self));
>  }
>  
> +/**
> + * mm_modem_3gpp_get_eps_ue_mode_operation:
> + * @self: A #MMModem3gpp.
> + *
> + * Get the UE mode of operation for EPS.
> + *
> + * Returns: A #MMModem3gppEpsUeModeOperation.
> + */
> +MMModem3gppEpsUeModeOperation
> +mm_modem_3gpp_get_eps_ue_mode_operation (MMModem3gpp *self)
> +{
> +    g_return_val_if_fail (MM_IS_MODEM_3GPP (self), MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN);
> +
> +    return mm_gdbus_modem3gpp_get_eps_ue_mode_operation (MM_GDBUS_MODEM3GPP (self));
> +}
> +
>  /*****************************************************************************/
>  
>  /**
> @@ -590,6 +606,43 @@ mm_modem_3gpp_scan_sync (MMModem3gpp *self,
>  
>  /*****************************************************************************/
>  
> +gboolean
> +mm_modem_3gpp_set_eps_ue_mode_operation_finish (MMModem3gpp   *self,
> +                                                GAsyncResult  *res,
> +                                                GError       **error)
> +{
> +    g_return_val_if_fail (MM_IS_MODEM_3GPP (self), FALSE);
> +
> +    return mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_finish (MM_GDBUS_MODEM3GPP (self), res, error);
> +}
> +
> +void
> +mm_modem_3gpp_set_eps_ue_mode_operation (MMModem3gpp                    *self,
> +                                         MMModem3gppEpsUeModeOperation   mode,
> +                                         GCancellable                   *cancellable,
> +                                         GAsyncReadyCallback             callback,
> +                                         gpointer                        user_data)
> +{
> +    g_return_if_fail (MM_IS_MODEM_3GPP (self));
> +    g_return_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN);
> +
> +    mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation (MM_GDBUS_MODEM3GPP (self), (guint) mode, cancellable, callback, user_data);
> +}
> +
> +gboolean
> +mm_modem_3gpp_set_eps_ue_mode_operation_sync (MMModem3gpp                    *self,
> +                                              MMModem3gppEpsUeModeOperation   mode,
> +                                              GCancellable                   *cancellable,
> +                                              GError                        **error)
> +{
> +    g_return_val_if_fail (MM_IS_MODEM_3GPP (self), FALSE);
> +    g_return_val_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN, FALSE);
> +
> +    return mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_sync (MM_GDBUS_MODEM3GPP (self), (guint) mode, cancellable, error);
> +}
> +
> +/*****************************************************************************/
> +
>  static void
>  mm_modem_3gpp_init (MMModem3gpp *self)
>  {
> diff --git a/libmm-glib/mm-modem-3gpp.h b/libmm-glib/mm-modem-3gpp.h
> index 7cfe0115..a3b37f08 100644
> --- a/libmm-glib/mm-modem-3gpp.h
> +++ b/libmm-glib/mm-modem-3gpp.h
> @@ -80,6 +80,7 @@ MMModem3gppSubscriptionState  mm_modem_3gpp_get_subscription_state     (MMModem3
>  
>  MMModem3gppFacility           mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self);
>  
> +MMModem3gppEpsUeModeOperation mm_modem_3gpp_get_eps_ue_mode_operation  (MMModem3gpp *self);
>  
>  void     mm_modem_3gpp_register        (MMModem3gpp *self,
>                                          const gchar *network_id,
> @@ -120,6 +121,19 @@ GList *mm_modem_3gpp_scan_sync   (MMModem3gpp *self,
>                                    GCancellable *cancellable,
>                                    GError **error);
>  
> +void     mm_modem_3gpp_set_eps_ue_mode_operation        (MMModem3gpp                    *self,
> +                                                         MMModem3gppEpsUeModeOperation   mode,
> +                                                         GCancellable                   *cancellable,
> +                                                         GAsyncReadyCallback             callback,
> +                                                         gpointer                        user_data);
> +gboolean mm_modem_3gpp_set_eps_ue_mode_operation_finish (MMModem3gpp                    *self,
> +                                                         GAsyncResult                   *res,
> +                                                         GError                        **error);
> +gboolean mm_modem_3gpp_set_eps_ue_mode_operation_sync   (MMModem3gpp                    *self,
> +                                                         MMModem3gppEpsUeModeOperation   mode,
> +                                                         GCancellable                   *cancellable,
> +                                                         GError                        **error);
> +
>  G_END_DECLS
>  
>  #endif /* _MM_MODEM_3GPP_H_ */
> diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
> index e1a61ced..7a9f7785 100644
> --- a/src/mm-iface-modem-3gpp.c
> +++ b/src/mm-iface-modem-3gpp.c
> @@ -774,6 +774,141 @@ handle_scan (MmGdbusModem3gpp *skeleton,
>  
>  /*****************************************************************************/
>  
> +typedef struct {
> +    MmGdbusModem3gpp              *skeleton;
> +    GDBusMethodInvocation         *invocation;
> +    MMIfaceModem3gpp              *self;
> +    MMModem3gppEpsUeModeOperation  mode;
> +} HandleSetEpsUeModeOperationContext;
> +
> +static void
> +handle_set_eps_ue_mode_operation_context_free (HandleSetEpsUeModeOperationContext *ctx)
> +{
> +    g_object_unref (ctx->skeleton);
> +    g_object_unref (ctx->invocation);
> +    g_object_unref (ctx->self);
> +    g_slice_free (HandleSetEpsUeModeOperationContext, ctx);
> +}
> +
> +static void
> +after_set_load_eps_ue_mode_operation_ready (MMIfaceModem3gpp                   *self,
> +                                            GAsyncResult                       *res,
> +                                            HandleSetEpsUeModeOperationContext *ctx)
> +{
> +    MMModem3gppEpsUeModeOperation  uemode;
> +    GError                        *error = NULL;
> +
> +    uemode = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish (self, res, &error);
> +    if (error) {
> +        g_dbus_method_invocation_take_error (ctx->invocation, error);
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    if (uemode != ctx->mode) {
> +        g_dbus_method_invocation_return_error_literal (ctx->invocation,
> +                                                       MM_CORE_ERROR,
> +                                                       MM_CORE_ERROR_FAILED,
> +                                                       "UE mode of operation for EPS wasn't updated");
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    mm_gdbus_modem3gpp_set_eps_ue_mode_operation (ctx->skeleton, uemode);
> +    mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
> +    handle_set_eps_ue_mode_operation_context_free (ctx);
> +}
> +
> +static void
> +handle_set_eps_ue_mode_operation_ready (MMIfaceModem3gpp                   *self,
> +                                        GAsyncResult                       *res,
> +                                        HandleSetEpsUeModeOperationContext *ctx)
> +{
> +    GError *error = NULL;
> +
> +    if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation_finish (self, res, &error)) {
> +        g_dbus_method_invocation_take_error (ctx->invocation, error);
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation &&
> +        MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish) {
> +        MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation (
> +            self,
> +            (GAsyncReadyCallback)after_set_load_eps_ue_mode_operation_ready,
> +            ctx);
> +        return;
> +    }
> +
> +    /* Assume we're ok */
> +    mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
> +    handle_set_eps_ue_mode_operation_context_free (ctx);
> +}
> +
> +static void
> +handle_set_eps_ue_mode_operation_auth_ready (MMBaseModem                        *self,
> +                                             GAsyncResult                       *res,
> +                                             HandleSetEpsUeModeOperationContext *ctx)
> +{
> +    GError *error = NULL;
> +
> +    if (!mm_base_modem_authorize_finish (self, res, &error)) {
> +        g_dbus_method_invocation_take_error (ctx->invocation, error);
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    /* Check if we already are in the requested mode */
> +    if (mm_gdbus_modem3gpp_get_eps_ue_mode_operation (ctx->skeleton) == ctx->mode) {
> +        /* Nothing to do */
> +        mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    /* If UE mode update is not implemented, report an error */
> +    if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation ||
> +        !MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation_finish) {
> +        g_dbus_method_invocation_return_error (ctx->invocation,
> +                                               MM_CORE_ERROR,
> +                                               MM_CORE_ERROR_UNSUPPORTED,
> +                                               "Cannot set UE mode of operation for EPS: operation not supported");
> +        handle_set_eps_ue_mode_operation_context_free (ctx);
> +        return;
> +    }
> +
> +    MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation (
> +        MM_IFACE_MODEM_3GPP (self),
> +        ctx->mode,
> +        (GAsyncReadyCallback)handle_set_eps_ue_mode_operation_ready,
> +        ctx);
> +}
> +
> +static gboolean
> +handle_set_eps_ue_mode_operation (MmGdbusModem3gpp      *skeleton,
> +                                  GDBusMethodInvocation *invocation,
> +                                  guint                  mode,
> +                                  MMIfaceModem3gpp      *self)
> +{
> +    HandleSetEpsUeModeOperationContext *ctx;
> +
> +    ctx = g_slice_new (HandleSetEpsUeModeOperationContext);
> +    ctx->skeleton   = g_object_ref (skeleton);
> +    ctx->invocation = g_object_ref (invocation);
> +    ctx->self       = g_object_ref (self);
> +    ctx->mode       = mode;
> +
> +    mm_base_modem_authorize (MM_BASE_MODEM (self),
> +                             invocation,
> +                             MM_AUTHORIZATION_DEVICE_CONTROL,
> +                             (GAsyncReadyCallback)handle_set_eps_ue_mode_operation_auth_ready,
> +                             ctx);
> +    return TRUE;
> +}
> +
> +/*****************************************************************************/
> +
>  gboolean
>  mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
>                                                      GAsyncResult *res,
> @@ -1861,6 +1996,7 @@ typedef enum {
>      INITIALIZATION_STEP_FIRST,
>      INITIALIZATION_STEP_IMEI,
>      INITIALIZATION_STEP_ENABLED_FACILITY_LOCKS,
> +    INITIALIZATION_STEP_EPS_UE_MODE_OPERATION,
>      INITIALIZATION_STEP_LAST
>  } InitializationStep;
>  
> @@ -1892,6 +2028,30 @@ sim_pin_lock_enabled_cb (MMBaseSim *self,
>      mm_gdbus_modem3gpp_set_enabled_facility_locks (skeleton, facilities);
>  }
>  
> +static void
> +load_eps_ue_mode_operation_ready (MMIfaceModem3gpp *self,
> +                                  GAsyncResult     *res,
> +                                  GTask            *task)
> +{
> +    InitializationContext         *ctx;
> +    MMModem3gppEpsUeModeOperation  uemode;
> +    GError                        *error = NULL;
> +
> +    ctx = g_task_get_task_data (task);
> +
> +    uemode = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish (self, res, &error);
> +    mm_gdbus_modem3gpp_set_eps_ue_mode_operation (ctx->skeleton, uemode);
> +
> +    if (error) {
> +        mm_warn ("couldn't load UE mode of operation for EPS: '%s'", error->message);
> +        g_error_free (error);
> +    }
> +
> +    /* Go on to next step */
> +    ctx->step++;
> +    interface_initialization_step (task);
> +}
> +
>  static void
>  load_enabled_facility_locks_ready (MMIfaceModem3gpp *self,
>                                     GAsyncResult *res,
> @@ -2004,6 +2164,18 @@ interface_initialization_step (GTask *task)
>          /* Fall down to next step */
>          ctx->step++;
>  
> +    case INITIALIZATION_STEP_EPS_UE_MODE_OPERATION:
> +        if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation &&
> +            MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish) {
> +            MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation (
> +                self,
> +                (GAsyncReadyCallback)load_eps_ue_mode_operation_ready,
> +                task);
> +            return;
> +        }
> +        /* Fall down to next step */
> +        ctx->step++;
> +
>      case INITIALIZATION_STEP_LAST:
>          /* We are done without errors! */
>  
> @@ -2016,7 +2188,10 @@ interface_initialization_step (GTask *task)
>                            "handle-scan",
>                            G_CALLBACK (handle_scan),
>                            self);
> -
> +        g_signal_connect (ctx->skeleton,
> +                          "handle-set-eps-ue-mode-operation",
> +                          G_CALLBACK (handle_set_eps_ue_mode_operation),
> +                          self);
>  
>          /* Finally, export the new interface */
>          mm_gdbus_object_skeleton_set_modem3gpp (MM_GDBUS_OBJECT_SKELETON (self),
> diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
> index 6237b8aa..7b6d47e1 100644
> --- a/src/mm-iface-modem-3gpp.h
> +++ b/src/mm-iface-modem-3gpp.h
> @@ -68,6 +68,14 @@ struct _MMIfaceModem3gpp {
>                                                                 GAsyncResult *res,
>                                                                 GError **error);
>  
> +    /* Loading of the UE mode of operation for EPS property */
> +    void                          (* load_eps_ue_mode_operation)        (MMIfaceModem3gpp     *self,
> +                                                                         GAsyncReadyCallback   callback,
> +                                                                         gpointer              user_data);
> +    MMModem3gppEpsUeModeOperation (* load_eps_ue_mode_operation_finish) (MMIfaceModem3gpp     *self,
> +                                                                         GAsyncResult         *res,
> +                                                                         GError              **error);
> +
>      /* Asynchronous setting up unsolicited events */
>      void (*setup_unsolicited_events) (MMIfaceModem3gpp *self,
>                                        GAsyncReadyCallback callback,
> @@ -191,6 +199,15 @@ struct _MMIfaceModem3gpp {
>      GList * (*scan_networks_finish) (MMIfaceModem3gpp *self,
>                                       GAsyncResult *res,
>                                       GError **error);
> +
> +    /* Set UE mode of operation for EPS */
> +    void     (* set_eps_ue_mode_operation)        (MMIfaceModem3gpp               *self,
> +                                                   MMModem3gppEpsUeModeOperation   mode,
> +                                                   GAsyncReadyCallback             callback,
> +                                                   gpointer                        user_data);
> +    gboolean (* set_eps_ue_mode_operation_finish) (MMIfaceModem3gpp               *self,
> +                                                   GAsyncResult                   *res,
> +                                                   GError                        **error);
>  };
>  
>  GType mm_iface_modem_3gpp_get_type (void);
> 


-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list