diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h index a12e1a24..e86b7752 100644 --- a/include/ModemManager-enums.h +++ b/include/ModemManager-enums.h @@ -386,6 +386,7 @@ typedef enum { /*< underscore_name=mm_modem_mode >*/ * @MM_MODEM_BAND_EUTRAN_70: E-UTRAN band 70. Since 1.8. * @MM_MODEM_BAND_EUTRAN_71: E-UTRAN band 71. Since 1.8. * @MM_MODEM_BAND_EUTRAN_85: E-UTRAN band 85. Since 1.20. + * @MM_MODEM_BAND_EUTRAN_106: E-UTRAN band 106. Since 1.26. * @MM_MODEM_BAND_CDMA_BC0: CDMA Band Class 0 (US Cellular 850MHz). Since 1.8. * @MM_MODEM_BAND_CDMA_BC1: CDMA Band Class 1 (US PCS 1900MHz). Since 1.8. * @MM_MODEM_BAND_CDMA_BC2: CDMA Band Class 2 (UK TACS 900MHz). Since 1.8. @@ -652,7 +653,9 @@ typedef enum { /*< underscore_name=mm_modem_band >*/ MM_MODEM_BAND_NGRAN_257 = 557, MM_MODEM_BAND_NGRAN_258 = 558, MM_MODEM_BAND_NGRAN_260 = 560, - MM_MODEM_BAND_NGRAN_261 = 561 + MM_MODEM_BAND_NGRAN_261 = 561, + /* LTE bands > 97 follow EUTRAN numbering + 1000 as offset */ + MM_MODEM_BAND_EUTRAN_106 = 1136 } MMModemBand; /** diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c index 12796429..f14cd6f0 100644 --- a/libmm-glib/mm-common-helpers.c +++ b/libmm-glib/mm-common-helpers.c @@ -1314,7 +1314,9 @@ mm_common_band_is_utran (MMModemBand band) gboolean mm_common_band_is_eutran (MMModemBand band) { - return (band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71); + return ((band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71) || + (band == MM_MODEM_BAND_EUTRAN_85) || + (band == MM_MODEM_BAND_EUTRAN_106)); } gboolean diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c index ea09b9d8..c83614af 100644 --- a/src/mm-modem-helpers-qmi.c +++ b/src/mm-modem-helpers-qmi.c @@ -338,18 +338,29 @@ dms_add_extended_qmi_lte_bands (GArray *mm_bands, val = g_array_index (extended_qmi_bands, guint16, i); - /* MM_MODEM_BAND_EUTRAN_1 = 31, + /* Valid EUTRAN bands: + * + * MM_MODEM_BAND_EUTRAN_1 = 31, * ... * MM_MODEM_BAND_EUTRAN_71 = 101 + * + * MM_MODEM_BAND_EUTRAN_85 = 115 + * + * There's then an offset of 1000 for EUTRAN bands >= 98 + * + * MM_MODEM_BAND_EUTRAN_106 = 1136 */ - if (val < 1 || val > 71) - mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val); - else { + if ((val >= 1 && val <= 71) || + (val == 85) || (val == 106)) { MMModemBand band; - band = (MMModemBand)(val + MM_MODEM_BAND_EUTRAN_1 - 1); + if (val >= 98) + band = (MMModemBand)(val + 1000 + MM_MODEM_BAND_EUTRAN_1 - 1); + else + band = (MMModemBand)(val + MM_MODEM_BAND_EUTRAN_1 - 1); g_array_append_val (mm_bands, band); - } + } else + mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val); } } @@ -584,18 +595,29 @@ nas_add_extended_qmi_lte_bands (GArray *mm_bands, val = 1 + j + (i * 64); - /* MM_MODEM_BAND_EUTRAN_1 = 31, + /* Valid EUTRAN bands: + * + * MM_MODEM_BAND_EUTRAN_1 = 31, * ... * MM_MODEM_BAND_EUTRAN_71 = 101 + * + * MM_MODEM_BAND_EUTRAN_85 = 115 + * + * There's then an offset of 1000 for EUTRAN bands >= 98 + * + * MM_MODEM_BAND_EUTRAN_106 = 1136 */ - if (val < 1 || val > 71) - mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val); - else { + if ((val >= 1 && val <= 71) || + (val == 85) || (val == 106)) { MMModemBand band; - band = (val + MM_MODEM_BAND_EUTRAN_1 - 1); + if (val >= 98) + band = (val + 1000 + MM_MODEM_BAND_EUTRAN_1 - 1); + else + band = (val + MM_MODEM_BAND_EUTRAN_1 - 1); g_array_append_val (mm_bands, band); - } + } else + mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val); } } } @@ -686,13 +708,18 @@ mm_modem_bands_to_qmi_band_preference (GArray *mm_bands, band = g_array_index (mm_bands, MMModemBand, i); - if (band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71) { + if ((band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71) || + (band == MM_MODEM_BAND_EUTRAN_85) || + (band == MM_MODEM_BAND_EUTRAN_106)) { if (extended_qmi_lte_bands && extended_qmi_lte_bands_size) { /* Add extended LTE band preference */ guint val; guint j; guint k; + /* Check first if we need to subtract the offset */ + if (band == MM_MODEM_BAND_EUTRAN_106) + band -= 1000; /* it's really (band - MM_MODEM_BAND_EUTRAN_1 +1 -1), because * we want EUTRAN1 in index 0 */ val = band - MM_MODEM_BAND_EUTRAN_1; diff --git a/src/tests/test-modem-helpers-qmi.c b/src/tests/test-modem-helpers-qmi.c index 576beb68..016c63a1 100644 --- a/src/tests/test-modem-helpers-qmi.c +++ b/src/tests/test-modem-helpers-qmi.c @@ -1929,6 +1929,240 @@ test_registration_state_from_qmi_system_info_5g_5gs_home (void) MM_MODEM_ACCESS_TECHNOLOGY_5GNR); } +/*****************************************************************************/ +/* Test modem bands helpers */ + +static void +test_supported_bands_eutran_telit_fn990 (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + g_autoptr(GArray) mm_bands_arr_expected = NULL; + g_autoptr(GArray) extended_qmi_lte_bands = NULL; + static const guint16 qmi_bands[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 12, 13, 14, 17, 18, 19, 20, 25, + 26, 28, 29, 30, 32, 34, 38, 39, + 40, 41, 42, 43, 46, 48, 66, 71, + }; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, + MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_6, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_14, MM_MODEM_BAND_EUTRAN_17, + MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_25, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, + MM_MODEM_BAND_EUTRAN_32, MM_MODEM_BAND_EUTRAN_34, MM_MODEM_BAND_EUTRAN_38, MM_MODEM_BAND_EUTRAN_39, + MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_42, MM_MODEM_BAND_EUTRAN_43, + MM_MODEM_BAND_EUTRAN_46, MM_MODEM_BAND_EUTRAN_48, MM_MODEM_BAND_EUTRAN_66, MM_MODEM_BAND_EUTRAN_71, + }; + + extended_qmi_lte_bands = g_array_sized_new (FALSE, FALSE, sizeof (guint16), G_N_ELEMENTS (qmi_bands)); + mm_bands_arr_expected = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr_expected, &mm_bands, G_N_ELEMENTS (mm_bands)); + g_array_append_vals (extended_qmi_lte_bands, &qmi_bands, G_N_ELEMENTS (qmi_bands)); + + mm_bands_arr = mm_modem_bands_from_qmi_band_capabilities (0, 0, extended_qmi_lte_bands, NULL, NULL); + + g_assert_cmpmem ( + mm_bands_arr->data, mm_bands_arr->len * sizeof (MMModemBand), + mm_bands_arr_expected->data, mm_bands_arr_expected->len * sizeof (MMModemBand) + ); +} + +static void +test_supported_bands_eutran_telit_fn990_b106 (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + g_autoptr(GArray) mm_bands_arr_expected = NULL; + g_autoptr(GArray) extended_qmi_lte_bands = NULL; + static const guint16 qmi_bands[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 12, 13, 14, 17, 18, 19, 20, 25, + 26, 28, 29, 30, 32, 34, 38, 39, + 40, 41, 42, 43, 46, 48, 66, 71, + 106 + }; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, + MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_6, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_14, MM_MODEM_BAND_EUTRAN_17, + MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_25, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, + MM_MODEM_BAND_EUTRAN_32, MM_MODEM_BAND_EUTRAN_34, MM_MODEM_BAND_EUTRAN_38, MM_MODEM_BAND_EUTRAN_39, + MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_42, MM_MODEM_BAND_EUTRAN_43, + MM_MODEM_BAND_EUTRAN_46, MM_MODEM_BAND_EUTRAN_48, MM_MODEM_BAND_EUTRAN_66, MM_MODEM_BAND_EUTRAN_71, + MM_MODEM_BAND_EUTRAN_106 + }; + + extended_qmi_lte_bands = g_array_sized_new (FALSE, FALSE, sizeof (guint16), G_N_ELEMENTS (qmi_bands)); + mm_bands_arr_expected = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr_expected, &mm_bands, G_N_ELEMENTS (mm_bands)); + g_array_append_vals (extended_qmi_lte_bands, &qmi_bands, G_N_ELEMENTS (qmi_bands)); + + mm_bands_arr = mm_modem_bands_from_qmi_band_capabilities (0, 0, extended_qmi_lte_bands, NULL, NULL); + + g_assert_cmpmem ( + mm_bands_arr->data, mm_bands_arr->len * sizeof (MMModemBand), + mm_bands_arr_expected->data, mm_bands_arr_expected->len * sizeof (MMModemBand) + ); +} + +static void +test_supported_bands_cdma_generic (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + g_autoptr(GArray) mm_bands_arr_expected = NULL; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_CDMA_BC0, MM_MODEM_BAND_CDMA_BC3, MM_MODEM_BAND_CDMA_BC12, MM_MODEM_BAND_CDMA_BC14, + MM_MODEM_BAND_CDMA_BC17, MM_MODEM_BAND_CDMA_BC19, + }; + QmiDmsBandCapability cdma_bands = ( + QMI_DMS_BAND_CAPABILITY_BC_0_A_SYSTEM | QMI_DMS_BAND_CAPABILITY_BC_3_A_SYSTEM | + QMI_DMS_BAND_CAPABILITY_BC_12 | QMI_DMS_BAND_CAPABILITY_BC_14 | + QMI_DMS_BAND_CAPABILITY_BC_17 | QMI_DMS_BAND_CAPABILITY_BC_19 + ); + + mm_bands_arr_expected = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr_expected, &mm_bands, G_N_ELEMENTS (mm_bands)); + + mm_bands_arr = mm_modem_bands_from_qmi_band_capabilities (cdma_bands, 0, NULL, NULL, NULL); + + g_assert_cmpmem ( + mm_bands_arr->data, mm_bands_arr->len * sizeof (MMModemBand), + mm_bands_arr_expected->data, mm_bands_arr_expected->len * sizeof (MMModemBand) + ); +} + +static void +test_mm_bands_to_qmi_eutran_telit_fn990 (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, + MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_6, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_14, MM_MODEM_BAND_EUTRAN_17, + MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_25, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, + MM_MODEM_BAND_EUTRAN_32, MM_MODEM_BAND_EUTRAN_34, MM_MODEM_BAND_EUTRAN_38, MM_MODEM_BAND_EUTRAN_39, + MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_42, MM_MODEM_BAND_EUTRAN_43, + MM_MODEM_BAND_EUTRAN_46, MM_MODEM_BAND_EUTRAN_48, MM_MODEM_BAND_EUTRAN_66, MM_MODEM_BAND_EUTRAN_71, + }; + guint64 extended_qmi_lte_bands[4]; + guint extended_qmi_lte_bands_size = G_N_ELEMENTS (extended_qmi_lte_bands); + guint64 extended_qmi_lte_bands_expected[4] = { + 0b101001111110001010111011000011110011100011111111, + 0b1000010, + 0, + 0, + }; + guint extended_qmi_lte_bands_expected_size = G_N_ELEMENTS (extended_qmi_lte_bands_expected); + /* The following are not needed for this test, but mm_modem_bands_to_qmi_band_preference does not check for NULL */ + QmiNasBandPreference nas_bands_preference; + QmiNasLteBandPreference nas_lte_bands_preference; + + mm_bands_arr = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr, &mm_bands, G_N_ELEMENTS (mm_bands)); + + mm_modem_bands_to_qmi_band_preference ( + mm_bands_arr, + &nas_bands_preference, + &nas_lte_bands_preference, + extended_qmi_lte_bands, + extended_qmi_lte_bands_size, + NULL, + 0, + NULL + ); + + g_assert_cmpmem ( + extended_qmi_lte_bands, extended_qmi_lte_bands_size * sizeof (guint64), + extended_qmi_lte_bands_expected, extended_qmi_lte_bands_expected_size * sizeof (guint64) + ); +} + +static void +test_mm_bands_to_qmi_eutran_telit_fn990_b106 (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_2, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_4, + MM_MODEM_BAND_EUTRAN_5, MM_MODEM_BAND_EUTRAN_6, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, + MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, MM_MODEM_BAND_EUTRAN_14, MM_MODEM_BAND_EUTRAN_17, + MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_25, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, + MM_MODEM_BAND_EUTRAN_32, MM_MODEM_BAND_EUTRAN_34, MM_MODEM_BAND_EUTRAN_38, MM_MODEM_BAND_EUTRAN_39, + MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_42, MM_MODEM_BAND_EUTRAN_43, + MM_MODEM_BAND_EUTRAN_46, MM_MODEM_BAND_EUTRAN_48, MM_MODEM_BAND_EUTRAN_66, MM_MODEM_BAND_EUTRAN_71, + MM_MODEM_BAND_EUTRAN_106, + }; + guint64 extended_qmi_lte_bands[4]; + guint extended_qmi_lte_bands_size = G_N_ELEMENTS (extended_qmi_lte_bands); + guint64 extended_qmi_lte_bands_expected[4] = { + 0b101001111110001010111011000011110011100011111111, + 0b100000000000000000000000000000000001000010, + 0, + 0, + }; + guint extended_qmi_lte_bands_expected_size = G_N_ELEMENTS (extended_qmi_lte_bands_expected); + /* The following are not needed for this test, but mm_modem_bands_to_qmi_band_preference does not check for NULL */ + QmiNasBandPreference nas_bands_preference; + QmiNasLteBandPreference nas_lte_bands_preference; + + mm_bands_arr = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr, &mm_bands, G_N_ELEMENTS (mm_bands)); + + mm_modem_bands_to_qmi_band_preference ( + mm_bands_arr, + &nas_bands_preference, + &nas_lte_bands_preference, + extended_qmi_lte_bands, + extended_qmi_lte_bands_size, + NULL, + 0, + NULL + ); + + g_assert_cmpmem ( + extended_qmi_lte_bands, extended_qmi_lte_bands_size * sizeof (guint64), + extended_qmi_lte_bands_expected, extended_qmi_lte_bands_expected_size * sizeof (guint64) + ); +} + +static void +test_mm_bands_to_qmi_cdma_generic (void) +{ + g_autoptr(GArray) mm_bands_arr = NULL; + static const MMModemBand mm_bands[] = { + MM_MODEM_BAND_CDMA_BC0, MM_MODEM_BAND_CDMA_BC3, MM_MODEM_BAND_CDMA_BC12, MM_MODEM_BAND_CDMA_BC14, + MM_MODEM_BAND_CDMA_BC17, MM_MODEM_BAND_CDMA_BC19, + }; + QmiNasBandPreference nas_bands_preference; + QmiNasBandPreference nas_bands_preference_expected; + /* Not needed for this test, but mm_modem_bands_to_qmi_band_preference does not check for NULL */ + QmiNasLteBandPreference nas_lte_bands_preference; + + mm_bands_arr = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (mm_bands)); + g_array_append_vals (mm_bands_arr, &mm_bands, G_N_ELEMENTS (mm_bands)); + nas_bands_preference_expected = ( + QMI_NAS_BAND_PREFERENCE_BC_0_A_SYSTEM | QMI_NAS_BAND_PREFERENCE_BC_0_B_SYSTEM | + QMI_NAS_BAND_PREFERENCE_BC_3_A_SYSTEM | QMI_NAS_BAND_PREFERENCE_BC_12 | + QMI_NAS_BAND_PREFERENCE_BC_14 | QMI_NAS_BAND_PREFERENCE_BC_17 | + QMI_NAS_BAND_PREFERENCE_BC_19 + ); + + mm_modem_bands_to_qmi_band_preference ( + mm_bands_arr, + &nas_bands_preference, + &nas_lte_bands_preference, + NULL, + 0, + NULL, + 0, + NULL + ); + + g_assert_true (nas_bands_preference == nas_bands_preference_expected); +} + /*****************************************************************************/ int main (int argc, char **argv) @@ -2007,5 +2241,12 @@ int main (int argc, char **argv) g_test_add_func ("/MM/qmi/registration-state-from-system-info/4g/eps-home", test_registration_state_from_qmi_system_info_4g_eps_home); g_test_add_func ("/MM/qmi/registration-state-from-system-info/5g/5gs-home", test_registration_state_from_qmi_system_info_5g_5gs_home); + g_test_add_func ("/MM/qmi/supported-bands/eutran/telit/fn990", test_supported_bands_eutran_telit_fn990); + g_test_add_func ("/MM/qmi/supported-bands/eutran/telit/fn990-b106", test_supported_bands_eutran_telit_fn990_b106); + g_test_add_func ("/MM/qmi/supported-bands/cdma/generic", test_supported_bands_cdma_generic); + g_test_add_func ("/MM/qmi/mm-bands-to-qmi/eutran/telit/fn990", test_mm_bands_to_qmi_eutran_telit_fn990); + g_test_add_func ("/MM/qmi/mm-bands-to-qmi/eutran/telit/fn990-b106", test_mm_bands_to_qmi_eutran_telit_fn990_b106); + g_test_add_func ("/MM/qmi/mm-bands-to-qmi/cdma/generic", test_mm_bands_to_qmi_cdma_generic); + return g_test_run (); }