diff options
Diffstat (limited to 'src/plugins/ublox/tests/test-modem-helpers-ublox.c')
-rw-r--r-- | src/plugins/ublox/tests/test-modem-helpers-ublox.c | 1026 |
1 files changed, 1026 insertions, 0 deletions
diff --git a/src/plugins/ublox/tests/test-modem-helpers-ublox.c b/src/plugins/ublox/tests/test-modem-helpers-ublox.c new file mode 100644 index 00000000..2d662877 --- /dev/null +++ b/src/plugins/ublox/tests/test-modem-helpers-ublox.c @@ -0,0 +1,1026 @@ +/* -*- 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) 2016 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <glib.h> +#include <glib-object.h> +#include <locale.h> +#include <arpa/inet.h> + +#include <ModemManager.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-log-test.h" +#include "mm-modem-helpers.h" +#include "mm-modem-helpers-ublox.h" + +#include "test-helpers.h" + +/*****************************************************************************/ +/* Test +UPINCNT responses */ + +typedef struct { + const gchar *str; + guint pin_attempts; + guint pin2_attempts; + guint puk_attempts; + guint puk2_attempts; +} UpinCntResponseTest; + +static const UpinCntResponseTest upincnt_response_tests[] = { + { .str = "+UPINCNT: 3,3,10,10\r\n", + .pin_attempts = 3, + .pin2_attempts = 3, + .puk_attempts = 10, + .puk2_attempts = 10 + }, + { .str = "+UPINCNT: 0,3,5,5\r\n", + .pin_attempts = 0, + .pin2_attempts = 3, + .puk_attempts = 5, + .puk2_attempts = 5 + }, + { .str = "+UPINCNT: 0,0,0,0\r\n", + .pin_attempts = 0, + .pin2_attempts = 0, + .puk_attempts = 0, + .puk2_attempts = 0 + }, +}; + +static void +test_upincnt_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (upincnt_response_tests); i++) { + GError *error = NULL; + gboolean success; + guint pin_attempts = G_MAXUINT; + guint pin2_attempts = G_MAXUINT; + guint puk_attempts = G_MAXUINT; + guint puk2_attempts = G_MAXUINT; + + success = mm_ublox_parse_upincnt_response (upincnt_response_tests[i].str, + &pin_attempts, &pin2_attempts, + &puk_attempts, &puk2_attempts, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (upincnt_response_tests[i].pin_attempts, ==, pin_attempts); + g_assert_cmpuint (upincnt_response_tests[i].pin2_attempts, ==, pin2_attempts); + g_assert_cmpuint (upincnt_response_tests[i].puk_attempts, ==, puk_attempts); + g_assert_cmpuint (upincnt_response_tests[i].puk2_attempts, ==, puk2_attempts); + } +} + +/*****************************************************************************/ +/* Test UUSBCONF? responses */ + +typedef struct { + const gchar *str; + MMUbloxUsbProfile profile; +} UusbconfResponseTest; + +static const UusbconfResponseTest uusbconf_response_tests[] = { + { + .str = "+UUSBCONF: 3,\"RNDIS\",,\"0x1146\"\r\n", + .profile = MM_UBLOX_USB_PROFILE_RNDIS + }, + { + .str = "+UUSBCONF: 2,\"ECM\",,\"0x1143\"\r\n", + .profile = MM_UBLOX_USB_PROFILE_ECM + }, + { + .str = "+UUSBCONF: 0,\"\",,\"0x1141\"\r\n", + .profile = MM_UBLOX_USB_PROFILE_BACK_COMPATIBLE + }, +}; + +static void +test_uusbconf_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (uusbconf_response_tests); i++) { + MMUbloxUsbProfile profile = MM_UBLOX_USB_PROFILE_UNKNOWN; + GError *error = NULL; + gboolean success; + + success = mm_ublox_parse_uusbconf_response (uusbconf_response_tests[i].str, &profile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (uusbconf_response_tests[i].profile, ==, profile); + } +} + +/*****************************************************************************/ +/* Test UBMCONF? responses */ + +typedef struct { + const gchar *str; + MMUbloxNetworkingMode mode; +} UbmconfResponseTest; + +static const UbmconfResponseTest ubmconf_response_tests[] = { + { + .str = "+UBMCONF: 1\r\n", + .mode = MM_UBLOX_NETWORKING_MODE_ROUTER + }, + { + .str = "+UBMCONF: 2\r\n", + .mode = MM_UBLOX_NETWORKING_MODE_BRIDGE + }, +}; + +static void +test_ubmconf_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (ubmconf_response_tests); i++) { + MMUbloxNetworkingMode mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; + GError *error = NULL; + gboolean success; + + success = mm_ublox_parse_ubmconf_response (ubmconf_response_tests[i].str, &mode, &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (ubmconf_response_tests[i].mode, ==, mode); + } +} + +/*****************************************************************************/ +/* Test UIPADDR=N responses */ + +typedef struct { + const gchar *str; + guint cid; + const gchar *if_name; + const gchar *ipv4_address; + const gchar *ipv4_subnet; + const gchar *ipv6_global_address; + const gchar *ipv6_link_local_address; +} UipaddrResponseTest; + +static const UipaddrResponseTest uipaddr_response_tests[] = { + { + .str = "+UIPADDR: 1,\"ccinet0\",\"5.168.120.13\",\"255.255.255.0\",\"\",\"\"", + .cid = 1, + .if_name = "ccinet0", + .ipv4_address = "5.168.120.13", + .ipv4_subnet = "255.255.255.0", + }, + { + .str = "+UIPADDR: 2,\"ccinet1\",\"\",\"\",\"2001::1:200:FF:FE00:0/64\",\"FE80::200:FF:FE00:0/64\"", + .cid = 2, + .if_name = "ccinet1", + .ipv6_global_address = "2001::1:200:FF:FE00:0/64", + .ipv6_link_local_address = "FE80::200:FF:FE00:0/64", + }, + { + .str = "+UIPADDR: 3,\"ccinet2\",\"5.10.100.2\",\"255.255.255.0\",\"2001::1:200:FF:FE00:0/64\",\"FE80::200:FF:FE00:0/64\"", + .cid = 3, + .if_name = "ccinet2", + .ipv4_address = "5.10.100.2", + .ipv4_subnet = "255.255.255.0", + .ipv6_global_address = "2001::1:200:FF:FE00:0/64", + .ipv6_link_local_address = "FE80::200:FF:FE00:0/64", + }, +}; + +static void +test_uipaddr_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (uipaddr_response_tests); i++) { + GError *error = NULL; + gboolean success; + guint cid = G_MAXUINT; + gchar *if_name = NULL; + gchar *ipv4_address = NULL; + gchar *ipv4_subnet = NULL; + gchar *ipv6_global_address = NULL; + gchar *ipv6_link_local_address = NULL; + + success = mm_ublox_parse_uipaddr_response (uipaddr_response_tests[i].str, + &cid, + &if_name, + &ipv4_address, + &ipv4_subnet, + &ipv6_global_address, + &ipv6_link_local_address, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (uipaddr_response_tests[i].cid, ==, cid); + g_assert_cmpstr (uipaddr_response_tests[i].if_name, ==, if_name); + g_assert_cmpstr (uipaddr_response_tests[i].ipv4_address, ==, ipv4_address); + g_assert_cmpstr (uipaddr_response_tests[i].ipv4_subnet, ==, ipv4_subnet); + g_assert_cmpstr (uipaddr_response_tests[i].ipv6_global_address, ==, ipv6_global_address); + g_assert_cmpstr (uipaddr_response_tests[i].ipv6_link_local_address, ==, ipv6_link_local_address); + + g_free (if_name); + g_free (ipv4_address); + g_free (ipv4_subnet); + g_free (ipv6_global_address); + g_free (ipv6_link_local_address); + } +} + +/*****************************************************************************/ +/* Test CFUN? response */ + +typedef struct { + const gchar *str; + MMModemPowerState state; +} CfunQueryTest; + +static const CfunQueryTest cfun_query_tests[] = { + { "+CFUN: 1", MM_MODEM_POWER_STATE_ON }, + { "+CFUN: 1,0", MM_MODEM_POWER_STATE_ON }, + { "+CFUN: 0", MM_MODEM_POWER_STATE_LOW }, + { "+CFUN: 0,0", MM_MODEM_POWER_STATE_LOW }, + { "+CFUN: 4", MM_MODEM_POWER_STATE_LOW }, + { "+CFUN: 4,0", MM_MODEM_POWER_STATE_LOW }, + { "+CFUN: 19", MM_MODEM_POWER_STATE_LOW }, + { "+CFUN: 19,0", MM_MODEM_POWER_STATE_LOW }, +}; + +static void +test_cfun_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (cfun_query_tests); i++) { + GError *error = NULL; + gboolean success; + MMModemPowerState state = MM_MODEM_POWER_STATE_UNKNOWN; + + success = mm_ublox_parse_cfun_response (cfun_query_tests[i].str, &state, &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (cfun_query_tests[i].state, ==, state); + } +} + +/*****************************************************************************/ +/* Test URAT=? responses and model based filtering */ + +static void +compare_combinations (const gchar *response, + const gchar *model, + const MMModemModeCombination *expected_combinations, + guint n_expected_combinations) +{ + GArray *combinations; + GError *error = NULL; + guint i; + + combinations = mm_ublox_parse_urat_test_response (response, NULL, &error); + g_assert_no_error (error); + g_assert (combinations); + + combinations = mm_ublox_filter_supported_modes (model, combinations, NULL, &error); + g_assert_no_error (error); + g_assert (combinations); + + g_assert_cmpuint (combinations->len, ==, n_expected_combinations); + + for (i = 0; i < combinations->len; i++) { + MMModemModeCombination combination; + guint j; + gboolean found = FALSE; + + combination = g_array_index (combinations, MMModemModeCombination, i); + for (j = 0; !found && j < n_expected_combinations; j++) + found = (combination.allowed == expected_combinations[j].allowed && + combination.preferred == expected_combinations[j].preferred); + g_assert (found); + } + + g_array_unref (combinations); +} + +static void +test_urat_test_response_2g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE } + }; + + compare_combinations ("+URAT: 0", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: 0,0", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0),(0)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_urat_test_response_2g3g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G, 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 }, + }; + + compare_combinations ("+URAT: (0,1,2),(0,2)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0-2),(0,2)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_urat_test_response_2g3g4g (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { 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 }, + }; + + compare_combinations ("+URAT: (0,1,2,3,4,5,6),(0,2,3)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); + compare_combinations ("+URAT: (0-6),(0,2,3)", NULL, expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_mode_filtering_toby_l201 (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { 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 }, + }; + + compare_combinations ("+URAT: (0-6),(0,2,3)", "TOBY-L201", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_mode_filtering_lisa_u200 (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE }, + { MM_MODEM_MODE_3G, 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 }, + }; + + compare_combinations ("+URAT: (0-6),(0,2,3)", "LISA-U200", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +static void +test_mode_filtering_sara_u280 (void) +{ + static const MMModemModeCombination expected_combinations[] = { + { MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE }, + }; + + compare_combinations ("+URAT: (0-6),(0,2,3)", "SARA-U280", expected_combinations, G_N_ELEMENTS (expected_combinations)); +} + +/*****************************************************************************/ +/* URAT? response parser and URAT=X command builder */ + +typedef struct { + const gchar *command; + const gchar *response; + MMModemMode allowed; + MMModemMode preferred; +} UratTest; + +static const UratTest urat_tests[] = { + { + .command = "+URAT=1,2", + .response = "+URAT: 1,2\r\n", + .allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), + .preferred = MM_MODEM_MODE_3G, + }, + { + .command = "+URAT=4,0", + .response = "+URAT: 4,0\r\n", + .allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), + .preferred = MM_MODEM_MODE_2G, + }, + { + .command = "+URAT=0", + .response = "+URAT: 0\r\n", + .allowed = MM_MODEM_MODE_2G, + .preferred = MM_MODEM_MODE_NONE, + }, + { + .command = "+URAT=6", + .response = "+URAT: 6\r\n", + .allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), + .preferred = MM_MODEM_MODE_NONE, + }, +}; + +static void +test_urat_read_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (urat_tests); i++) { + MMModemMode allowed = MM_MODEM_MODE_NONE; + MMModemMode preferred = MM_MODEM_MODE_NONE; + GError *error = NULL; + gboolean success; + + success = mm_ublox_parse_urat_read_response (urat_tests[i].response, NULL, + &allowed, &preferred, &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (urat_tests[i].allowed, ==, allowed); + g_assert_cmpuint (urat_tests[i].preferred, ==, preferred); + } +} + +static void +test_urat_write_command (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (urat_tests); i++) { + gchar *command; + GError *error = NULL; + + command = mm_ublox_build_urat_set_command (urat_tests[i].allowed, urat_tests[i].preferred, &error); + g_assert_no_error (error); + g_assert_cmpstr (command, ==, urat_tests[i].command); + g_free (command); + } +} + +/*****************************************************************************/ +/* Test +UBANDSEL? response parser */ + +static void +common_validate_ubandsel_response (const gchar *str, + const MMModemBand *expected_bands, + const gchar *model, + guint n_expected_bands) +{ + GError *error = NULL; + GArray *bands; + + bands = mm_ublox_parse_ubandsel_response (str, model, NULL, &error); + g_assert_no_error (error); + g_assert (bands); + + mm_test_helpers_compare_bands (bands, expected_bands, n_expected_bands); + g_array_unref (bands); +} + +static void +test_ubandsel_response_four (void) +{ + const MMModemBand expected_bands[] = { + /* 700 */ MM_MODEM_BAND_EUTRAN_4, + /* 1700 */ MM_MODEM_BAND_EUTRAN_13 + }; + + common_validate_ubandsel_response ("+UBANDSEL: 700,1700\r\n", expected_bands, "LARA-R204", G_N_ELEMENTS (expected_bands)); +} + +static void +test_ubandsel_response_three (void) +{ + const MMModemBand expected_bands[] = { + /* 800 */ MM_MODEM_BAND_UTRAN_6, + /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, + /* 900 */ MM_MODEM_BAND_EGSM, MM_MODEM_BAND_UTRAN_8, + /* 1900 */ MM_MODEM_BAND_PCS, MM_MODEM_BAND_UTRAN_2, + /* 2100 */ MM_MODEM_BAND_UTRAN_1 + }; + + common_validate_ubandsel_response ("+UBANDSEL: 800,850,900,1900,2100\r\n", expected_bands, "SARA-U201", G_N_ELEMENTS (expected_bands)); +} + +static void +test_ubandsel_response_two (void) +{ + const MMModemBand expected_bands[] = { + /* 850 */ MM_MODEM_BAND_G850, + /* 900 */ MM_MODEM_BAND_EGSM, + /* 1800 */ MM_MODEM_BAND_DCS, + /* 1900 */ MM_MODEM_BAND_PCS + }; + + common_validate_ubandsel_response ("+UBANDSEL: 850,900,1800,1900\r\n", expected_bands, "SARA-G310", G_N_ELEMENTS (expected_bands)); +} + +static void +test_ubandsel_response_one (void) +{ + const MMModemBand expected_bands[] = { + /* 850 */ MM_MODEM_BAND_G850, MM_MODEM_BAND_UTRAN_5, MM_MODEM_BAND_EUTRAN_5, + /* 1700 */ MM_MODEM_BAND_EUTRAN_4, + /* 1900 */ MM_MODEM_BAND_PCS, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_EUTRAN_2 + }; + + common_validate_ubandsel_response ("+UBANDSEL: 850,1700,1900\r\n", expected_bands, "TOBY-R200", G_N_ELEMENTS (expected_bands)); +} + +/*****************************************************************************/ +/* +UBANDSEL=x command builder */ + +static void +common_validate_ubandsel_request (const MMModemBand *bands, + guint n_bands, + const gchar *model, + const gchar *expected_request) +{ + GError *error = NULL; + GArray *bands_array; + gchar *request; + + bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), n_bands); + g_array_append_vals (bands_array, bands, n_bands); + + request = mm_ublox_build_ubandsel_set_command (bands_array, model, &error); + g_assert_no_error (error); + g_assert (request); + + g_assert_cmpstr (request, ==, expected_request); + + g_array_unref (bands_array); + g_free (request); +} + +static void +test_ubandsel_request_any (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_ANY + }; + + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "TOBY-R200", "+UBANDSEL=0"); +} + +static void +test_ubandsel_request_2g (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS + }; + + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "SARA-G310", "+UBANDSEL=850,900,1800,1900"); +} + +static void +test_ubandsel_request_1800 (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_DCS, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_EUTRAN_3 + }; + + common_validate_ubandsel_request (bands, G_N_ELEMENTS (bands), "TOBY-R200", "+UBANDSEL=1800"); +} + +/*****************************************************************************/ +/* Test +UACT? response parser */ + +static void +common_validate_uact_response (const gchar *str, + const MMModemBand *expected_bands, + guint n_expected_bands) +{ + GError *error = NULL; + GArray *bands; + + bands = mm_ublox_parse_uact_response (str, &error); + + if (n_expected_bands > 0) { + g_assert (bands); + g_assert_no_error (error); + mm_test_helpers_compare_bands (bands, expected_bands, n_expected_bands); + g_array_unref (bands); + } else { + g_assert (!bands); + g_assert (error); + g_error_free (error); + } +} + +static void +test_uact_response_empty_list (void) +{ + common_validate_uact_response ("", NULL, 0); + common_validate_uact_response ("+UACT: ,,,\r\n", NULL, 0); +} + +static void +test_uact_response_2g (void) +{ + const MMModemBand expected_bands[] = { + MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, + }; + + common_validate_uact_response ("+UACT: ,,,900,1800,1900,850\r\n", + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +static void +test_uact_response_2g3g (void) +{ + const MMModemBand expected_bands[] = { + MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, + MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_7, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_9, + }; + + common_validate_uact_response ("+UACT: ,,,900,1800,1900,850,1,2,3,4,5,6,7,8,9\r\n", + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +static void +test_uact_response_2g3g4g (void) +{ + const MMModemBand expected_bands[] = { + MM_MODEM_BAND_G850, MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_2, MM_MODEM_BAND_UTRAN_3, MM_MODEM_BAND_UTRAN_4, MM_MODEM_BAND_UTRAN_5, + MM_MODEM_BAND_UTRAN_6, MM_MODEM_BAND_UTRAN_7, MM_MODEM_BAND_UTRAN_8, MM_MODEM_BAND_UTRAN_9, + 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_9, + }; + + common_validate_uact_response ("+UACT: ,,,900,1800,1900,850,1,2,3,4,5,6,7,8,9,101,102,103,104,105,106,107,108,109\r\n", + expected_bands, G_N_ELEMENTS (expected_bands)); +} + +/*****************************************************************************/ +/* Test +UACT=? test parser */ + +static void +common_validate_uact_test (const gchar *str, + const MMModemBand *expected_bands_2g, + guint n_expected_bands_2g, + const MMModemBand *expected_bands_3g, + guint n_expected_bands_3g, + const MMModemBand *expected_bands_4g, + guint n_expected_bands_4g) +{ + GError *error = NULL; + gboolean result; + GArray *bands_2g = NULL; + GArray *bands_3g = NULL; + GArray *bands_4g = NULL; + + result = mm_ublox_parse_uact_test (str, NULL, &bands_2g, &bands_3g, &bands_4g, &error); + g_assert_no_error (error); + g_assert (result); + + mm_test_helpers_compare_bands (bands_2g, expected_bands_2g, n_expected_bands_2g); + if (bands_2g) + g_array_unref (bands_2g); + mm_test_helpers_compare_bands (bands_3g, expected_bands_3g, n_expected_bands_3g); + if (bands_3g) + g_array_unref (bands_3g); + mm_test_helpers_compare_bands (bands_4g, expected_bands_4g, n_expected_bands_4g); + if (bands_4g) + g_array_unref (bands_4g); +} + +static void +test_uact_test_2g (void) +{ + const MMModemBand expected_bands_2g[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS + }; + + common_validate_uact_test ("+UACT: ,,,(900,1800)\r\n", + expected_bands_2g, G_N_ELEMENTS (expected_bands_2g), + NULL, 0, + NULL, 0); +} + +static void +test_uact_test_2g3g (void) +{ + const MMModemBand expected_bands_2g[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS + }; + const MMModemBand expected_bands_3g[] = { + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8 + }; + + common_validate_uact_test ("+UACT: ,,,(900,1800),(1,8)\r\n", + expected_bands_2g, G_N_ELEMENTS (expected_bands_2g), + expected_bands_3g, G_N_ELEMENTS (expected_bands_3g), + NULL, 0); +} + +static void +test_uact_test_2g3g4g (void) +{ + const MMModemBand expected_bands_2g[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS + }; + const MMModemBand expected_bands_3g[] = { + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8 + }; + const MMModemBand expected_bands_4g[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 + }; + + common_validate_uact_test ("+UACT: ,,,(900,1800),(1,8),(101,103,107,108,120)\r\n", + expected_bands_2g, G_N_ELEMENTS (expected_bands_2g), + expected_bands_3g, G_N_ELEMENTS (expected_bands_3g), + expected_bands_4g, G_N_ELEMENTS (expected_bands_4g)); +} + +static void +test_uact_test_2g3g4g_2 (void) +{ + const MMModemBand expected_bands_2g[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS + }; + const MMModemBand expected_bands_3g[] = { + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8 + }; + const MMModemBand expected_bands_4g[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 + }; + + common_validate_uact_test ("+UACT: ,,,(900,1800),(1,8),(101,103,107,108,120),(138)\r\n", + expected_bands_2g, G_N_ELEMENTS (expected_bands_2g), + expected_bands_3g, G_N_ELEMENTS (expected_bands_3g), + expected_bands_4g, G_N_ELEMENTS (expected_bands_4g)); +} + +/*****************************************************************************/ +/* +UACT=x command builder */ + +static void +common_validate_uact_request (const MMModemBand *bands, + guint n_bands, + const gchar *expected_request) +{ + GError *error = NULL; + GArray *bands_array; + gchar *request; + + bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), n_bands); + g_array_append_vals (bands_array, bands, n_bands); + + request = mm_ublox_build_uact_set_command (bands_array, &error); + g_assert_no_error (error); + g_assert (request); + + g_assert_cmpstr (request, ==, expected_request); + + g_array_unref (bands_array); + g_free (request); +} + +static void +test_uact_request_any (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_ANY + }; + + common_validate_uact_request (bands, G_N_ELEMENTS (bands), "+UACT=,,,0"); +} + +static void +test_uact_request_2g (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, + }; + + common_validate_uact_request (bands, G_N_ELEMENTS (bands), "+UACT=,,,900,1800"); +} + +static void +test_uact_request_3g (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_UTRAN_1, MM_MODEM_BAND_UTRAN_8, + }; + + common_validate_uact_request (bands, G_N_ELEMENTS (bands), "+UACT=,,,1,8"); +} + +static void +test_uact_request_4g (void) +{ + const MMModemBand bands[] = { + MM_MODEM_BAND_EUTRAN_1, MM_MODEM_BAND_EUTRAN_3, MM_MODEM_BAND_EUTRAN_7, MM_MODEM_BAND_EUTRAN_8, MM_MODEM_BAND_EUTRAN_20 + }; + + common_validate_uact_request (bands, G_N_ELEMENTS (bands), "+UACT=,,,101,103,107,108,120"); +} + +/*****************************************************************************/ +/* Test +UAUTHREQ=? responses */ + +static void +common_validate_uauthreq_test (const gchar *str, + MMUbloxBearerAllowedAuth expected_allowed_auths) +{ + GError *error = NULL; + MMUbloxBearerAllowedAuth allowed_auths; + + allowed_auths = mm_ublox_parse_uauthreq_test (str, NULL, &error); + g_assert_no_error (error); + g_assert_cmpuint (allowed_auths, ==, expected_allowed_auths); +} + +static void +test_uauthreq_tobyl4 (void) +{ + common_validate_uauthreq_test ("+UAUTHREQ: (1-4),(0-2),,", + (MM_UBLOX_BEARER_ALLOWED_AUTH_NONE | + MM_UBLOX_BEARER_ALLOWED_AUTH_PAP | + MM_UBLOX_BEARER_ALLOWED_AUTH_CHAP)); +} + +static void +test_uauthreq_with_auto (void) +{ + common_validate_uauthreq_test ("+UAUTHREQ: (1-4),(0-3),,", + (MM_UBLOX_BEARER_ALLOWED_AUTH_NONE | + MM_UBLOX_BEARER_ALLOWED_AUTH_PAP | + MM_UBLOX_BEARER_ALLOWED_AUTH_CHAP | + MM_UBLOX_BEARER_ALLOWED_AUTH_AUTO)); +} + +static void +test_uauthreq_less_fields (void) +{ + common_validate_uauthreq_test ("+UAUTHREQ: (1-4),(0-2)", + (MM_UBLOX_BEARER_ALLOWED_AUTH_NONE | + MM_UBLOX_BEARER_ALLOWED_AUTH_PAP | + MM_UBLOX_BEARER_ALLOWED_AUTH_CHAP)); +} + +/*****************************************************************************/ +/* Test +UGCNTRD responses */ + +typedef struct { + const gchar *str; + guint cid; + guint64 session_tx_bytes; + guint64 session_rx_bytes; + guint64 total_tx_bytes; + guint64 total_rx_bytes; +} UgcntrdResponseTest; + +static const UgcntrdResponseTest ugcntrd_response_tests[] = { + { + .str = "+UGCNTRD: 1, 100, 0, 100, 0", + .cid = 1, + .session_tx_bytes = 100, + .session_rx_bytes = 0, + .total_tx_bytes = 100, + .total_rx_bytes = 0 + }, + { + .str = "+UGCNTRD: 31,2704,1819,2724,1839", + .cid = 31, + .session_tx_bytes = 2704, + .session_rx_bytes = 1819, + .total_tx_bytes = 2724, + .total_rx_bytes = 1839 + }, + { + .str = "+UGCNTRD: 1, 100, 0, 100, 0\r\n" + "+UGCNTRD: 31,2704,1819,2724,1839\r\n", + .cid = 1, + .session_tx_bytes = 100, + .session_rx_bytes = 0, + .total_tx_bytes = 100, + .total_rx_bytes = 0 + }, + { + .str = "+UGCNTRD: 1, 100, 0, 100, 0\r\n" + "+UGCNTRD: 31,2704,1819,2724,1839\r\n", + .cid = 31, + .session_tx_bytes = 2704, + .session_rx_bytes = 1819, + .total_tx_bytes = 2724, + .total_rx_bytes = 1839 + }, + { + .str = "+UGCNTRD: 2,1397316870,113728263578,1397316870,113728263578\r\n", + .cid = 2, + .session_tx_bytes = 1397316870ULL, + .session_rx_bytes = 113728263578ULL, + .total_tx_bytes = 1397316870ULL, + .total_rx_bytes = 113728263578ULL + } +}; + +static void +test_ugcntrd_response (void) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (ugcntrd_response_tests); i++) { + GError *error = NULL; + gboolean success; + guint64 session_tx_bytes = 0; + guint64 session_rx_bytes = 0; + guint64 total_tx_bytes = 0; + guint64 total_rx_bytes = 0; + + success = mm_ublox_parse_ugcntrd_response_for_cid (ugcntrd_response_tests[i].str, + ugcntrd_response_tests[i].cid, + &session_tx_bytes, + &session_rx_bytes, + &total_tx_bytes, + &total_rx_bytes, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert_cmpuint (ugcntrd_response_tests[i].session_tx_bytes, ==, session_tx_bytes); + g_assert_cmpuint (ugcntrd_response_tests[i].session_rx_bytes, ==, session_rx_bytes); + g_assert_cmpuint (ugcntrd_response_tests[i].total_tx_bytes, ==, total_tx_bytes); + g_assert_cmpuint (ugcntrd_response_tests[i].total_rx_bytes, ==, total_rx_bytes); + } +} + +/*****************************************************************************/ + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/MM/ublox/upincnt/response", test_upincnt_response); + g_test_add_func ("/MM/ublox/uusbconf/response", test_uusbconf_response); + g_test_add_func ("/MM/ublox/ubmconf/response", test_ubmconf_response); + g_test_add_func ("/MM/ublox/uipaddr/response", test_uipaddr_response); + g_test_add_func ("/MM/ublox/cfun/response", test_cfun_response); + g_test_add_func ("/MM/ublox/urat/test/response/2g", test_urat_test_response_2g); + g_test_add_func ("/MM/ublox/urat/test/response/2g3g", test_urat_test_response_2g3g); + g_test_add_func ("/MM/ublox/urat/test/response/2g3g4g", test_urat_test_response_2g3g4g); + g_test_add_func ("/MM/ublox/urat/test/response/toby-l201", test_mode_filtering_toby_l201); + g_test_add_func ("/MM/ublox/urat/test/response/lisa-u200", test_mode_filtering_lisa_u200); + g_test_add_func ("/MM/ublox/urat/test/response/sara-u280", test_mode_filtering_sara_u280); + g_test_add_func ("/MM/ublox/urat/read/response", test_urat_read_response); + g_test_add_func ("/MM/ublox/urat/write/command", test_urat_write_command); + g_test_add_func ("/MM/ublox/ubandsel/response/one", test_ubandsel_response_one); + g_test_add_func ("/MM/ublox/ubandsel/response/two", test_ubandsel_response_two); + g_test_add_func ("/MM/ublox/ubandsel/response/three", test_ubandsel_response_three); + g_test_add_func ("/MM/ublox/ubandsel/response/four", test_ubandsel_response_four); + g_test_add_func ("/MM/ublox/ubandsel/request/any", test_ubandsel_request_any); + g_test_add_func ("/MM/ublox/ubandsel/request/2g", test_ubandsel_request_2g); + g_test_add_func ("/MM/ublox/ubandsel/request/1800", test_ubandsel_request_1800); + g_test_add_func ("/MM/ublox/uact/response/empty-list", test_uact_response_empty_list); + g_test_add_func ("/MM/ublox/uact/response/2g", test_uact_response_2g); + g_test_add_func ("/MM/ublox/uact/response/2g3g", test_uact_response_2g3g); + g_test_add_func ("/MM/ublox/uact/response/2g3g4g", test_uact_response_2g3g4g); + g_test_add_func ("/MM/ublox/uact/test/2g", test_uact_test_2g); + g_test_add_func ("/MM/ublox/uact/test/2g3g", test_uact_test_2g3g); + g_test_add_func ("/MM/ublox/uact/test/2g3g4g", test_uact_test_2g3g4g); + g_test_add_func ("/MM/ublox/uact/test/2g3g4g/2", test_uact_test_2g3g4g_2); + g_test_add_func ("/MM/ublox/uact/request/any", test_uact_request_any); + g_test_add_func ("/MM/ublox/uact/request/2g", test_uact_request_2g); + g_test_add_func ("/MM/ublox/uact/request/3g", test_uact_request_3g); + g_test_add_func ("/MM/ublox/uact/request/4g", test_uact_request_4g); + g_test_add_func ("/MM/ublox/uauthreq/test/tobyl4", test_uauthreq_tobyl4); + g_test_add_func ("/MM/ublox/uauthreq/test/with-auto", test_uauthreq_with_auto); + g_test_add_func ("/MM/ublox/uauthreq/test/less-fields", test_uauthreq_less_fields); + g_test_add_func ("/MM/ublox/ugcntrd/response", test_ugcntrd_response); + + return g_test_run (); +} |