aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOliver Kästner <git@oliver-kaestner.de>2024-05-23 00:17:40 +0200
committerOliver Kästner <git@oliver-kaestner.de>2024-05-23 00:35:01 +0200
commit2d3caa9a355588bf542a3f7e472cbee63e3b2b64 (patch)
tree168594d991302dfdf15cc81c1cfc99492ed9fe2c /src
parente01eac5bfe64eb5a53c0d0c437c440347d26ba95 (diff)
huawei: enable setting LTE bands
Diffstat (limited to 'src')
-rw-r--r--src/plugins/huawei/mm-broadband-modem-huawei.c102
1 files changed, 60 insertions, 42 deletions
diff --git a/src/plugins/huawei/mm-broadband-modem-huawei.c b/src/plugins/huawei/mm-broadband-modem-huawei.c
index ea664ca1..8c4372ca 100644
--- a/src/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/src/plugins/huawei/mm-broadband-modem-huawei.c
@@ -799,48 +799,44 @@ static BandTable lte_bands[] = {
};
static gboolean
-bands_array_to_huawei (BandTable *band_table,
- guint band_table_len,
- GArray *bands_array,
- guint64 *out_huawei)
+bands_array_to_huawei (GArray *bands_array,
+ guint64 *out_gsm_umts_huawei,
+ guint64 *out_lte_huawei)
{
guint i;
+ MMModemBand mm_band;
- /* Treat ANY as a special case: All huawei flags enabled */
- if (bands_array->len == 1 &&
- g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
- /* This is only correct for 2G/3G bands when using ^SYSCFG(EX).
- * For setting LTE bands with ^SYSCFGEX, the
- * MM_HUAWEI_SYSCFGEX_BAND_ANY_LTE mask has to be used
- */
- *out_huawei = MM_HUAWEI_SYSCFG_BAND_ANY;
+ g_assert (out_gsm_umts_huawei);
+ g_assert (out_lte_huawei);
+
+ if (bands_array->len == 1 && g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
+ *out_gsm_umts_huawei = MM_HUAWEI_SYSCFG_BAND_ANY;
+ *out_lte_huawei = MM_HUAWEI_SYSCFGEX_BAND_ANY_LTE;
return TRUE;
}
- *out_huawei = 0;
+ *out_gsm_umts_huawei = 0;
+ *out_lte_huawei = 0;
+
for (i = 0; i < bands_array->len; i++) {
guint j;
+
+ mm_band = g_array_index (bands_array, MMModemBand, i);
- for (j = 0; j < band_table_len; j++) {
- if (g_array_index (bands_array, MMModemBand, i) == band_table[j].mm)
- *out_huawei |= band_table[j].huawei;
+ if (mm_band < MM_MODEM_BAND_EUTRAN_1) {
+ for (j = 0; j < G_N_ELEMENTS (gsm_umts_bands); j++) {
+ if (mm_band == gsm_umts_bands[j].mm)
+ *out_gsm_umts_huawei |= gsm_umts_bands[j].huawei;
+ }
+ } else {
+ for (j = 0; j < G_N_ELEMENTS (lte_bands); j++) {
+ if (mm_band == lte_bands[j].mm)
+ *out_lte_huawei |= lte_bands[j].huawei;
+ }
}
}
- return (*out_huawei > 0 ? TRUE : FALSE);
-}
-
-static gboolean
-gsm_umts_bands_array_to_huawei (GArray *bands_array,
- guint32 *out_huawei)
-{
- gboolean success;
- guint64 huawei64;
-
- success = bands_array_to_huawei (gsm_umts_bands, G_N_ELEMENTS (gsm_umts_bands), bands_array, &huawei64);
-
- *out_huawei = (guint32) huawei64;
- return success;
+ return (*out_gsm_umts_huawei + *out_lte_huawei) > 0;
}
static gboolean
@@ -1036,41 +1032,63 @@ syscfg_set_ready (MMBaseModem *self,
}
static void
-set_current_bands (MMIfaceModem *self,
- GArray *bands_array,
- GAsyncReadyCallback callback,
- gpointer user_data)
+set_current_bands (MMIfaceModem *self,
+ GArray *bands_array,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GTask *task;
- gchar *cmd;
- guint32 huawei_band = 0x3FFFFFFF;
- gchar *bands_string;
+ g_autofree gchar *cmd = NULL;
+ g_autofree gchar *bands_string = NULL;
+ guint64 huawei_gsm_umts_bands;
+ guint64 huawei_lte_bands;
task = g_task_new (self, NULL, callback, user_data);
bands_string = mm_common_build_bands_string ((MMModemBand *)(gpointer)bands_array->data,
bands_array->len);
- if (!gsm_umts_bands_array_to_huawei (bands_array, &huawei_band)) {
+ /* We need to split the bands array into two parts: gsm/umts and lte bands.
+ * The encoded huawei values overlap and need to be passed as separate
+ * AT command parameters to ^SYSCFG(EX) */
+ if (!bands_array_to_huawei (bands_array, &huawei_gsm_umts_bands, &huawei_lte_bands)) {
g_task_return_new_error (task,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Invalid bands requested: '%s'",
bands_string);
g_object_unref (task);
- g_free (bands_string);
return;
}
- cmd = g_strdup_printf ("AT^SYSCFG=16,3,%X,2,4", huawei_band);
+ /* Note: SYSCFG(EX) requires at least one band per enabled technology/mode.
+ * E.g. if the user wants to set only LTE bands, we'd also need to switch
+ * to LTE-only mode ("03"). "Automatic" mode ("00") won't work in this case.
+ * "No Change" ("99" or 16) will work if the mode is already set accordingly.
+ * So to keep things simple here, assume that the current mode is correct.
+ */
+ if (MM_BROADBAND_MODEM_HUAWEI (self)->priv->syscfgex_support == FEATURE_SUPPORTED) {
+ cmd = g_strdup_printf ("^SYSCFGEX=\"99\",%" G_GINT64_MODIFIER "X,2,4,%" G_GINT64_MODIFIER "X,,",
+ huawei_gsm_umts_bands,
+ huawei_lte_bands);
+ } else if (MM_BROADBAND_MODEM_HUAWEI (self)->priv->syscfg_support == FEATURE_SUPPORTED) {
+ cmd = g_strdup_printf ("^SYSCFG=16,3,%" G_GINT64_MODIFIER "X,2,4",
+ huawei_gsm_umts_bands);
+ } else {
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Neither ^SYSCFG nor ^SYSCFGEX is supported to set bands");
+ g_object_unref (task);
+ return;
+ }
+
mm_base_modem_at_command (MM_BASE_MODEM (self),
cmd,
3,
FALSE,
(GAsyncReadyCallback)syscfg_set_ready,
task);
- g_free (cmd);
- g_free (bands_string);
}
/*****************************************************************************/