[PATCH v2 4/4] cinterion: use ^SIND unsolicited messages for access tech reporting

Aleksander Morgado aleksander at aleksander.es
Tue Jun 6 13:27:40 UTC 2017


On 30/05/17 20:09, Aleksander Morgado wrote:
> If the modem supports ^SIND psinfo reporting, we enable the URC and
> flag the access technology polling unsupported, so that we only update
> access technology via the +CIEV URCs.
> 
> E.g.:
> 
>     (ttyACM1): --> 'AT^SIND="psinfo",1<CR>'
>     (ttyACM1): <-- '<CR><LF>^SIND: psinfo,1,10<CR><LF><CR><LF>OK<CR><LF>'
>     Reporting initial access technologies...
>     Modem /org/freedesktop/ModemManager1/Modem/0: access technology changed (unknown -> hsdpa, hsupa)
>     ...
>     (ttyACM1): <-- '<CR><LF>+CIEV: psinfo,4<CR><LF>'
>     Modem /org/freedesktop/ModemManager1/Modem/0: access technology changed (hsdpa, hsupa -> edge)
>     ...
> ---

Pushed to git master.

>  plugins/cinterion/mm-broadband-modem-cinterion.c | 470 ++++++++++++++++-------
>  plugins/cinterion/mm-modem-helpers-cinterion.c   |  33 ++
>  plugins/cinterion/mm-modem-helpers-cinterion.h   |   5 +
>  3 files changed, 366 insertions(+), 142 deletions(-)
> 
> diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c
> index 5cdb0107..befd0041 100644
> --- a/plugins/cinterion/mm-broadband-modem-cinterion.c
> +++ b/plugins/cinterion/mm-broadband-modem-cinterion.c
> @@ -61,9 +61,6 @@ typedef enum {
>  } FeatureSupport;
> 
>  struct _MMBroadbandModemCinterionPrivate {
> -    /* Flag to know if we should try AT^SIND or not to get psinfo */
> -    gboolean sind_psinfo;
> -
>      /* Command to go into sleep mode */
>      gchar *sleep_mode_cmd;
> 
> @@ -80,8 +77,12 @@ struct _MMBroadbandModemCinterionPrivate {
>      GArray *cnmi_supported_ds;
>      GArray *cnmi_supported_bfr;
> 
> -    /*Flags for SWWAN support*/
> +    /* +CIEV 'psinfo' indications */
> +    GRegex *ciev_psinfo_regex;
> +
> +    /* Flags for feature support checks */
>      FeatureSupport swwan_support;
> +    FeatureSupport sind_psinfo_support;
>  };
> 
>  /*****************************************************************************/
> @@ -572,185 +573,354 @@ modem_power_off (MMIfaceModem *self,
>  }
> 
>  /*****************************************************************************/
> -/* ACCESS TECHNOLOGIES */
> +/* Access technologies polling */
> 
>  static gboolean
> -load_access_technologies_finish (MMIfaceModem *self,
> -                                 GAsyncResult *res,
> -                                 MMModemAccessTechnology *access_technologies,
> -                                 guint *mask,
> -                                 GError **error)
> +load_access_technologies_finish (MMIfaceModem             *self,
> +                                 GAsyncResult             *res,
> +                                 MMModemAccessTechnology  *access_technologies,
> +                                 guint                    *mask,
> +                                 GError                  **error)
>  {
> -    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
> +    gssize val;
> +
> +    if ((val = g_task_propagate_int (G_TASK (res), error)) < 0)
>          return FALSE;
> 
> -    *access_technologies = (MMModemAccessTechnology) GPOINTER_TO_UINT (
> -        g_simple_async_result_get_op_res_gpointer (
> -            G_SIMPLE_ASYNC_RESULT (res)));
> +    *access_technologies = (MMModemAccessTechnology) val;
>      *mask = MM_MODEM_ACCESS_TECHNOLOGY_ANY;
>      return TRUE;
>  }
> 
>  static void
> -smong_query_ready (MMBroadbandModemCinterion *self,
> +smong_query_ready (MMBaseModem  *self,
>                     GAsyncResult *res,
> -                   GSimpleAsyncResult *operation_result)
> +                   GTask        *task)
>  {
>      const gchar             *response;
>      GError                  *error = NULL;
>      MMModemAccessTechnology  access_tech;
> 
> -    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
> -    if (!response) {
> -        /* Let the error be critical. */
> -        g_simple_async_result_take_error (operation_result, error);
> -    } else if (!mm_cinterion_parse_smong_response (response, &access_tech, &error)) {
> -        /* We'll reset here the flag to try to use SIND/psinfo the next time */
> -        self->priv->sind_psinfo = TRUE;
> -        g_simple_async_result_take_error (operation_result, error);
> -    } else {
> -        /* We'll default to use SMONG then */
> -        self->priv->sind_psinfo = FALSE;
> -        g_simple_async_result_set_op_res_gpointer (operation_result, GUINT_TO_POINTER (access_tech), NULL);
> +    response = mm_base_modem_at_command_finish (self, res, &error);
> +    if (!response || !mm_cinterion_parse_smong_response (response, &access_tech, &error))
> +        g_task_return_error (task, error);
> +    else
> +        g_task_return_int (task, (gssize) access_tech);
> +    g_object_unref (task);
> +}
> +
> +static void
> +load_access_technologies (MMIfaceModem        *_self,
> +                          GAsyncReadyCallback  callback,
> +                          gpointer             user_data)
> +{
> +    MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
> +    GTask                     *task;
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +
> +    /* Abort access technology polling if ^SIND psinfo URCs are enabled */
> +    if (self->priv->sind_psinfo_support == FEATURE_SUPPORTED) {
> +        g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "No need to poll access technologies");
> +        g_object_unref (task);
> +        return;
>      }
> 
> -    g_simple_async_result_complete (operation_result);
> -    g_object_unref (operation_result);
> +    mm_base_modem_at_command (
> +        MM_BASE_MODEM (self),
> +        "^SMONG",
> +        3,
> +        FALSE,
> +        (GAsyncReadyCallback)smong_query_ready,
> +        task);
>  }
> 
> -static MMModemAccessTechnology
> -get_access_technology_from_psinfo (const gchar *psinfo,
> -                                   GError **error)
> -{
> -    guint psinfoval;
> -
> -    if (mm_get_uint_from_str (psinfo, &psinfoval)) {
> -        switch (psinfoval) {
> -        case 0:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> -        case 1:
> -        case 2:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_GPRS;
> -        case 3:
> -        case 4:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_EDGE;
> -        case 5:
> -        case 6:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_UMTS;
> -        case 7:
> -        case 8:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_HSDPA;
> -        case 9:
> -        case 10:
> -            return (MM_MODEM_ACCESS_TECHNOLOGY_HSDPA | MM_MODEM_ACCESS_TECHNOLOGY_HSUPA);
> -        case 16:
> -        case 17:
> -            return MM_MODEM_ACCESS_TECHNOLOGY_LTE;
> -        default:
> -            mm_dbg ("Unable to identify access technology in case:%i", psinfoval);
> -            break;
> -        }
> +/*****************************************************************************/
> +/* Disable unsolicited events (3GPP interface) */
> +
> +static gboolean
> +modem_3gpp_disable_unsolicited_events_finish (MMIfaceModem3gpp  *self,
> +                                              GAsyncResult      *res,
> +                                              GError           **error)
> +{
> +    return g_task_propagate_boolean (G_TASK (res), error);
> +}
> +
> +static void
> +parent_disable_unsolicited_events_ready (MMIfaceModem3gpp *self,
> +                                         GAsyncResult     *res,
> +                                         GTask            *task)
> +{
> +    GError *error = NULL;
> +
> +    if (!iface_modem_3gpp_parent->disable_unsolicited_events_finish (self, res, &error)) {
> +        mm_warn ("Couldn't disable parent 3GPP unsolicited events: %s", error->message);
> +        g_error_free (error);
>      }
> -    else
> -        mm_err ("FAILED get_access_technology_from_psinfo-int");
> 
> -    g_set_error (error,
> -                 MM_CORE_ERROR,
> -                 MM_CORE_ERROR_INVALID_ARGS,
> -                 "Couldn't get network capabilities, "
> -                 "invalid psinfo value: '%s'",
> -                 psinfo);
> -    return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> +    g_task_return_boolean (task, TRUE);
> +    g_object_unref (task);
>  }
> 
>  static void
> -sind_query_ready (MMBroadbandModemCinterion *self,
> -                  GAsyncResult *res,
> -                  GSimpleAsyncResult *operation_result)
> +parent_disable_unsolicited_messages (GTask *task)
> +{
> +    /* Chain up parent's disable */
> +    iface_modem_3gpp_parent->disable_unsolicited_events (
> +        MM_IFACE_MODEM_3GPP (g_task_get_source_object (task)),
> +        (GAsyncReadyCallback)parent_disable_unsolicited_events_ready,
> +        task);
> +}
> +
> +static void
> +sind_psinfo_disable_ready (MMBaseModem  *self,
> +                           GAsyncResult *res,
> +                           GTask        *task)
>  {
> -    const gchar *response;
>      GError *error = NULL;
> -    GMatchInfo *match_info = NULL;
> -    GRegex *regex;
> 
> -    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
> -    if (!response) {
> -        /* Let the error be critical. */
> -        g_simple_async_result_take_error (operation_result, error);
> -        g_simple_async_result_complete (operation_result);
> -        g_object_unref (operation_result);
> +    if (!mm_base_modem_at_command_finish (self, res, &error)) {
> +        mm_warn ("Couldn't disable ^SIND psinfo notifications: %s", error->message);
> +        g_error_free (error);
> +    }
> +
> +    parent_disable_unsolicited_messages (task);
> +}
> +
> +static void
> +modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp    *_self,
> +                                       GAsyncReadyCallback  callback,
> +                                       gpointer             user_data)
> +{
> +    MMBroadbandModemCinterion *self;
> +    GTask                     *task;
> +
> +    self = MM_BROADBAND_MODEM_CINTERION (_self);
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +
> +    if (self->priv->sind_psinfo_support == FEATURE_SUPPORTED) {
> +        /* Disable access technology update reporting */
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),
> +                                  "AT^SIND=\"psinfo\",0",
> +                                  3,
> +                                  FALSE,
> +                                  (GAsyncReadyCallback)sind_psinfo_disable_ready,
> +                                  task);
>          return;
>      }
> 
> -    /* The AT^SIND? command replies a list of several different indicators.
> -     * We will only look for 'psinfo' which is the one which may tell us
> -     * the available network access technology. Note that only 3G-enabled
> -     * devices seem to have this indicator.
> -     *
> -     * AT+SIND?
> -     * ^SIND: battchg,1,1
> -     * ^SIND: signal,1,99
> -     * ...
> -     */
> -    regex = g_regex_new ("\\r\\n\\^SIND:\\s*psinfo,\\s*(\\d*),\\s*(\\d*)", 0, 0, NULL);
> -    if (g_regex_match_full (regex, response, strlen (response), 0, 0, &match_info, NULL)) {
> -        MMModemAccessTechnology act;
> -        gchar *ind_value;
> -
> -        ind_value = g_match_info_fetch (match_info, 2);
> -        act = get_access_technology_from_psinfo (ind_value, &error);
> -        g_free (ind_value);
> -        g_simple_async_result_set_op_res_gpointer (operation_result, GUINT_TO_POINTER (act), NULL);
> -        g_simple_async_result_complete (operation_result);
> -        g_object_unref (operation_result);
> +    parent_disable_unsolicited_messages (task);
> +}
> +
> +/*****************************************************************************/
> +/* Enable unsolicited events (3GPP interface) */
> +
> +static gboolean
> +modem_3gpp_enable_unsolicited_events_finish (MMIfaceModem3gpp  *self,
> +                                             GAsyncResult      *res,
> +                                             GError           **error)
> +{
> +    return g_task_propagate_boolean (G_TASK (res), error);
> +}
> +
> +static void
> +sind_psinfo_enable_ready (MMBaseModem  *_self,
> +                          GAsyncResult *res,
> +                          GTask        *task)
> +{
> +    MMBroadbandModemCinterion *self;
> +    GError                    *error = NULL;
> +    const gchar               *response;
> +    guint                      mode;
> +    guint                      val;
> +
> +    self = MM_BROADBAND_MODEM_CINTERION (_self);
> +    if (!(response = mm_base_modem_at_command_finish (_self, res, &error))) {
> +        self->priv->sind_psinfo_support = FEATURE_NOT_SUPPORTED;
> +        mm_warn ("Couldn't enable ^SIND psinfo notifications: %s", error->message);
> +        g_error_free (error);
> +    } else if (!mm_cinterion_parse_sind_response (response, NULL, &mode, &val, &error)) {
> +        self->priv->sind_psinfo_support = FEATURE_NOT_SUPPORTED;
> +        mm_warn ("Couldn't parse ^SIND psinfo response: %s", error->message);
> +        g_error_free (error);
>      } else {
> -        /* If there was no 'psinfo' indicator, we'll try AT^SMONG and read the cell
> -         * info table. */
> -        mm_base_modem_at_command (
> -            MM_BASE_MODEM (self),
> -            "^SMONG",
> -            3,
> -            FALSE,
> -            (GAsyncReadyCallback)smong_query_ready,
> -            operation_result);
> +        /* Flag ^SIND psinfo supported so that we don't poll */
> +        self->priv->sind_psinfo_support = FEATURE_SUPPORTED;
> +
> +        /* Report initial access technology gathered right away */
> +        mm_dbg ("Reporting initial access technologies...");
> +        mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self),
> +                                                   mm_cinterion_get_access_technology_from_sind_psinfo (val),
> +                                                   MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK);
>      }
> 
> -    g_match_info_free (match_info);
> -    g_regex_unref (regex);
> +    g_task_return_boolean (task, TRUE);
> +    g_object_unref (task);
>  }
> 
>  static void
> -load_access_technologies (MMIfaceModem *self,
> -                          GAsyncReadyCallback callback,
> -                          gpointer user_data)
> +parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *_self,
> +                                        GAsyncResult     *res,
> +                                        GTask            *task)
>  {
> -    MMBroadbandModemCinterion *broadband = MM_BROADBAND_MODEM_CINTERION (self);
> -    GSimpleAsyncResult *result;
> +    MMBroadbandModemCinterion *self;
> +    GError                    *error = NULL;
> 
> -    result = g_simple_async_result_new (G_OBJECT (self),
> -                                        callback,
> -                                        user_data,
> -                                        load_access_technologies);
> +    self = MM_BROADBAND_MODEM_CINTERION (_self);
> 
> -    if (broadband->priv->sind_psinfo) {
> -        /* TODO: Trigger off psinfo URC instead of this polling. */
> -        mm_base_modem_at_command (
> -            MM_BASE_MODEM (self),
> -            "^SIND?",
> -            3,
> -            FALSE,
> -            (GAsyncReadyCallback)sind_query_ready,
> -            result);
> +    if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (_self, res, &error)) {
> +        mm_warn ("Couldn't enable parent 3GPP unsolicited events: %s", error->message);
> +        g_error_free (error);
> +    }
> +
> +    if (self->priv->sind_psinfo_support != FEATURE_NOT_SUPPORTED) {
> +        /* Enable access technology update reporting */
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),
> +                                  "AT^SIND=\"psinfo\",1",
> +                                  3,
> +                                  FALSE,
> +                                  (GAsyncReadyCallback)sind_psinfo_enable_ready,
> +                                  task);
>          return;
>      }
> 
> -    mm_base_modem_at_command (
> -        MM_BASE_MODEM (self),
> -        "^SMONG",
> -        3,
> -        FALSE,
> -        (GAsyncReadyCallback)smong_query_ready,
> -        result);
> +    g_task_return_boolean (task, TRUE);
> +    g_object_unref (task);
> +}
> +
> +static void
> +modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp    *self,
> +                                      GAsyncReadyCallback  callback,
> +                                      gpointer             user_data)
> +{
> +    GTask *task;
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +
> +    /* Chain up parent's enable */
> +    iface_modem_3gpp_parent->enable_unsolicited_events (
> +        self,
> +        (GAsyncReadyCallback)parent_enable_unsolicited_events_ready,
> +        task);
> +}
> +
> +/*****************************************************************************/
> +/* Setup/Cleanup unsolicited events (3GPP interface) */
> +
> +static void
> +sind_psinfo_received (MMPortSerialAt            *port,
> +                      GMatchInfo                *match_info,
> +                      MMBroadbandModemCinterion *self)
> +{
> +    guint val;
> +
> +    if (!mm_get_uint_from_match_info (match_info, 1, &val)) {
> +        mm_dbg ("Failed to convert psinfo value");
> +        return;
> +    }
> +
> +    mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self),
> +                                               mm_cinterion_get_access_technology_from_sind_psinfo (val),
> +                                               MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK);
> +}
> +
> +static void
> +set_unsolicited_events_handlers (MMBroadbandModemCinterion *self,
> +                                 gboolean                   enable)
> +{
> +    MMPortSerialAt *ports[2];
> +    guint           i;
> +
> +    ports[0] = mm_base_modem_peek_port_primary   (MM_BASE_MODEM (self));
> +    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
> +
> +    /* Enable unsolicited events in given port */
> +    for (i = 0; i < G_N_ELEMENTS (ports); i++) {
> +        if (!ports[i])
> +            continue;
> +
> +        mm_port_serial_at_add_unsolicited_msg_handler (
> +            ports[i],
> +            self->priv->ciev_psinfo_regex,
> +            enable ? (MMPortSerialAtUnsolicitedMsgFn)sind_psinfo_received : NULL,
> +            enable ? self : NULL,
> +            NULL);
> +    }
> +}
> +
> +static gboolean
> +modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp  *self,
> +                                                    GAsyncResult      *res,
> +                                                    GError           **error)
> +{
> +    return g_task_propagate_boolean (G_TASK (res), error);
> +}
> +
> +static void
> +parent_setup_unsolicited_events_ready (MMIfaceModem3gpp *self,
> +                                       GAsyncResult     *res,
> +                                       GTask            *task)
> +{
> +    GError *error = NULL;
> +
> +    if (!iface_modem_3gpp_parent->setup_unsolicited_events_finish (self, res, &error))
> +        g_task_return_error (task, error);
> +    else {
> +        /* Our own setup now */
> +        set_unsolicited_events_handlers (MM_BROADBAND_MODEM_CINTERION (self), TRUE);
> +        g_task_return_boolean (task, TRUE);
> +    }
> +    g_object_unref (task);
> +}
> +
> +static void
> +modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp    *self,
> +                                     GAsyncReadyCallback  callback,
> +                                     gpointer             user_data)
> +{
> +    GTask *task;
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +
> +    /* Chain up parent's setup */
> +    iface_modem_3gpp_parent->setup_unsolicited_events (
> +        self,
> +        (GAsyncReadyCallback)parent_setup_unsolicited_events_ready,
> +        task);
> +}
> +
> +static void
> +parent_cleanup_unsolicited_events_ready (MMIfaceModem3gpp *self,
> +                                         GAsyncResult     *res,
> +                                         GTask            *task)
> +{
> +    GError *error = NULL;
> +
> +    if (!iface_modem_3gpp_parent->cleanup_unsolicited_events_finish (self, res, &error))
> +        g_task_return_error (task, error);
> +    else
> +        g_task_return_boolean (task, TRUE);
> +    g_object_unref (task);
> +}
> +
> +static void
> +modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp    *self,
> +                                       GAsyncReadyCallback  callback,
> +                                       gpointer             user_data)
> +{
> +    GTask *task;
> +
> +    task = g_task_new (self, NULL, callback, user_data);
> +
> +    /* Our own cleanup first */
> +    set_unsolicited_events_handlers (MM_BROADBAND_MODEM_CINTERION (self), FALSE);
> +
> +    /* And now chain up parent's cleanup */
> +    iface_modem_3gpp_parent->cleanup_unsolicited_events (
> +        self,
> +        (GAsyncReadyCallback)parent_cleanup_unsolicited_events_ready,
> +        task);
>  }
> 
>  /*****************************************************************************/
> @@ -1735,8 +1905,11 @@ mm_broadband_modem_cinterion_init (MMBroadbandModemCinterion *self)
>                                                MMBroadbandModemCinterionPrivate);
> 
>      /* Initialize private variables */
> -    self->priv->sind_psinfo = TRUE; /* Initially, always try to get psinfo */
> -    self->priv->swwan_support = FEATURE_SUPPORT_UNKNOWN;
> +    self->priv->sind_psinfo_support = FEATURE_SUPPORT_UNKNOWN;
> +    self->priv->swwan_support       = FEATURE_SUPPORT_UNKNOWN;
> +
> +    self->priv->ciev_psinfo_regex = g_regex_new ("\\r\\n\\+CIEV: psinfo,(\\d+)\\r\\n",
> +                                                 G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
>  }
> 
>  static void
> @@ -1758,6 +1931,8 @@ finalize (GObject *object)
>      if (self->priv->cnmi_supported_bfr)
>          g_array_unref (self->priv->cnmi_supported_bfr);
> 
> +    g_regex_unref (self->priv->ciev_psinfo_regex);
> +
>      G_OBJECT_CLASS (mm_broadband_modem_cinterion_parent_class)->finalize (object);
>  }
> 
> @@ -1796,6 +1971,17 @@ static void
>  iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
>  {
>      iface_modem_3gpp_parent = g_type_interface_peek_parent (iface);
> +
> +    iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events;
> +    iface->enable_unsolicited_events_finish = modem_3gpp_enable_unsolicited_events_finish;
> +    iface->disable_unsolicited_events = modem_3gpp_disable_unsolicited_events;
> +    iface->disable_unsolicited_events_finish = modem_3gpp_disable_unsolicited_events_finish;
> +
> +    iface->setup_unsolicited_events = modem_3gpp_setup_unsolicited_events;
> +    iface->setup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
> +    iface->cleanup_unsolicited_events = modem_3gpp_cleanup_unsolicited_events;
> +    iface->cleanup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
> +
>      iface->register_in_network = register_in_network;
>      iface->register_in_network_finish = register_in_network_finish;
>  }
> diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
> index da1e7787..3c7a0a0c 100644
> --- a/plugins/cinterion/mm-modem-helpers-cinterion.c
> +++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
> @@ -624,3 +624,36 @@ mm_cinterion_parse_smong_response (const gchar              *response,
>      g_assert (access_tech != MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
>      return TRUE;
>  }
> +
> +/*****************************************************************************/
> +/* ^SIND psinfo helper */
> +
> +MMModemAccessTechnology
> +mm_cinterion_get_access_technology_from_sind_psinfo (guint val)
> +{
> +    switch (val) {
> +    case 0:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> +    case 1:
> +    case 2:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_GPRS;
> +    case 3:
> +    case 4:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_EDGE;
> +    case 5:
> +    case 6:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_UMTS;
> +    case 7:
> +    case 8:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_HSDPA;
> +    case 9:
> +    case 10:
> +        return (MM_MODEM_ACCESS_TECHNOLOGY_HSDPA | MM_MODEM_ACCESS_TECHNOLOGY_HSUPA);
> +    case 16:
> +    case 17:
> +        return MM_MODEM_ACCESS_TECHNOLOGY_LTE;
> +    default:
> +        mm_dbg ("Unable to identify access technology from psinfo reported value: %u", val);
> +        return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
> +    }
> +}
> diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h
> index bcf02f9d..2ec05157 100644
> --- a/plugins/cinterion/mm-modem-helpers-cinterion.h
> +++ b/plugins/cinterion/mm-modem-helpers-cinterion.h
> @@ -82,4 +82,9 @@ gboolean mm_cinterion_parse_smong_response (const gchar              *response,
>                                              MMModemAccessTechnology  *access_tech,
>                                              GError                  **error);
> 
> +/*****************************************************************************/
> +/* ^SIND psinfo helper */
> +
> +MMModemAccessTechnology mm_cinterion_get_access_technology_from_sind_psinfo (guint val);
> +
>  #endif  /* MM_MODEM_HELPERS_CINTERION_H */
> --
> 2.13.0
> 


-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list