aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-05-29 12:41:49 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-06-05 19:15:14 +0200
commit45ceba76924f184ed9e12ba3d35e00a55ad3a197 (patch)
treec413d3e29a64eb86340e964ec48e67d8a66c6f76 /plugins
parent212d00c529ee07131bf3b71a8759dca49292c059 (diff)
api,introspection: 'SupportedModes' is now a list of possible combinations
Instead of just a mask of MMModemMode values, we now provide a list of the allowed and preferred mode combinations supported by the modem. E.g.: $> sudo mmcli -m 0 ------------------------- Modes | supported: 'allowed: 2g; preferred: none | allowed: 3g; preferred: none | allowed: 2g, 3g; preferred: none | allowed: 2g, 3g; preferred: 2g | allowed: 2g, 3g; preferred: 3g | allowed: 4g; preferred: none | allowed: 2g, 3g, 4g; preferred: none'
Diffstat (limited to 'plugins')
-rw-r--r--plugins/cinterion/mm-broadband-modem-cinterion.c82
-rw-r--r--plugins/huawei/mm-broadband-modem-huawei.c93
-rw-r--r--plugins/icera/mm-broadband-modem-icera.c92
-rw-r--r--plugins/iridium/mm-broadband-modem-iridium.c17
-rw-r--r--plugins/linktop/mm-broadband-modem-linktop.c88
-rw-r--r--plugins/longcheer/mm-broadband-modem-longcheer.c106
-rw-r--r--plugins/mbm/mm-broadband-modem-mbm.c79
-rw-r--r--plugins/nokia/mm-broadband-modem-nokia.c41
-rw-r--r--plugins/novatel/mm-broadband-modem-novatel.c90
-rw-r--r--plugins/option/mm-broadband-modem-option.c92
-rw-r--r--plugins/sierra/mm-broadband-modem-sierra.c119
-rw-r--r--plugins/simtech/mm-broadband-modem-simtech.c109
-rw-r--r--plugins/wavecom/mm-broadband-modem-wavecom.c134
-rw-r--r--plugins/x22x/mm-broadband-modem-x22x.c84
-rw-r--r--plugins/zte/mm-broadband-modem-zte.c103
15 files changed, 1198 insertions, 131 deletions
diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c
index 921755ba..4c74774c 100644
--- a/plugins/cinterion/mm-broadband-modem-cinterion.c
+++ b/plugins/cinterion/mm-broadband-modem-cinterion.c
@@ -38,10 +38,12 @@ static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
+static MMIfaceModem *iface_modem_parent;
+
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init))
struct _MMBroadbandModemCinterionPrivate {
/* Flag to know if we should try AT^SIND or not to get psinfo */
@@ -514,6 +516,80 @@ load_access_technologies (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
+
+ /* 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);
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* ALLOWED MODES */
static gboolean
@@ -1191,6 +1267,10 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
iface->set_allowed_modes_finish = set_allowed_modes_finish;
iface->load_supported_bands = load_supported_bands;
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
index 19965b47..410032df 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -1075,6 +1075,90 @@ set_current_bands (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+ /* CDMA modems don't support 'preferred' setups */
+ if (!mm_iface_modem_is_cdma_only (self)) {
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
@@ -1091,7 +1175,7 @@ parse_prefmode (const gchar *response, MMModemMode *preferred, GError **error)
*preferred = MM_MODEM_MODE_3G;
return TRUE;
} else if (a == 8) {
- *preferred = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G;
+ *preferred = MM_MODEM_MODE_NONE;
return TRUE;
}
@@ -1116,10 +1200,7 @@ load_allowed_modes_finish (MMIfaceModem *self,
return FALSE;
if (mm_iface_modem_is_cdma_only (self)) {
- /* CDMA-only devices always support 2G and 3G if they have 3G, so just
- * use the modes from GCAP as the list of allowed modes.
- */
- *allowed = mm_iface_modem_get_supported_modes (self);
+ *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
return parse_prefmode (response, preferred, error);
}
@@ -2660,6 +2741,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->load_current_bands_finish = load_current_bands_finish;
iface->set_current_bands = set_current_bands;
iface->set_current_bands_finish = set_current_bands_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
index 7d8661bc..a9fdfe38 100644
--- a/plugins/icera/mm-broadband-modem-icera.c
+++ b/plugins/icera/mm-broadband-modem-icera.c
@@ -40,12 +40,13 @@ static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface);
+static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIcera, mm_broadband_modem_icera, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init))
enum {
PROP_0,
@@ -67,6 +68,88 @@ struct _MMBroadbandModemIceraPrivate {
};
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
@@ -201,7 +284,8 @@ modem_set_allowed_modes (MMIfaceModem *self,
icera_mode = 3;
else /* none preferred, so AUTO */
icera_mode = 5;
- }
+ } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
+ icera_mode = 5;
if (icera_mode < 0) {
gchar *allowed_str;
@@ -1769,6 +1853,10 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = modem_load_allowed_modes;
iface->load_allowed_modes_finish = modem_load_allowed_modes_finish;
iface->set_allowed_modes = modem_set_allowed_modes;
diff --git a/plugins/iridium/mm-broadband-modem-iridium.c b/plugins/iridium/mm-broadband-modem-iridium.c
index c3c81aaf..b26851b2 100644
--- a/plugins/iridium/mm-broadband-modem-iridium.c
+++ b/plugins/iridium/mm-broadband-modem-iridium.c
@@ -219,13 +219,12 @@ setup_flow_control (MMIfaceModem *self,
/*****************************************************************************/
/* Load supported modes (Modem inteface) */
-static MMModemMode
+static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- /* Report CS only, Iridium connections are circuit-switched */
- return MM_MODEM_MODE_CS;
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
@@ -234,11 +233,23 @@ load_supported_modes (MMIfaceModem *self,
gpointer user_data)
{
GSimpleAsyncResult *result;
+ GArray *combinations;
+ MMModemModeCombination mode;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes);
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
+
+ /* Report CS only, Iridium connections are circuit-switched */
+ mode.allowed = MM_MODEM_MODE_CS;
+ mode.preferred = MM_MODEM_MODE_NONE;
+ g_array_append_val (combinations, mode);
+
+ g_simple_async_result_set_op_res_gpointer (result, combinations, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
diff --git a/plugins/linktop/mm-broadband-modem-linktop.c b/plugins/linktop/mm-broadband-modem-linktop.c
index 49722819..bcfa7daf 100644
--- a/plugins/linktop/mm-broadband-modem-linktop.c
+++ b/plugins/linktop/mm-broadband-modem-linktop.c
@@ -40,8 +40,84 @@
static void iface_modem_init (MMIfaceModem *iface);
+static MMIfaceModem *iface_modem_parent;
+
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemLinktop, mm_broadband_modem_linktop, MM_TYPE_BROADBAND_MODEM, 0,
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
+
+/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
+
+ /* 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);
+
+ /* 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);
+}
+
+static void
+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));
+}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -158,9 +234,11 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_3G)
linktop_mode = LINKTOP_MODE_3G;
else if ((allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) &&
- (preferred == MM_MODEM_MODE_NONE)) {
+ (preferred == MM_MODEM_MODE_NONE))
+ linktop_mode = LINKTOP_MODE_ANY;
+ else if ((allowed == MM_MODEM_MODE_ANY &&
+ preferred == MM_MODEM_MODE_NONE))
linktop_mode = LINKTOP_MODE_ANY;
- }
if (linktop_mode < 0) {
gchar *allowed_str;
@@ -220,6 +298,10 @@ mm_broadband_modem_linktop_init (MMBroadbandModemLinktop *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/longcheer/mm-broadband-modem-longcheer.c b/plugins/longcheer/mm-broadband-modem-longcheer.c
index 949d54d8..3abaaeaf 100644
--- a/plugins/longcheer/mm-broadband-modem-longcheer.c
+++ b/plugins/longcheer/mm-broadband-modem-longcheer.c
@@ -33,8 +33,88 @@
static void iface_modem_init (MMIfaceModem *iface);
+static MMIfaceModem *iface_modem_parent;
+
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemLongcheer, mm_broadband_modem_longcheer, MM_TYPE_BROADBAND_MODEM, 0,
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
+
+/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 4);
+
+ /* 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, 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);
+}
+
+static void
+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));
+}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -76,16 +156,16 @@ load_allowed_modes_finish (MMIfaceModem *self,
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_3G;
return TRUE;
- case 4:
- /* GSM preferred */
- *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
- *preferred = MM_MODEM_MODE_2G;
- return TRUE;
case 3:
/* GSM only */
*allowed = MM_MODEM_MODE_2G;
*preferred = MM_MODEM_MODE_NONE;
return TRUE;
+ case 4:
+ /* GSM preferred */
+ *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
+ *preferred = MM_MODEM_MODE_2G;
+ return TRUE;
default:
break;
}
@@ -159,14 +239,14 @@ set_allowed_modes (MMIfaceModem *self,
mododr = 3;
else if (allowed == MM_MODEM_MODE_3G)
mododr = 1;
- else if (allowed == MM_MODEM_MODE_ANY || (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))) {
+ else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
if (preferred == MM_MODEM_MODE_2G)
mododr = 4;
- else if (preferred == MM_MODEM_MODE_3G ||
- preferred == MM_MODEM_MODE_NONE ||
- preferred == MM_MODEM_MODE_ANY)
+ else if (preferred == MM_MODEM_MODE_3G)
mododr = 2;
- }
+ } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
+ /* Default to 3G preferred */
+ mododr = 2;
if (mododr == 0) {
gchar *allowed_str;
@@ -338,8 +418,12 @@ mm_broadband_modem_longcheer_init (MMBroadbandModemLongcheer *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/mbm/mm-broadband-modem-mbm.c b/plugins/mbm/mm-broadband-modem-mbm.c
index f75a9a8d..e5eacaf0 100644
--- a/plugins/mbm/mm-broadband-modem-mbm.c
+++ b/plugins/mbm/mm-broadband-modem-mbm.c
@@ -45,6 +45,7 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
+static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbm, mm_broadband_modem_mbm, MM_TYPE_BROADBAND_MODEM, 0,
@@ -191,6 +192,80 @@ modem_after_sim_unlock (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
+
+ /* 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);
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
@@ -1237,12 +1312,16 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->create_bearer = modem_create_bearer;
iface->create_bearer_finish = modem_create_bearer_finish;
iface->create_sim = create_sim;
iface->create_sim_finish = create_sim_finish;
iface->modem_after_sim_unlock = modem_after_sim_unlock;
iface->modem_after_sim_unlock_finish = modem_after_sim_unlock_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/nokia/mm-broadband-modem-nokia.c b/plugins/nokia/mm-broadband-modem-nokia.c
index 998683c1..a0f870b8 100644
--- a/plugins/nokia/mm-broadband-modem-nokia.c
+++ b/plugins/nokia/mm-broadband-modem-nokia.c
@@ -68,45 +68,6 @@ create_sim (MMIfaceModem *self,
}
/*****************************************************************************/
-/* Load supported modes (Modem interface) */
-
-static MMModemMode
-modem_load_supported_modes_finish (MMIfaceModem *self,
- GAsyncResult *res,
- GError **error)
-{
- return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res)));
-}
-
-static void
-modem_load_supported_modes (MMIfaceModem *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *result;
- MMModemMode mode;
-
- /* Nokia phones don't seem to like AT+WS46?, they just report 2G even if
- * 3G is supported, so we'll just assume they actually do 3G. */
- mode = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
-
- /* Then, if the modem has LTE caps, it does 4G */
- if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
- mode |= MM_MODEM_MODE_4G;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_load_supported_modes);
- g_simple_async_result_set_op_res_gpointer (result,
- GUINT_TO_POINTER (mode),
- NULL);
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-}
-
-/*****************************************************************************/
/* Load access technologies (Modem interface) */
typedef struct {
@@ -407,8 +368,6 @@ iface_modem_init (MMIfaceModem *iface)
iface->modem_power_down = NULL;
iface->modem_power_down_finish = NULL;
- iface->load_supported_modes = modem_load_supported_modes;
- iface->load_supported_modes_finish = modem_load_supported_modes_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
}
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c
index 3d84509b..62f4a3a7 100644
--- a/plugins/novatel/mm-broadband-modem-novatel.c
+++ b/plugins/novatel/mm-broadband-modem-novatel.c
@@ -48,7 +48,89 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemNovatel, mm_broadband_modem_novatel, MM_
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init))
+
+/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -275,6 +357,10 @@ set_allowed_modes (MMIfaceModem *self,
a = 1;
else if (preferred == MM_MODEM_MODE_3G)
a = 2;
+ } else if (allowed == MM_MODEM_MODE_ANY &&
+ preferred == MM_MODEM_MODE_NONE) {
+ b = 2;
+ a = 0;
}
if (a < 0 || b < 0) {
@@ -1149,6 +1235,8 @@ iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/option/mm-broadband-modem-option.c b/plugins/option/mm-broadband-modem-option.c
index 4c63f3db..42d9570e 100644
--- a/plugins/option/mm-broadband-modem-option.c
+++ b/plugins/option/mm-broadband-modem-option.c
@@ -35,11 +35,12 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
+static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemOption, mm_broadband_modem_option, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init))
struct _MMBroadbandModemOptionPrivate {
/* Regex for access-technology related notifications */
@@ -57,6 +58,88 @@ struct _MMBroadbandModemOptionPrivate {
};
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
@@ -186,7 +269,8 @@ set_allowed_modes (MMIfaceModem *self,
option_mode = 3;
else /* none preferred, so AUTO */
option_mode = 5;
- }
+ } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
+ option_mode = 5;
if (option_mode < 0) {
gchar *allowed_str;
@@ -1140,10 +1224,14 @@ mm_broadband_modem_option_init (MMBroadbandModemOption *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->modem_after_power_up = modem_after_power_up;
iface->modem_after_power_up_finish = modem_after_power_up_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
index f8cfb743..46d2f3c3 100644
--- a/plugins/sierra/mm-broadband-modem-sierra.c
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
@@ -514,6 +514,109 @@ load_access_technologies (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* CDMA-only modems don't support changing modes, default to parent's */
+ if (!mm_iface_modem_is_3gpp (self)) {
+ g_simple_async_result_set_op_res_gpointer (simple, all, (GDestroyNotify) g_array_unref);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ /* Build list of combinations for 3GPP devices */
+ 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);
+
+ /* Non-LTE devices allow 2G/3G preferred modes */
+ if (!mm_iface_modem_is_3gpp_lte (self)) {
+ /* 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);
+ } else {
+ /* 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);
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
typedef struct {
@@ -569,7 +672,10 @@ selrat_query_ready (MMBaseModem *self,
if (mm_get_uint_from_match_info (match_info, 1, &mode) && mode <= 7) {
switch (mode) {
case 0:
- result.allowed = MM_MODEM_MODE_ANY;
+ result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
+ result.preferred = MM_MODEM_MODE_NONE;
+ if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
+ result.allowed |= MM_MODEM_MODE_4G;
result.preferred = MM_MODEM_MODE_NONE;
break;
case 1:
@@ -583,7 +689,7 @@ selrat_query_ready (MMBaseModem *self,
case 3:
/* in Sierra LTE devices, mode 3 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) {
- result.allowed = MM_MODEM_MODE_ANY;
+ result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
result.preferred = MM_MODEM_MODE_NONE;
} else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -593,7 +699,7 @@ selrat_query_ready (MMBaseModem *self,
case 4:
/* in Sierra LTE devices, mode 4 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) {
- result.allowed = MM_MODEM_MODE_ANY;
+ result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
result.preferred = MM_MODEM_MODE_NONE;
} else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -773,9 +879,10 @@ set_allowed_modes (MMIfaceModem *self,
idx = 0;
} else if (allowed == MM_MODEM_MODE_4G)
idx = 6;
- else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G))
+ else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G) &&
+ preferred == MM_MODEM_MODE_NONE)
idx = 7;
- else if (allowed == MM_MODEM_MODE_ANY)
+ else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
idx = 0;
if (idx < 0) {
@@ -1556,6 +1663,8 @@ iface_modem_init (MMIfaceModem *iface)
mm_common_sierra_peek_parent_interfaces (iface);
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/simtech/mm-broadband-modem-simtech.c b/plugins/simtech/mm-broadband-modem-simtech.c
index 359dde50..f7353d88 100644
--- a/plugins/simtech/mm-broadband-modem-simtech.c
+++ b/plugins/simtech/mm-broadband-modem-simtech.c
@@ -37,11 +37,12 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
+static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemSimtech, mm_broadband_modem_simtech, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init))
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */
@@ -445,6 +446,87 @@ load_access_technologies (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
typedef struct {
@@ -731,19 +813,28 @@ set_allowed_modes (MMIfaceModem *self,
user_data,
set_allowed_modes);
- ctx->nmp = 2; /* automatic mode preference */
- ctx->naop = 0; /* automatic acquisition order */
+ /* Defaults: automatic search */
+ ctx->nmp = 2;
+ ctx->naop = 0;
- if (allowed == MM_MODEM_MODE_2G)
+ if (allowed == MM_MODEM_MODE_ANY &&
+ preferred == MM_MODEM_MODE_NONE) {
+ /* defaults nmp and naop */
+ } else if (allowed == MM_MODEM_MODE_2G) {
ctx->nmp = 13;
- else if (allowed == MM_MODEM_MODE_3G)
+ ctx->naop = 0;
+ } else if (allowed == MM_MODEM_MODE_3G) {
ctx->nmp = 14;
- else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
+ ctx->naop = 0;
+ } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
+ /* default nmp */
if (preferred == MM_MODEM_MODE_2G)
ctx->naop = 3;
else if (preferred == MM_MODEM_MODE_3G)
ctx->naop = 2;
- /* else, auto */
+ else
+ /* default naop */
+ ctx->naop = 0;
} else {
gchar *allowed_str;
gchar *preferred_str;
@@ -830,8 +921,12 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/wavecom/mm-broadband-modem-wavecom.c b/plugins/wavecom/mm-broadband-modem-wavecom.c
index 6f487b42..1ee16e99 100644
--- a/plugins/wavecom/mm-broadband-modem-wavecom.c
+++ b/plugins/wavecom/mm-broadband-modem-wavecom.c
@@ -37,6 +37,8 @@
static void iface_modem_init (MMIfaceModem *iface);
+static MMIfaceModem *iface_modem_parent;
+
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemWavecom, mm_broadband_modem_wavecom, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
@@ -82,18 +84,17 @@ static const WavecomBand3G bands_3g[] = {
};
/*****************************************************************************/
-/* Supported modes (Modem interface) */
+/* Load supported modes (Modem interface) */
-static MMModemMode
+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))
- return MM_MODEM_MODE_NONE;
+ return NULL;
- return (MMModemMode) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res)));
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
@@ -101,9 +102,13 @@ supported_ms_classes_query_ready (MMBaseModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
const gchar *response;
GError *error = NULL;
- MMModemMode mode;
+ MMModemModeCombination mode;
+ MMModemMode mode_all;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
@@ -115,40 +120,71 @@ supported_ms_classes_query_ready (MMBaseModem *self,
}
response = mm_strip_tag (response, "+CGCLASS:");
- mode = MM_MODEM_MODE_NONE;
-
- if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR)) {
- mm_dbg ("Modem supports Class A mobile station");
- mode |= MM_MODEM_MODE_3G;
- }
-
- if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR)) {
- mm_dbg ("Modem supports Class B mobile station");
- mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
- }
-
- if (strstr (response, WAVECOM_MS_CLASS_CG_IDSTR)) {
- mm_dbg ("Modem supports Class CG mobile station");
- mode |= MM_MODEM_MODE_2G;
- }
-
- if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR)) {
- mm_dbg ("Modem supports Class CC mobile station");
- mode |= MM_MODEM_MODE_CS;
- }
+ mode_all = MM_MODEM_MODE_NONE;
+ if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR))
+ mode_all |= MM_MODEM_MODE_3G;
+ if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR))
+ mode_all |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
+ if (strstr (response, WAVECOM_MS_CLASS_CG_IDSTR))
+ mode_all |= MM_MODEM_MODE_2G;
+ if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR))
+ mode_all |= MM_MODEM_MODE_CS;
/* If none received, error */
- if (mode == MM_MODEM_MODE_NONE)
+ if (mode_all == MM_MODEM_MODE_NONE) {
g_simple_async_result_set_error (simple,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Couldn't get supported mobile station classes: '%s'",
response);
- else
- g_simple_async_result_set_op_res_gpointer (simple,
- GUINT_TO_POINTER (mode),
- NULL);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+ /* Build ALL mask */
+ all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
+ mode.allowed = mode_all;
+ mode.preferred = MM_MODEM_MODE_NONE;
+ g_array_append_val (all, mode);
+
+ /* Build list of combinations */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 7);
+ /* CS only */
+ mode.allowed = MM_MODEM_MODE_CS;
+ mode.preferred = MM_MODEM_MODE_NONE;
+ g_array_append_val (combinations, mode);
+ /* 2G only */
+ mode.allowed = MM_MODEM_MODE_2G;
+ mode.preferred = MM_MODEM_MODE_NONE;
+ g_array_append_val (combinations, mode);
+ /* CS and 2G */
+ mode.allowed = (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G);
+ mode.preferred = MM_MODEM_MODE_2G;
+ 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);
}
@@ -158,20 +194,16 @@ load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- load_supported_modes);
-
mm_base_modem_at_command (
MM_BASE_MODEM (self),
"+CGCLASS=?",
3,
FALSE,
(GAsyncReadyCallback)supported_ms_classes_query_ready,
- result);
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ load_supported_modes));
}
/*****************************************************************************/
@@ -387,8 +419,6 @@ load_allowed_modes (MMIfaceModem *self,
typedef struct {
MMBroadbandModemWavecom *self;
GSimpleAsyncResult *result;
- MMModemMode allowed;
- MMModemMode preferred;
gchar *cgclass_command;
gchar *wwsm_command;
} SetAllowedModesContext;
@@ -473,19 +503,27 @@ set_allowed_modes (MMIfaceModem *self,
callback,
user_data,
set_allowed_modes);
- ctx->allowed = allowed;
- ctx->preferred = preferred;
+
+ /* Handle ANY/NONE */
+ if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE) {
+ if (mm_iface_modem_is_3g (self)) {
+ allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
+ preferred = MM_MODEM_MODE_NONE;
+ } else {
+ allowed = (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G);
+ preferred = MM_MODEM_MODE_2G;
+ }
+ }
if (allowed == MM_MODEM_MODE_CS)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CC_IDSTR);
else if (allowed == MM_MODEM_MODE_2G)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CG_IDSTR);
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS) &&
- preferred == MM_MODEM_MODE_NONE)
+ preferred == MM_MODEM_MODE_2G)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_B_IDSTR);
else if (allowed & MM_MODEM_MODE_3G) {
- if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) ||
- allowed == (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
+ if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
if (preferred == MM_MODEM_MODE_2G)
ctx->wwsm_command = g_strdup ("+WWSM=2,1");
else if (preferred == MM_MODEM_MODE_3G)
@@ -1144,6 +1182,8 @@ mm_broadband_modem_wavecom_init (MMBroadbandModemWavecom *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
diff --git a/plugins/x22x/mm-broadband-modem-x22x.c b/plugins/x22x/mm-broadband-modem-x22x.c
index 2120b6d2..3afb08cb 100644
--- a/plugins/x22x/mm-broadband-modem-x22x.c
+++ b/plugins/x22x/mm-broadband-modem-x22x.c
@@ -33,8 +33,83 @@
static void iface_modem_init (MMIfaceModem *iface);
+static MMIfaceModem *iface_modem_parent;
+
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemX22x, mm_broadband_modem_x22x, MM_TYPE_BROADBAND_MODEM, 0,
- G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
+
+/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+ /* Build list of combinations for 3GPP devices */
+ combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
+
+ /* 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);
+
+ /* 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);
+}
+
+static void
+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));
+}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -168,7 +243,8 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE)
syssel = 0;
- else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))
+ else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) &&
+ preferred == MM_MODEM_MODE_NONE)
syssel = 0;
else {
gchar *allowed_str;
@@ -264,8 +340,12 @@ mm_broadband_modem_x22x_init (MMBroadbandModemX22x *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
diff --git a/plugins/zte/mm-broadband-modem-zte.c b/plugins/zte/mm-broadband-modem-zte.c
index e7d190ad..d4f4f0f8 100644
--- a/plugins/zte/mm-broadband-modem-zte.c
+++ b/plugins/zte/mm-broadband-modem-zte.c
@@ -250,6 +250,100 @@ modem_power_down (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load supported modes (Modem interface) */
+
+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))
+ return NULL;
+
+ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+}
+
+static void
+parent_load_supported_modes_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+ GArray *all;
+ GArray *combinations;
+ GArray *filtered;
+ MMModemModeCombination mode;
+
+ 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;
+ }
+
+ /* 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);
+
+ if (!mm_iface_modem_is_3gpp_lte (self)) {
+ /* 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);
+ } else {
+ /* 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);
+ }
+
+ /* 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);
+}
+
+static void
+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));
+}
+
+/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
@@ -413,7 +507,12 @@ set_allowed_modes (MMIfaceModem *self,
pref_acq = 2;
else /* none preferred, so AUTO */
pref_acq = 0;
- } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G)) {
+ } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G) &&
+ preferred == MM_MODEM_MODE_NONE) {
+ cm_mode = 0;
+ pref_acq = 0;
+ } else if (allowed == MM_MODEM_MODE_ANY &&
+ preferred == MM_MODEM_MODE_NONE) {
cm_mode = 0;
pref_acq = 0;
} else if (allowed == MM_MODEM_MODE_4G) {
@@ -679,6 +778,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->modem_power_down_finish = modem_power_down_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->load_supported_modes = load_supported_modes;
+ iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;