[PATCH] cinterion: support changing modes in LTE capable devices
Aleksander Morgado
aleksander at aleksander.es
Mon May 29 12:47:13 UTC 2017
On 21/05/17 21:51, Aleksander Morgado wrote:
> ---
>
> Hey,
>
> This patch implements some basic support for changing allowed modes for LTE capable Cinterion devices.
>
> Comments?
>
I rebased this patch on top of git master and merged it.
> ---
> plugins/cinterion/mm-broadband-modem-cinterion.c | 162 +++++++++++------------
> 1 file changed, 77 insertions(+), 85 deletions(-)
>
> diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c
> index f59e3d0e..1ffc3bf3 100644
> --- a/plugins/cinterion/mm-broadband-modem-cinterion.c
> +++ b/plugins/cinterion/mm-broadband-modem-cinterion.c
> @@ -972,20 +972,17 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
> /* Load supported modes (Modem interface) */
>
> static GArray *
> -load_supported_modes_finish (MMIfaceModem *self,
> - GAsyncResult *res,
> - GError **error)
> +load_supported_modes_finish (MMIfaceModem *self,
> + GAsyncResult *res,
> + GError **error)
> {
> - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
> - return NULL;
> -
> - return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
> + return g_task_propagate_pointer (G_TASK (res), error);
> }
>
> static void
> parent_load_supported_modes_ready (MMIfaceModem *self,
> GAsyncResult *res,
> - GSimpleAsyncResult *simple)
> + GTask *task)
> {
> GError *error = NULL;
> GArray *all;
> @@ -995,9 +992,8 @@ parent_load_supported_modes_ready (MMIfaceModem *self,
>
> all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
> if (!all) {
> - g_simple_async_result_take_error (simple, error);
> - g_simple_async_result_complete (simple);
> - g_object_unref (simple);
> + g_task_return_error (task, error);
> + g_object_unref (task);
> return;
> }
>
> @@ -1012,19 +1008,30 @@ parent_load_supported_modes_ready (MMIfaceModem *self,
> mode.allowed = MM_MODEM_MODE_3G;
> mode.preferred = MM_MODEM_MODE_NONE;
> g_array_append_val (combinations, mode);
> - /* 2G and 3G */
> - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
> - mode.preferred = MM_MODEM_MODE_NONE;
> - g_array_append_val (combinations, mode);
> +
> + if (mm_iface_modem_is_4g (self)) {
> + /* 4G only */
> + mode.allowed = MM_MODEM_MODE_4G;
> + mode.preferred = MM_MODEM_MODE_NONE;
> + g_array_append_val (combinations, mode);
> + /* 2G, 3G and 4G */
> + mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
> + mode.preferred = MM_MODEM_MODE_NONE;
> + g_array_append_val (combinations, mode);
> + } else {
> + /* 2G and 3G */
> + mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
> + mode.preferred = MM_MODEM_MODE_NONE;
> + g_array_append_val (combinations, mode);
> + }
>
> /* Filter out those unsupported modes */
> filtered = mm_filter_supported_modes (all, combinations);
> g_array_unref (all);
> g_array_unref (combinations);
>
> - g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
> - g_simple_async_result_complete (simple);
> - g_object_unref (simple);
> + g_task_return_pointer (task, filtered, (GDestroyNotify) g_array_unref);
> + g_object_unref (task);
> }
>
> static void
> @@ -1036,102 +1043,87 @@ load_supported_modes (MMIfaceModem *self,
> iface_modem_parent->load_supported_modes (
> MM_IFACE_MODEM (self),
> (GAsyncReadyCallback)parent_load_supported_modes_ready,
> - g_simple_async_result_new (G_OBJECT (self),
> - callback,
> - user_data,
> - load_supported_modes));
> + g_task_new (self, NULL, callback, user_data));
> }
>
> /*****************************************************************************/
> /* Set current modes (Modem interface) */
>
> static gboolean
> -set_current_modes_finish (MMIfaceModem *self,
> - GAsyncResult *res,
> - GError **error)
> +set_current_modes_finish (MMIfaceModem *self,
> + GAsyncResult *res,
> + GError **error)
> {
> - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
> + return g_task_propagate_boolean (G_TASK (res), error);
> }
>
> static void
> allowed_access_technology_update_ready (MMBroadbandModemCinterion *self,
> - GAsyncResult *res,
> - GSimpleAsyncResult *operation_result)
> + GAsyncResult *res,
> + GTask *task)
> {
> GError *error = NULL;
>
> mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
> if (error)
> - /* Let the error be critical. */
> - g_simple_async_result_take_error (operation_result, error);
> + g_task_return_error (task, error);
> else
> - g_simple_async_result_set_op_res_gboolean (operation_result, TRUE);
> - g_simple_async_result_complete (operation_result);
> - g_object_unref (operation_result);
> + g_task_return_boolean (task, TRUE);
> + g_object_unref (task);
> }
>
> static void
> -set_current_modes (MMIfaceModem *_self,
> - MMModemMode allowed,
> - MMModemMode preferred,
> - GAsyncReadyCallback callback,
> - gpointer user_data)
> +set_current_modes (MMIfaceModem *_self,
> + MMModemMode allowed,
> + MMModemMode preferred,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> {
> - GSimpleAsyncResult *result;
> MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
> + gchar *command;
> + GTask *task;
>
> g_assert (preferred == MM_MODEM_MODE_NONE);
>
> - result = g_simple_async_result_new (G_OBJECT (self),
> - callback,
> - user_data,
> - set_current_modes);
> -
> - /* For dual 2G/3G devices... */
> - if (mm_iface_modem_is_2g (_self) &&
> - mm_iface_modem_is_3g (_self)) {
> - gchar *command;
> -
> - /* We will try to simulate the possible allowed modes here. The
> - * Cinterion devices do not seem to allow setting preferred access
> - * technology in 3G devices, but they allow restricting to a given
> - * one:
> - * - 2G-only is forced by forcing GERAN RAT (AcT=0)
> - * - 3G-only is forced by forcing UTRAN RAT (AcT=2)
> - * - for the remaining ones, we default to automatic selection of RAT,
> - * which is based on the quality of the connection.
> - */
> + task = g_task_new (self, NULL, callback, user_data);
>
> - if (allowed == MM_MODEM_MODE_3G)
> - command = g_strdup ("+COPS=,,,2");
> - else if (allowed == MM_MODEM_MODE_2G)
> - command = g_strdup ("+COPS=,,,0");
> - else if (allowed == (MM_MODEM_MODE_3G | MM_MODEM_MODE_2G)) {
> - /* no AcT given, defaults to Auto. For this case, we cannot provide
> - * AT+COPS=,,, (i.e. just without a last value). Instead, we need to
> - * re-run the last manual/automatic selection command which succeeded,
> - * (or auto by default if none was launched) */
> - if (self->priv->manual_operator_id)
> - command = g_strdup_printf ("+COPS=1,2,\"%s\"", self->priv->manual_operator_id);
> - else
> - command = g_strdup ("+COPS=0");
> - } else
> - g_assert_not_reached ();
> + /* We will try to simulate the possible allowed modes here. The
> + * Cinterion devices do not seem to allow setting preferred access
> + * technology in devices, but they allow restricting to a given
> + * one:
> + * - 2G-only is forced by forcing GERAN RAT (AcT=0)
> + * - 3G-only is forced by forcing UTRAN RAT (AcT=2)
> + * - 4G-only is forced by forcing E-UTRAN RAT (AcT=7)
> + * - for the remaining ones, we default to automatic selection of RAT,
> + * which is based on the quality of the connection.
> + */
>
> - mm_base_modem_at_command (
> - MM_BASE_MODEM (self),
> - command,
> - 20,
> - FALSE,
> - (GAsyncReadyCallback)allowed_access_technology_update_ready,
> - result);
> - g_free (command);
> - return;
> + if (mm_iface_modem_is_4g (_self) && allowed == MM_MODEM_MODE_4G)
> + command = g_strdup ("+COPS=,,,7");
> + else if (mm_iface_modem_is_3g (_self) && allowed == MM_MODEM_MODE_3G)
> + command = g_strdup ("+COPS=,,,2");
> + else if (mm_iface_modem_is_2g (_self) && allowed == MM_MODEM_MODE_2G)
> + command = g_strdup ("+COPS=,,,0");
> + else {
> + /* For any other combination (e.g. ANY or no AcT given, defaults to Auto. For this case, we cannot provide
> + * AT+COPS=,,, (i.e. just without a last value). Instead, we need to
> + * re-run the last manual/automatic selection command which succeeded,
> + * (or auto by default if none was launched) */
> + if (self->priv->manual_operator_id)
> + command = g_strdup_printf ("+COPS=1,2,\"%s\"", self->priv->manual_operator_id);
> + else
> + command = g_strdup ("+COPS=0");
> }
>
> - /* For 2G-only and 3G-only devices, we already stated that we don't
> - * support mode switching. */
> - g_assert_not_reached ();
> + mm_base_modem_at_command (
> + MM_BASE_MODEM (self),
> + command,
> + 20,
> + FALSE,
> + (GAsyncReadyCallback)allowed_access_technology_update_ready,
> + task);
> +
> + g_free (command);
> }
>
> /*****************************************************************************/
> --
> 2.12.2
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list