[PATCH 2/2] broadband-modem: implement support for the +CEMODE command
Aleksander Morgado
aleksander at aleksander.es
Sat Jan 20 14:43:57 UTC 2018
On 28/12/17 18:41, Aleksander Morgado wrote:
> The +CEMODE command is defined in 3GPP TS 27.007 (e.g. in section
> 10.1.28 in v11.0.0). This command allows querying or updating the
> current UE mode, as well as checking the supported modes.
>
> We implement support for loading the current mode and updating it. It
> is assumed that the device does any additional operation needed by the
> setting update, e.g. un-registering from CS when selecting an EPS-only
> mode.
Pushed to git master.
> ---
> src/mm-broadband-modem.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
> src/mm-modem-helpers.c | 45 +++++++++++++++++++++++++++++++++
> src/mm-modem-helpers.h | 6 +++++
> 3 files changed, 117 insertions(+)
>
> diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
> index f82122b1..1e3bae69 100644
> --- a/src/mm-broadband-modem.c
> +++ b/src/mm-broadband-modem.c
> @@ -3821,6 +3821,68 @@ modem_3gpp_load_subscription_state (MMIfaceModem3gpp *self,
> g_object_unref (task);
> }
>
> +/*****************************************************************************/
> +/* UE mode of operation for EPS loading (3GPP interface) */
> +
> +static MMModem3gppEpsUeModeOperation
> +modem_3gpp_load_eps_ue_mode_operation_finish (MMIfaceModem3gpp *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + MMModem3gppEpsUeModeOperation mode;
> + const gchar *result;
> +
> + result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
> + if (!result || !mm_3gpp_parse_cemode_query_response (result, &mode, error))
> + return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN;
> +
> + return mode;
> +}
> +
> +static void
> +modem_3gpp_load_eps_ue_mode_operation (MMIfaceModem3gpp *self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + mm_dbg ("loading UE mode of operation for EPS...");
> + mm_base_modem_at_command (MM_BASE_MODEM (self),
> + "+CEMODE?",
> + 3,
> + FALSE,
> + callback,
> + user_data);
> +}
> +
> +/*****************************************************************************/
> +/* UE mode of operation for EPS settin (3GPP interface) */
> +
> +static gboolean
> +modem_3gpp_set_eps_ue_mode_operation_finish (MMIfaceModem3gpp *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
> +}
> +
> +static void
> +modem_3gpp_set_eps_ue_mode_operation (MMIfaceModem3gpp *self,
> + MMModem3gppEpsUeModeOperation mode,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + gchar *cmd;
> +
> + mm_dbg ("updating UE mode of operation for EPS...");
> + cmd = mm_3gpp_build_cemode_set_request (mode);
> + mm_base_modem_at_command (MM_BASE_MODEM (self),
> + cmd,
> + 3,
> + FALSE,
> + callback,
> + user_data);
> + g_free (cmd);
> +}
> +
> /*****************************************************************************/
> /* Unsolicited registration messages handling (3GPP interface) */
>
> @@ -10922,6 +10984,8 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
> iface->load_imei_finish = modem_3gpp_load_imei_finish;
> iface->load_enabled_facility_locks = modem_3gpp_load_enabled_facility_locks;
> iface->load_enabled_facility_locks_finish = modem_3gpp_load_enabled_facility_locks_finish;
> + iface->load_eps_ue_mode_operation = modem_3gpp_load_eps_ue_mode_operation;
> + iface->load_eps_ue_mode_operation_finish = modem_3gpp_load_eps_ue_mode_operation_finish;
>
> /* Enabling steps */
> iface->setup_unsolicited_events = modem_3gpp_setup_unsolicited_events;
> @@ -10956,6 +11020,8 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
> iface->register_in_network_finish = modem_3gpp_register_in_network_finish;
> iface->scan_networks = modem_3gpp_scan_networks;
> iface->scan_networks_finish = modem_3gpp_scan_networks_finish;
> + iface->set_eps_ue_mode_operation = modem_3gpp_set_eps_ue_mode_operation;
> + iface->set_eps_ue_mode_operation_finish = modem_3gpp_set_eps_ue_mode_operation_finish;
> }
>
> static void
> diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
> index b2806dfa..9ba8c750 100644
> --- a/src/mm-modem-helpers.c
> +++ b/src/mm-modem-helpers.c
> @@ -2485,6 +2485,51 @@ mm_3gpp_parse_cfun_query_generic_response (const gchar *response,
> }
> }
>
> +static MMModem3gppEpsUeModeOperation cemode_values[] = {
> + [0] = MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2,
> + [1] = MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1,
> + [2] = MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2,
> + [3] = MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1,
> +};
> +
> +gchar *
> +mm_3gpp_build_cemode_set_request (MMModem3gppEpsUeModeOperation mode)
> +{
> + guint i;
> +
> + g_return_val_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN, NULL);
> +
> + for (i = 0; i < G_N_ELEMENTS (cemode_values); i++) {
> + if (mode == cemode_values[i])
> + return g_strdup_printf ("+CEMODE=%u", i);
> + }
> +
> + g_assert_not_reached ();
> + return NULL;
> +}
> +
> +gboolean
> +mm_3gpp_parse_cemode_query_response (const gchar *response,
> + MMModem3gppEpsUeModeOperation *out_mode,
> + GError **error)
> +{
> + guint value = 0;
> +
> + response = mm_strip_tag (response, "+CEMODE:");
> + if (mm_get_uint_from_str (response, &value) && value < G_N_ELEMENTS (cemode_values)) {
> + if (out_mode)
> + *out_mode = cemode_values[value];
> + return TRUE;
> + }
> +
> + g_set_error (error,
> + MM_CORE_ERROR,
> + MM_CORE_ERROR_FAILED,
> + "Couldn't parse UE mode of operation: '%s' (value %u)",
> + response, value);
> + return FALSE;
> +}
> +
> /*************************************************************************/
>
> static MMSmsStorage
> diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
> index 524f05ae..d14eb17b 100644
> --- a/src/mm-modem-helpers.h
> +++ b/src/mm-modem-helpers.h
> @@ -328,6 +328,12 @@ gboolean mm_3gpp_cesq_response_to_signal_info (const gchar *response,
> MMSignal **out_lte,
> GError **error);
>
> +/* CEMODE? response parser */
> +gchar *mm_3gpp_build_cemode_set_request (MMModem3gppEpsUeModeOperation mode);
> +gboolean mm_3gpp_parse_cemode_query_response (const gchar *response,
> + MMModem3gppEpsUeModeOperation *out_mode,
> + GError **error);
> +
> /* Additional 3GPP-specific helpers */
>
> MMModem3gppFacility mm_3gpp_acronym_to_facility (const gchar *str);
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list