diff options
Diffstat (limited to 'plugins/icera/mm-broadband-modem-icera.c')
-rw-r--r-- | plugins/icera/mm-broadband-modem-icera.c | 191 |
1 files changed, 132 insertions, 59 deletions
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c index 84e998b..b84cd12 100644 --- a/plugins/icera/mm-broadband-modem-icera.c +++ b/plugins/icera/mm-broadband-modem-icera.c @@ -70,68 +70,143 @@ struct _MMBroadbandModemIceraPrivate { /*****************************************************************************/ /* Load supported modes (Modem interface) */ +static void +add_supported_mode (GArray **combinations, + guint mode) +{ + MMModemModeCombination combination; + + switch (mode) { + case 0: + mm_dbg ("Modem supports 2G-only mode"); + combination.allowed = MM_MODEM_MODE_2G; + combination.preferred = MM_MODEM_MODE_NONE; + break; + case 1: + mm_dbg ("Modem supports 3G-only mode"); + combination.allowed = MM_MODEM_MODE_3G; + combination.preferred = MM_MODEM_MODE_NONE; + break; + case 2: + mm_dbg ("Modem supports 2G/3G mode with 2G preferred"); + combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); + combination.preferred = MM_MODEM_MODE_2G; + break; + case 3: + mm_dbg ("Modem supports 2G/3G mode with 3G preferred"); + combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); + combination.preferred = MM_MODEM_MODE_3G; + break; + case 5: + mm_dbg ("Modem supports 'any', but not explicitly listing it"); + /* Any, no need to add it to the list */ + return; + default: + mm_warn ("Unsupported Icera mode found: %u", mode); + return; + } + + if (*combinations == NULL) + *combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5); + + g_array_append_val (*combinations, combination); +} + static GArray * load_supported_modes_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) { - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + GArray *combinations = NULL; + const gchar *response; + gchar **split = NULL; + GMatchInfo *match_info; + GRegex *r; + guint i; + + response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); + if (!response) return NULL; - return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); -} + /* Reply goes like this: + * AT%IPSYS=? + * %IPSYS: (0-3,5),(0-3) + */ -static void -parent_load_supported_modes_ready (MMIfaceModem *self, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - GError *error = NULL; - GArray *all; - GArray *combinations; - GArray *filtered; - MMModemModeCombination mode; + r = g_regex_new ("\\%IPSYS:\\s*\\((.*)\\)\\s*,\\((.*)\\)", + G_REGEX_RAW, 0, NULL); + g_assert (r != NULL); - 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); - return; + g_regex_match (r, response, 0, &match_info); + if (g_match_info_matches (match_info)) { + gchar *aux; + + aux = mm_get_string_unquoted_from_match_info (match_info, 1); + if (aux) { + split = g_strsplit (aux, ",", -1); + g_free (aux); + } } - /* Build list of combinations */ - combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5); - - /* 2G only */ - mode.allowed = MM_MODEM_MODE_2G; - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 3G only */ - 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); - /* 2G and 3G, 2G preferred */ - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); - mode.preferred = MM_MODEM_MODE_2G; - g_array_append_val (combinations, mode); - /* 2G and 3G, 3G preferred */ - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); - mode.preferred = MM_MODEM_MODE_3G; - 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_match_info_free (match_info); + g_regex_unref (r); + + if (!split) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "%%IPSYS=? response didn't match"); + g_regex_unref (r); + return NULL; + } + + for (i = 0; split[i]; i++) { + gchar *interval_separator; + + g_strstrip (split[i]); + interval_separator = strstr (split[i], "-"); + if (interval_separator) { + /* Add all in interval */ + gchar *first, *last; + guint modefirst, modelast; + + first = g_strdup (split[i]); + interval_separator = strstr (first, "-"); + *(interval_separator++) = '\0'; + last = interval_separator; + + if (mm_get_uint_from_str (first, &modefirst) && + mm_get_uint_from_str (last, &modelast) && + modefirst < modelast && + modelast <= 5) { + guint j; + + for (j = modefirst; j <= modelast; j++) + add_supported_mode (&combinations, j); + } else + mm_warn ("Couldn't parse mode interval (%s) in %%IPSYS=? response", split[i]); + g_free (first); + } else { + guint mode; + + /* Add single */ + if (mm_get_uint_from_str (split[i], &mode)) + add_supported_mode (&combinations, mode); + else + mm_warn ("Couldn't parse mode (%s) in %%IPSYS=? response", split[i]); + } + } + + g_strfreev (split); + + if (!combinations) + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "No mode combinations were parsed from the %%IPSYS=? response (%s)", + response); + + return combinations; } static void @@ -139,14 +214,12 @@ load_supported_modes (MMIfaceModem *self, GAsyncReadyCallback callback, gpointer user_data) { - /* Run parent's loading */ - 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)); + mm_base_modem_at_command (MM_BASE_MODEM (self), + "%IPSYS=?", + 3, + TRUE, + callback, + user_data); } /*****************************************************************************/ |