diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-08-08 14:05:21 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-08-21 17:02:39 +0000 |
commit | 142f1d0360860ebecaa441b0431e37b1adf63751 (patch) | |
tree | 1c997ac595ca3d45e4608b1fbe367123872925e5 | |
parent | 69ca442dd42bdc56ba664153afd630f91513c98e (diff) | |
download | ModemManager-142f1d0360860ebecaa441b0431e37b1adf63751.tar.gz |
xmm: new common XACT=? parser for Intel XMM based devices
-rw-r--r-- | plugins/Makefile.am | 26 | ||||
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.c | 340 | ||||
-rw-r--r-- | plugins/xmm/mm-modem-helpers-xmm.h | 28 | ||||
-rw-r--r-- | plugins/xmm/tests/test-modem-helpers-xmm.c | 210 |
4 files changed, 604 insertions, 0 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 634452515..f17dee47d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -225,6 +225,32 @@ NOVATEL_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/novatel NOVATEL_COMMON_LIBADD_FLAGS = $(builddir)/libmm-utils-novatel.la ################################################################################ +# common xmm support +################################################################################ + +noinst_LTLIBRARIES += libhelpers-xmm.la +libhelpers_xmm_la_SOURCES = \ + xmm/mm-modem-helpers-xmm.c \ + xmm/mm-modem-helpers-xmm.h \ + $(NULL) + +noinst_PROGRAMS += test-modem-helpers-xmm +test_modem_helpers_xmm_SOURCES = \ + xmm/tests/test-modem-helpers-xmm.c \ + $(NULL) +test_modem_helpers_xmm_CPPFLAGS = \ + -I$(top_srcdir)/plugins/xmm \ + $(NULL) +test_modem_helpers_xmm_LDADD = \ + $(builddir)/libhelpers-xmm.la \ + $(top_builddir)/src/libhelpers.la \ + $(top_builddir)/libmm-glib/libmm-glib.la \ + $(NULL) + +XMM_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/xmm +XMM_COMMON_LIBADD_FLAGS = $(builddir)/libhelpers-xmm.la + +################################################################################ # plugin: generic ################################################################################ diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c new file mode 100644 index 000000000..e403cb35c --- /dev/null +++ b/plugins/xmm/mm-modem-helpers-xmm.c @@ -0,0 +1,340 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include "mm-log.h" +#include "mm-modem-helpers.h" +#include "mm-modem-helpers-xmm.h" + +/*****************************************************************************/ +/* XACT common config */ + +typedef struct { + guint num; + MMModemBand band; +} XactBandConfig; + +static const XactBandConfig xact_band_config[] = { + /* GSM bands */ + { .num = 900, .band = MM_MODEM_BAND_EGSM }, + { .num = 1800, .band = MM_MODEM_BAND_DCS }, + { .num = 1900, .band = MM_MODEM_BAND_PCS }, + { .num = 850, .band = MM_MODEM_BAND_G850 }, + { .num = 450, .band = MM_MODEM_BAND_G450 }, + { .num = 480, .band = MM_MODEM_BAND_G480 }, + { .num = 750, .band = MM_MODEM_BAND_G750 }, + { .num = 380, .band = MM_MODEM_BAND_G380 }, + { .num = 410, .band = MM_MODEM_BAND_G410 }, + { .num = 710, .band = MM_MODEM_BAND_G710 }, + { .num = 810, .band = MM_MODEM_BAND_G810 }, + /* UMTS bands */ + { .num = 1, .band = MM_MODEM_BAND_UTRAN_1 }, + { .num = 2, .band = MM_MODEM_BAND_UTRAN_2 }, + { .num = 3, .band = MM_MODEM_BAND_UTRAN_3 }, + { .num = 4, .band = MM_MODEM_BAND_UTRAN_4 }, + { .num = 5, .band = MM_MODEM_BAND_UTRAN_5 }, + { .num = 6, .band = MM_MODEM_BAND_UTRAN_6 }, + { .num = 7, .band = MM_MODEM_BAND_UTRAN_7 }, + { .num = 8, .band = MM_MODEM_BAND_UTRAN_8 }, + { .num = 9, .band = MM_MODEM_BAND_UTRAN_9 }, + { .num = 10, .band = MM_MODEM_BAND_UTRAN_10 }, + { .num = 11, .band = MM_MODEM_BAND_UTRAN_11 }, + { .num = 12, .band = MM_MODEM_BAND_UTRAN_12 }, + { .num = 13, .band = MM_MODEM_BAND_UTRAN_13 }, + { .num = 14, .band = MM_MODEM_BAND_UTRAN_14 }, + { .num = 19, .band = MM_MODEM_BAND_UTRAN_19 }, + { .num = 20, .band = MM_MODEM_BAND_UTRAN_20 }, + { .num = 21, .band = MM_MODEM_BAND_UTRAN_21 }, + { .num = 22, .band = MM_MODEM_BAND_UTRAN_22 }, + { .num = 25, .band = MM_MODEM_BAND_UTRAN_25 }, + /* LTE bands */ + { .num = 101, .band = MM_MODEM_BAND_EUTRAN_1 }, + { .num = 102, .band = MM_MODEM_BAND_EUTRAN_2 }, + { .num = 103, .band = MM_MODEM_BAND_EUTRAN_3 }, + { .num = 104, .band = MM_MODEM_BAND_EUTRAN_4 }, + { .num = 105, .band = MM_MODEM_BAND_EUTRAN_5 }, + { .num = 106, .band = MM_MODEM_BAND_EUTRAN_6 }, + { .num = 107, .band = MM_MODEM_BAND_EUTRAN_7 }, + { .num = 108, .band = MM_MODEM_BAND_EUTRAN_8 }, + { .num = 109, .band = MM_MODEM_BAND_EUTRAN_9 }, + { .num = 110, .band = MM_MODEM_BAND_EUTRAN_10 }, + { .num = 111, .band = MM_MODEM_BAND_EUTRAN_11 }, + { .num = 112, .band = MM_MODEM_BAND_EUTRAN_12 }, + { .num = 113, .band = MM_MODEM_BAND_EUTRAN_13 }, + { .num = 114, .band = MM_MODEM_BAND_EUTRAN_14 }, + { .num = 117, .band = MM_MODEM_BAND_EUTRAN_17 }, + { .num = 118, .band = MM_MODEM_BAND_EUTRAN_18 }, + { .num = 119, .band = MM_MODEM_BAND_EUTRAN_19 }, + { .num = 120, .band = MM_MODEM_BAND_EUTRAN_20 }, + { .num = 121, .band = MM_MODEM_BAND_EUTRAN_21 }, + { .num = 122, .band = MM_MODEM_BAND_EUTRAN_22 }, + { .num = 123, .band = MM_MODEM_BAND_EUTRAN_23 }, + { .num = 124, .band = MM_MODEM_BAND_EUTRAN_24 }, + { .num = 125, .band = MM_MODEM_BAND_EUTRAN_25 }, + { .num = 126, .band = MM_MODEM_BAND_EUTRAN_26 }, + { .num = 127, .band = MM_MODEM_BAND_EUTRAN_27 }, + { .num = 128, .band = MM_MODEM_BAND_EUTRAN_28 }, + { .num = 129, .band = MM_MODEM_BAND_EUTRAN_29 }, + { .num = 130, .band = MM_MODEM_BAND_EUTRAN_30 }, + { .num = 131, .band = MM_MODEM_BAND_EUTRAN_31 }, + { .num = 132, .band = MM_MODEM_BAND_EUTRAN_32 }, + { .num = 133, .band = MM_MODEM_BAND_EUTRAN_33 }, + { .num = 134, .band = MM_MODEM_BAND_EUTRAN_34 }, + { .num = 135, .band = MM_MODEM_BAND_EUTRAN_35 }, + { .num = 136, .band = MM_MODEM_BAND_EUTRAN_36 }, + { .num = 137, .band = MM_MODEM_BAND_EUTRAN_37 }, + { .num = 138, .band = MM_MODEM_BAND_EUTRAN_38 }, + { .num = 139, .band = MM_MODEM_BAND_EUTRAN_39 }, + { .num = 140, .band = MM_MODEM_BAND_EUTRAN_40 }, + { .num = 141, .band = MM_MODEM_BAND_EUTRAN_41 }, + { .num = 142, .band = MM_MODEM_BAND_EUTRAN_42 }, + { .num = 143, .band = MM_MODEM_BAND_EUTRAN_43 }, + { .num = 144, .band = MM_MODEM_BAND_EUTRAN_44 }, + { .num = 145, .band = MM_MODEM_BAND_EUTRAN_45 }, + { .num = 146, .band = MM_MODEM_BAND_EUTRAN_46 }, + { .num = 147, .band = MM_MODEM_BAND_EUTRAN_47 }, + { .num = 148, .band = MM_MODEM_BAND_EUTRAN_48 }, + { .num = 149, .band = MM_MODEM_BAND_EUTRAN_49 }, + { .num = 150, .band = MM_MODEM_BAND_EUTRAN_50 }, + { .num = 151, .band = MM_MODEM_BAND_EUTRAN_51 }, + { .num = 152, .band = MM_MODEM_BAND_EUTRAN_52 }, + { .num = 153, .band = MM_MODEM_BAND_EUTRAN_53 }, + { .num = 154, .band = MM_MODEM_BAND_EUTRAN_54 }, + { .num = 155, .band = MM_MODEM_BAND_EUTRAN_55 }, + { .num = 156, .band = MM_MODEM_BAND_EUTRAN_56 }, + { .num = 157, .band = MM_MODEM_BAND_EUTRAN_57 }, + { .num = 158, .band = MM_MODEM_BAND_EUTRAN_58 }, + { .num = 159, .band = MM_MODEM_BAND_EUTRAN_59 }, + { .num = 160, .band = MM_MODEM_BAND_EUTRAN_60 }, + { .num = 161, .band = MM_MODEM_BAND_EUTRAN_61 }, + { .num = 162, .band = MM_MODEM_BAND_EUTRAN_62 }, + { .num = 163, .band = MM_MODEM_BAND_EUTRAN_63 }, + { .num = 164, .band = MM_MODEM_BAND_EUTRAN_64 }, + { .num = 165, .band = MM_MODEM_BAND_EUTRAN_65 }, + { .num = 166, .band = MM_MODEM_BAND_EUTRAN_66 }, +}; + +#define XACT_NUM_IS_BAND_2G(num) (num > 300) +#define XACT_NUM_IS_BAND_3G(num) (num < 100) +#define XACT_NUM_IS_BAND_4G(num) (num > 100 && num < 300) + +static MMModemBand +xact_num_to_band (guint num) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (xact_band_config); i++) { + if (num == xact_band_config[i].num) + return xact_band_config[i].band; + } + return MM_MODEM_BAND_UNKNOWN; +} + +/*****************************************************************************/ +/* XACT=? response parser */ + +/* Index of the array is the XMM-specific value */ +static const MMModemMode xmm_modes[] = { + ( MM_MODEM_MODE_2G ), + ( MM_MODEM_MODE_3G ), + ( MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_3G ), + ( MM_MODEM_MODE_3G | MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_4G ), + ( MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G ), +}; + +gboolean +mm_xmm_parse_xact_test_response (const gchar *response, + GArray **modes_out, + GArray **bands_out, + GError **error) +{ + GError *inner_error = NULL; + GArray *modes = NULL; + GArray *all_modes = NULL; + GArray *filtered = NULL; + GArray *supported = NULL; + GArray *preferred = NULL; + GArray *bands = NULL; + gchar **split = NULL; + guint i; + + MMModemModeCombination all = { + .allowed = MM_MODEM_MODE_NONE, + .preferred = MM_MODEM_MODE_NONE + }; + + g_assert (modes_out && bands_out); + + /* + * AT+XACT=? + * +XACT: (0-6),(0-2),0,1,2,4,5,8,101,102,103,104,105,107,108,111,... + */ + response = mm_strip_tag (response, "+XACT:"); + split = mm_split_string_groups (response); + + if (g_strv_length (split) < 3) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing fields"); + goto out; + } + + /* First group is list of supported modes */ + supported = mm_parse_uint_list (split[0], &inner_error); + if (inner_error) + goto out; + if (!supported) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing modes"); + goto out; + } + + /* Second group is list of possible preferred modes. + * For our purposes, the preferred list may be empty */ + preferred = mm_parse_uint_list (split[1], &inner_error); + if (inner_error) + goto out; + + /* Build array of modes */ + modes = g_array_new (FALSE, FALSE, sizeof (MMModemModeCombination)); + + for (i = 0; i < supported->len; i++) { + guint supported_value; + MMModemModeCombination combination; + guint j; + + supported_value = g_array_index (supported, guint, i); + + if (supported_value >= G_N_ELEMENTS (xmm_modes)) { + mm_warn ("Unexpected AcT supported value: %u", supported_value); + continue; + } + + /* Combination without any preferred */ + combination.allowed = xmm_modes[supported_value]; + combination.preferred = MM_MODEM_MODE_NONE; + g_array_append_val (modes, combination); + + if (mm_count_bits_set (combination.allowed) == 1) + continue; + + if (!preferred) + continue; + + for (j = 0; j < preferred->len; j++) { + guint preferred_value; + + preferred_value = g_array_index (preferred, guint, j); + if (preferred_value >= G_N_ELEMENTS (xmm_modes)) { + mm_warn ("Unexpected AcT preferred value: %u", preferred_value); + continue; + } + combination.preferred = xmm_modes[preferred_value]; + if (mm_count_bits_set (combination.preferred) != 1) { + mm_warn ("AcT preferred value should be a single AcT: %u", preferred_value); + continue; + } + if (!(combination.allowed & combination.preferred)) + continue; + g_array_append_val (modes, combination); + } + } + + if (modes->len == 0) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No modes list built from +XACT=? response"); + goto out; + } + + /* Build array of bands */ + bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand)); + + /* + * The next element at index 2 may be '0'. We will just treat that field as + * any other band field as '0' isn't a supported band, we'll just ignore it. + */ + for (i = 2; split[i]; i++) { + MMModemBand band; + guint num; + + if (!mm_get_uint_from_str (split[i], &num)) { + mm_warn ("Unexpected band value: %s", split[i]); + continue; + } + + if (num == 0) + continue; + + band = xact_num_to_band (num); + if (band == MM_MODEM_BAND_UNKNOWN) { + mm_warn ("Unsupported band value: %s", split[i]); + continue; + } + + g_array_append_val (bands, band); + + if (XACT_NUM_IS_BAND_2G (num)) + all.allowed |= MM_MODEM_MODE_2G; + if (XACT_NUM_IS_BAND_3G (num)) + all.allowed |= MM_MODEM_MODE_3G; + if (XACT_NUM_IS_BAND_4G (num)) + all.allowed |= MM_MODEM_MODE_4G; + } + + if (bands->len == 0) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No bands list built from +XACT=? response"); + goto out; + } + + /* AT+XACT lies about the supported modes, e.g. it may report 2G supported + * for 3G+4G only devices. So, filter out unsupported modes based on the + * supported bands */ + all_modes = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1); + g_array_append_val (all_modes, all); + + filtered = mm_filter_supported_modes (all_modes, modes); + if (!filtered || filtered->len == 0) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Empty supported mode list after frequency band filtering"); + goto out; + } + + /* success */ + +out: + if (modes) + g_array_unref (modes); + if (all_modes) + g_array_unref (all_modes); + if (supported) + g_array_unref (supported); + if (preferred) + g_array_unref (preferred); + g_strfreev (split); + + if (inner_error) { + if (filtered) + g_array_unref (filtered); + if (bands) + g_array_unref (bands); + g_propagate_error (error, inner_error); + return FALSE; + } + + g_assert (filtered); + *modes_out = filtered; + g_assert (bands); + *bands_out = bands; + return TRUE; +} diff --git a/plugins/xmm/mm-modem-helpers-xmm.h b/plugins/xmm/mm-modem-helpers-xmm.h new file mode 100644 index 000000000..46cb9b5ed --- /dev/null +++ b/plugins/xmm/mm-modem-helpers-xmm.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es> + */ + +#ifndef MM_MODEM_HELPERS_XMM_H +#define MM_MODEM_HELPERS_XMM_H + +#include <glib.h> +#include <ModemManager.h> + +/* AT+XACT=? response parser */ +gboolean mm_xmm_parse_xact_test_response (const gchar *response, + GArray **modes_out, + GArray **bands_out, + GError **error); + +#endif /* MM_MODEM_HELPERS_XMM_H */ diff --git a/plugins/xmm/tests/test-modem-helpers-xmm.c b/plugins/xmm/tests/test-modem-helpers-xmm.c new file mode 100644 index 000000000..c402c23ca --- /dev/null +++ b/plugins/xmm/tests/test-modem-helpers-xmm.c @@ -0,0 +1,210 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <glib.h> +#include <glib-object.h> +#include <locale.h> + +#include <ModemManager.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-log.h" +#include "mm-modem-helpers.h" +#include "mm-modem-helpers-xmm.h" + +/*****************************************************************************/ +/* Test XACT=? responses */ + +static void +validate_xact_test_response (const gchar *response, + const MMModemModeCombination *expected_modes, + guint n_expected_modes, + const MMModemBand *expected_bands, + guint n_expected_bands) +{ + GError *error = NULL; + GArray *modes = NULL; + GArray *bands = NULL; + gboolean ret; + guint i; + + ret = mm_xmm_parse_xact_test_response (response, &modes, &bands, &error); + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpuint (modes->len, ==, n_expected_modes); + for (i = 0; i < modes->len; i++) { + MMModemModeCombination mode; + guint j; + gboolean found = FALSE; + + mode = g_array_index (modes, MMModemModeCombination, i); + for (j = 0; !found && j < n_expected_modes; j++) + found = (mode.allowed == expected_modes[j].allowed && mode.preferred == expected_modes[j].preferred); + g_assert (found); + } + g_array_unref (modes); + + g_assert_cmpuint (bands->len, ==, n_expected_bands); + for (i = 0; i < bands->len; i++) { + MMModemBand band; + guint j; + gboolean found = FALSE; + + band = g_array_index (bands, MMModemBand, i); + for (j = 0; !found && j < n_expected_bands; j++) + found = (band == expected_bands[j]); + g_assert (found); + } + g_array_unref (bands); +} + +static void +test_xact_test_4g_only (void) +{ + const gchar *response = + "+XACT: " + "(0-6),(0-2),0," + "101,102,103,104,105,107,108,111,112,113,117,118,119,120,121,126,128,129,130,138,139,140,141,166"; + + static const MMModemModeCombination expected_modes[] = { + { MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + }; + + static const MMModemBand expected_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_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, + MM_MODEM_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_21, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, MM_MODEM_BAND_EUTRAN_38, + MM_MODEM_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_66 + }; + + /* NOTE: 2G and 3G modes are reported in XACT but no 2G or 3G frequencies supported */ + validate_xact_test_response (response, + expected_modes, G_N_ELEMENTS (expected_modes), + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +static void +test_xact_test_3g_4g (void) +{ + const gchar *response = + "+XACT: " + "(0-6),(0-2),0," + "1,2,4,5,8," + "101,102,103,104,105,107,108,111,112,113,117,118,119,120,121,126,128,129,130,138,139,140,141,166"; + + static const MMModemModeCombination expected_modes[] = { + { MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + }; + + static const MMModemBand expected_bands[] = { + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + 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_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, + MM_MODEM_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_21, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, MM_MODEM_BAND_EUTRAN_38, + MM_MODEM_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_66 + }; + + /* NOTE: 2G modes are reported in XACT but no 2G frequencies supported */ + validate_xact_test_response (response, + expected_modes, G_N_ELEMENTS (expected_modes), + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +static void +test_xact_test_2g_3g_4g (void) +{ + const gchar *response = + "+XACT: " + "(0-6),(0-2),0," + "900,1800,1900,850," + "1,2,4,5,8," + "101,102,103,104,105,107,108,111,112,113,117,118,119,120,121,126,128,129,130,138,139,140,141,166"; + + static const MMModemModeCombination expected_modes[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_2G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_3G }, + { MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G, MM_MODEM_MODE_4G }, + }; + + static const MMModemBand expected_bands[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, MM_MODEM_BAND_G850, + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_UTRAN_8, + 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_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_11, MM_MODEM_BAND_EUTRAN_12, MM_MODEM_BAND_EUTRAN_13, + MM_MODEM_BAND_EUTRAN_17, MM_MODEM_BAND_EUTRAN_18, MM_MODEM_BAND_EUTRAN_19, MM_MODEM_BAND_EUTRAN_20, MM_MODEM_BAND_EUTRAN_21, + MM_MODEM_BAND_EUTRAN_26, MM_MODEM_BAND_EUTRAN_28, MM_MODEM_BAND_EUTRAN_29, MM_MODEM_BAND_EUTRAN_30, MM_MODEM_BAND_EUTRAN_38, + MM_MODEM_BAND_EUTRAN_39, MM_MODEM_BAND_EUTRAN_40, MM_MODEM_BAND_EUTRAN_41, MM_MODEM_BAND_EUTRAN_66 + }; + + validate_xact_test_response (response, + expected_modes, G_N_ELEMENTS (expected_modes), + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +/*****************************************************************************/ + +void +_mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) +{ +#if defined ENABLE_TEST_MESSAGE_TRACES + /* Dummy log function */ + va_list args; + gchar *msg; + + va_start (args, fmt); + msg = g_strdup_vprintf (fmt, args); + va_end (args); + g_print ("%s\n", msg); + g_free (msg); +#endif +} + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/MM/xmm/xact/test/4g-only", test_xact_test_4g_only); + g_test_add_func ("/MM/xmm/xact/test/3g-4g", test_xact_test_3g_4g); + g_test_add_func ("/MM/xmm/xact/test/2g-3g-4g", test_xact_test_2g_3g_4g); + + return g_test_run (); +} |