When receiving a message from modem containing multiple CREG events that
have different format, the parsing happens in the order CREG regexes are
registered, and not in the order the modem sent the events.
That means that when receiving the following URC:
<CR><LF>+CEREG: 2<CR><LF><CR><LF>+CNSMOD: 8<CR><LF><CR><LF>+CEREG: 1,AAAA,01234567,7<CR><LF>
we'd incorrectly parse the `CEREG: 1` before `CEREG: 2`, and remember
the state as searching (2) instead of home (1), which can cause trouble
connecting because of waiting for state to go home which would never
happen again.
This fixes that problem by merging all the regexes together, so the
parsing should properly process the events in matching order in
parse_unsolicited()
Unfortunately changing the regex like this means that
mm_3gpp_parse_creg_response() match info handling also needs to be
reworked: matches number are increased for each regex, so we can
reliably know which regex was matched based on match count.
This is actually cleaner than the old approach that just guessed if nth
field with "item_is_lac_not_stat()", but requires careful testing.
This was validated checking that tests fail if any of the indices is
changed by iterating over them all and running the test:
grep -n 'n_matches -' src/mm-modem-helpers.c | sed -e 's/:.*//' \
| while read lineno; do
echo $lineno
git show HEAD:src/mm-modem-helpers.c \
| awk -v l=$lineno '{ if (NR == l) {
print $1,$2,$3,$4,$5 - 1,";"
} else {
print
}}' > src/mm-modem-helpers.c
ninja -C build src/tests/test-modem-helpers || break
build/src/tests/test-modem-helpers && break
done
A test case was added to make this work, as the Samsung Wave S8500
sample 'act' doesn't seem to actually be a technology value?
(case 36/42 could actually be merged but were kept separate on purpose
for easier maintenance/testing)
Fixes: #1087
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
5554 lines
209 KiB
C
5554 lines
209 KiB
C
/* -*- 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) 2010 Red Hat, Inc.
|
|
* Copyright (C) 2024 JUCR GmbH
|
|
*/
|
|
|
|
#include <glib.h>
|
|
#include <glib-object.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#define _LIBMM_INSIDE_MM
|
|
#include <libmm-glib.h>
|
|
#include "mm-modem-helpers.h"
|
|
#include "mm-log-test.h"
|
|
|
|
#define g_assert_cmpfloat_tolerance(val1, val2, tolerance) \
|
|
g_assert_cmpfloat (fabs (val1 - val2), <, tolerance)
|
|
|
|
/*****************************************************************************/
|
|
/* Test IFC=? responses */
|
|
|
|
static void
|
|
test_ifc_response (const gchar *str,
|
|
const MMFlowControl expected)
|
|
{
|
|
MMFlowControl mask;
|
|
GError *error = NULL;
|
|
|
|
mask = mm_parse_ifc_test_response (str, NULL, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mask, ==, expected);
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_all_simple (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,1,2),(0,1,2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_all_groups (void)
|
|
{
|
|
test_ifc_response ("+IFC (0-2),(0-2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_none_only (void)
|
|
{
|
|
test_ifc_response ("+IFC (0),(0)", MM_FLOW_CONTROL_NONE);
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_xon_xoff_only (void)
|
|
{
|
|
test_ifc_response ("+IFC (1),(1)", MM_FLOW_CONTROL_XON_XOFF);
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_rts_cts_only (void)
|
|
{
|
|
test_ifc_response ("+IFC (2),(2)", MM_FLOW_CONTROL_RTS_CTS);
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_no_xon_xoff (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,2),(0,2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_no_xon_xoff_in_ta (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,1,2),(0,2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_no_xon_xoff_in_te (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,2),(0,1,2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_no_rts_cts_simple (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,1),(0,1)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_no_rts_cts_groups (void)
|
|
{
|
|
test_ifc_response ("+IFC (0-1),(0-1)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_all_simple_and_unknown (void)
|
|
{
|
|
test_ifc_response ("+IFC (0,1,2,3),(0,1,2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
static void
|
|
test_ifc_response_all_groups_and_unknown (void)
|
|
{
|
|
test_ifc_response ("+IFC (0-3),(0-2)", (MM_FLOW_CONTROL_NONE | MM_FLOW_CONTROL_XON_XOFF | MM_FLOW_CONTROL_RTS_CTS));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test WS46=? responses */
|
|
|
|
static void
|
|
test_ws46_response (const gchar *str,
|
|
const MMModemMode *expected,
|
|
guint n_expected)
|
|
{
|
|
guint i;
|
|
GArray *modes;
|
|
GError *error = NULL;
|
|
|
|
modes = mm_3gpp_parse_ws46_test_response (str, NULL, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (modes != NULL);
|
|
g_assert_cmpuint (modes->len, ==, n_expected);
|
|
|
|
for (i = 0; i < n_expected; i++) {
|
|
guint j;
|
|
|
|
for (j = 0; j < modes->len; j++) {
|
|
if (expected[i] == g_array_index (modes, MMModemMode, j))
|
|
break;
|
|
}
|
|
g_assert_cmpuint (j, !=, modes->len);
|
|
}
|
|
g_array_unref (modes);
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_generic_2g3g4g (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G,
|
|
MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
};
|
|
const gchar *str = "+WS46: (12,22,25,28,29)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_generic_2g3g (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G,
|
|
MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
};
|
|
const gchar *str = "+WS46: (12,22,25)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_generic_2g3g_v2 (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G,
|
|
MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
};
|
|
const gchar *str = "+WS46: (12,22,29)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_cinterion (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G,
|
|
MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
};
|
|
const gchar *str = "(12,22,25,28,29)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_telit_le866 (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_4G,
|
|
};
|
|
const gchar *str = "(28)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_range_1 (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
|
};
|
|
const gchar *str = "+WS46: (29-31)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_ws46_response_range_2 (void)
|
|
{
|
|
static const MMModemMode expected[] = {
|
|
MM_MODEM_MODE_2G,
|
|
MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_3G,
|
|
MM_MODEM_MODE_2G | MM_MODEM_MODE_4G,
|
|
MM_MODEM_MODE_3G | MM_MODEM_MODE_4G,
|
|
};
|
|
const gchar *str = "+WS46: (12,22,25,28-31)";
|
|
|
|
test_ws46_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CMGL responses */
|
|
|
|
static void
|
|
test_cmgl_response (const gchar *str,
|
|
const MM3gppPduInfo *expected,
|
|
guint n_expected)
|
|
{
|
|
guint i;
|
|
GList *list;
|
|
GError *error = NULL;
|
|
|
|
list = mm_3gpp_parse_pdu_cmgl_response (str, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (list != NULL);
|
|
g_assert_cmpuint (g_list_length (list), ==, n_expected);
|
|
|
|
for (i = 0; i < n_expected; i++) {
|
|
GList *l;
|
|
|
|
/* Look for the pdu with the expected index */
|
|
for (l = list; l; l = g_list_next (l)) {
|
|
MM3gppPduInfo *info = l->data;
|
|
|
|
/* Found */
|
|
if (info->index == expected[i].index) {
|
|
g_assert_cmpint (info->status, ==, expected[i].status);
|
|
g_assert_cmpstr (info->pdu, ==, expected[i].pdu);
|
|
break;
|
|
}
|
|
}
|
|
g_assert (l != NULL);
|
|
}
|
|
|
|
mm_3gpp_pdu_info_list_free (list);
|
|
}
|
|
|
|
static void
|
|
test_cmgl_response_generic (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGL: 0,1,,147\r\n07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07";
|
|
|
|
const MM3gppPduInfo expected [] = {
|
|
{
|
|
.index = 0,
|
|
.status = 1,
|
|
.pdu = (gchar *) "07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07"
|
|
}
|
|
};
|
|
|
|
test_cmgl_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cmgl_response_generic_multiple (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGL: 0,1,,147\r\n07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07\r\n"
|
|
"+CMGL: 1,1,,147\r\n07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07\r\n"
|
|
"+CMGL: 2,1,,147\r\n07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07";
|
|
|
|
const MM3gppPduInfo expected [] = {
|
|
{
|
|
.index = 0,
|
|
.status = 1,
|
|
.pdu = (gchar *) "07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07"
|
|
},
|
|
{
|
|
.index = 1,
|
|
.status = 1,
|
|
.pdu = (gchar *) "07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07"
|
|
},
|
|
{
|
|
.index = 2,
|
|
.status = 1,
|
|
.pdu = (gchar *) "07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07"
|
|
}
|
|
};
|
|
|
|
test_cmgl_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cmgl_response_pantech (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGL: 17,3,35\r\n079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020";
|
|
|
|
const MM3gppPduInfo expected [] = {
|
|
{
|
|
.index = 17,
|
|
.status = 3,
|
|
.pdu = (gchar *) "079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020"
|
|
}
|
|
};
|
|
|
|
test_cmgl_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cmgl_response_pantech_multiple (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGL: 17,3,35\r\n079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020\r\n"
|
|
"+CMGL: 15,3,35\r\n079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020\r\n"
|
|
"+CMGL: 13,3,35\r\n079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020\r\n"
|
|
"+CMGL: 11,3,35\r\n079100F40D1101000F001000B917118336058F300";
|
|
|
|
const MM3gppPduInfo expected [] = {
|
|
{
|
|
.index = 17,
|
|
.status = 3,
|
|
.pdu = (gchar *) "079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020"
|
|
},
|
|
{
|
|
.index = 15,
|
|
.status = 3,
|
|
.pdu = (gchar *) "079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020"
|
|
},
|
|
{
|
|
.index = 13,
|
|
.status = 3,
|
|
.pdu = (gchar *) "079100F40D1101000F001000B917118336058F300001954747A0E4ACF41F27298CDCE83C6EF371B0402814020"
|
|
},
|
|
{
|
|
.index = 11,
|
|
.status = 3,
|
|
.pdu = (gchar *) "079100F40D1101000F001000B917118336058F300"
|
|
}
|
|
};
|
|
|
|
test_cmgl_response (str, expected, G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CMGR responses */
|
|
|
|
static void
|
|
test_cmgr_response (const gchar *str,
|
|
const MM3gppPduInfo *expected)
|
|
{
|
|
MM3gppPduInfo *info;
|
|
GError *error = NULL;
|
|
|
|
info = mm_3gpp_parse_cmgr_read_response (str, 0, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (info != NULL);
|
|
|
|
/* Ignore index, it is not included in CMGR response */
|
|
g_assert_cmpint (info->status, ==, expected->status);
|
|
g_assert_cmpstr (info->pdu, ==, expected->pdu);
|
|
|
|
mm_3gpp_pdu_info_free (info);
|
|
}
|
|
|
|
static void
|
|
test_cmgr_response_generic (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGR: 1,,147 07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07";
|
|
|
|
const MM3gppPduInfo expected = {
|
|
.index = 0,
|
|
.status = 1,
|
|
.pdu = (gchar *) "07914306073011F00405812261F700003130916191314095C27"
|
|
"4D96D2FBBD3E437280CB2BEC961F3DB5D76818EF2F0381D9E83E06F39A8CC2E9FD372F"
|
|
"77BEE0249CBE37A594E0E83E2F532085E2F93CB73D0B93CA7A7DFEEB01C447F93DF731"
|
|
"0BD3E07CDCB727B7A9C7ECF41E432C8FC96B7C32079189E26874179D0F8DD7E93C3A0B"
|
|
"21B246AA641D637396C7EBBCB22D0FD7E77B5D376B3AB3C07"
|
|
};
|
|
|
|
test_cmgr_response (str, &expected);
|
|
}
|
|
|
|
/* Telit HE910 places empty quotation marks in the <alpha> field and a CR+LF
|
|
* before the PDU */
|
|
static void
|
|
test_cmgr_response_telit (void *f, gpointer d)
|
|
{
|
|
const gchar *str =
|
|
"+CMGR: 0,\"\",50\r\n07916163838428F9040B916121021021F7000051905141642"
|
|
"20A23C4B0BCFD5E8740C4B0BCFD5E83C26E3248196687C9A0301D440DBBC3677918";
|
|
|
|
const MM3gppPduInfo expected = {
|
|
.index = 0,
|
|
.status = 0,
|
|
.pdu = (gchar *) "07916163838428F9040B916121021021F7000051905141642"
|
|
"20A23C4B0BCFD5E8740C4B0BCFD5E83C26E3248196687C9A0301D440DBBC3677918"
|
|
};
|
|
|
|
test_cmgr_response (str, &expected);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test COPS responses */
|
|
|
|
static void
|
|
test_cops_results (const gchar *desc,
|
|
const gchar *reply,
|
|
MMModemCharset cur_charset,
|
|
MM3gppNetworkInfo *expected_results,
|
|
guint32 expected_results_len)
|
|
{
|
|
GList *l;
|
|
GError *error = NULL;
|
|
GList *results;
|
|
|
|
g_debug ("Testing %s +COPS response...", desc);
|
|
|
|
results = mm_3gpp_parse_cops_test_response (reply, cur_charset, NULL, &error);
|
|
g_assert (results);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
|
|
|
|
for (l = results; l; l = g_list_next (l)) {
|
|
MM3gppNetworkInfo *info = l->data;
|
|
gboolean found = FALSE;
|
|
guint i;
|
|
gchar *access_tech_str;
|
|
|
|
for (i = 0; !found && i < expected_results_len; i++) {
|
|
MM3gppNetworkInfo *expected;
|
|
|
|
expected = &expected_results[i];
|
|
if (g_str_equal (info->operator_code, expected->operator_code) &&
|
|
info->access_tech == expected->access_tech) {
|
|
found = TRUE;
|
|
|
|
g_assert_cmpuint (info->status, ==, expected->status);
|
|
|
|
if (expected->operator_long)
|
|
g_assert_cmpstr (info->operator_long, ==, expected->operator_long);
|
|
else
|
|
g_assert (info->operator_long == NULL);
|
|
|
|
if (expected->operator_short)
|
|
g_assert_cmpstr (info->operator_short, ==, expected->operator_short);
|
|
else
|
|
g_assert (info->operator_short == NULL);
|
|
}
|
|
}
|
|
|
|
access_tech_str = mm_modem_access_technology_build_string_from_mask (info->access_tech);
|
|
g_debug ("info: [%s,%s,%s,%s] %sfound in expected results",
|
|
info->operator_long ? info->operator_long : "",
|
|
info->operator_short ? info->operator_short : "",
|
|
info->operator_code,
|
|
access_tech_str,
|
|
found ? "" : "not ");
|
|
g_free (access_tech_str);
|
|
|
|
g_assert (found == TRUE);
|
|
}
|
|
|
|
mm_3gpp_network_info_list_free (results);
|
|
}
|
|
|
|
static void
|
|
test_cops_response_tm506 (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+COPS: (2,\"\",\"T-Mobile\",\"31026\",0),(2,\"T - Mobile\",\"T - Mobile\",\"310260\"),2),(1,\"AT&T\",\"AT&T\",\"310410\"),0)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, NULL, (gchar *) "T-Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T - Mobile", (gchar *) "T - Mobile", (gchar *) "310260", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM }
|
|
};
|
|
|
|
test_cops_results ("TM-506", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gt3gplus (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (1,\"T-Mobile US\",\"TMO US\",\"31026\",0),(1,\"Cingular\",\"Cingular\",\"310410\",0),,(0, 1, 3),(0-2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile US", (gchar *) "TMO US", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Cingular", (gchar *) "Cingular", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("GlobeTrotter 3G+ (nozomi)", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_ac881 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (1,\"T-Mobile\",\"TMO\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Sierra AirCard 881", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gtmax36 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile US\",\"TMO US\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0, 1,)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile US", (gchar *) "TMO US", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Option GlobeTrotter MAX 3.6", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_ac860 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"TMO\",\"31026\",0),(1,\"Cingular\",\"Cinglr\",\"310410\",2),(1,\"Cingular\",\"Cinglr\",\"310410\",0),,)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Cingular", (gchar *) "Cinglr", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Cingular", (gchar *) "Cinglr", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Sierra AirCard 860", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gtm378 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"T-Mobile\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0, 1, 3),(0-2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "T-Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Option GTM378", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_motoc (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"\",\"310260\"),(0,\"Cingular Wireless\",\"\",\"310410\")";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", NULL, (gchar *) "310260", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_UNKNOWN, (gchar *) "Cingular Wireless", NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("BUSlink SCWi275u (Motorola C-series)", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_mf627a (void *f, gpointer d)
|
|
{
|
|
/* The '@' in this string is ASCII 0x40, and 0x40 is a valid GSM-7 char: '¡' (which is 0xc2,0xa1 in UTF-8) */
|
|
const char *reply = "+COPS: (2,\"AT&T@\",\"AT&TD\",\"310410\",0),(3,\"Vstream Wireless\",\"VSTREAM\",\"31026\",0),";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "AT&T¡", (gchar *) "AT&TD", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, (gchar *) "Vstream Wireless", (gchar *) "VSTREAM", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("ZTE MF627 (A)", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_mf627b (void *f, gpointer d)
|
|
{
|
|
/* The '@' in this string is ASCII 0x40, and 0x40 is a valid GSM-7 char: '¡' (which is 0xc2,0xa1 in UTF-8) */
|
|
const char *reply = "+COPS: (2,\"AT&Tp\",\"AT&T@\",\"310410\",0),(3,\"\",\"\",\"31026\",0),";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "AT&Tp", (gchar *) "AT&T¡", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("ZTE MF627 (B)", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_e160g (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"TMO\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Huawei E160G", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_mercury (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"\",\"\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),(1,\"T-Mobile\",\"TMO\",\"31026\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, NULL, NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Sierra AT&T USBConnect Mercury", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_quicksilver (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"AT&T\",\"\",\"310410\",0),(2,\"\",\"\",\"3104100\",2),(1,\"AT&T\",\"\",\"310260\",0),,(0-4),(0-2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "AT&T", NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, NULL, NULL, (gchar *) "3104100", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", NULL, (gchar *) "310260", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Option AT&T Quicksilver", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_icon225 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile US\",\"TMO US\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0, 1, 3),(0-2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile US", (gchar *) "TMO US", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Option iCON 225", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_icon452 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (1,\"T-Mobile US\",\"TMO US\",\"31026\",0),(2,\"T-Mobile\",\"T-Mobile\",\"310260\",2),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile US", (gchar *) "TMO US", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "T-Mobile", (gchar *) "310260", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM }
|
|
};
|
|
|
|
test_cops_results ("Option iCON 452", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_f3507g (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T - Mobile\",\"T - Mobile\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T - Mobile", (gchar *) "T - Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS }
|
|
};
|
|
|
|
test_cops_results ("Ericsson F3507g", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_f3607gw (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T - Mobile\",\"T - Mobile\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\"),2),(1,\"AT&T\",\"AT&T\",\"310410\"),0)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T - Mobile", (gchar *) "T - Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM }
|
|
};
|
|
|
|
test_cops_results ("Ericsson F3607gw", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_mc8775 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"T-Mobile\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "T-Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM }
|
|
};
|
|
|
|
test_cops_results ("Sierra MC8775", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_n80 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T - Mobile\",,\"31026\"),(1,\"Einstein PCS\",,\"31064\"),(1,\"Cingular\",,\"31041\"),,(0,1,3),(0,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T - Mobile", NULL, (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Einstein PCS", NULL, (gchar *) "31064", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Cingular", NULL, (gchar *) "31041", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Nokia N80", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_e1550 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"TMO\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Huawei E1550", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_mf622 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"T-Mobile\",\"31026\",0),(1,\"\",\"\",\"310410\",0),";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "T-Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, NULL, NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("ZTE MF622", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_e226 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (1,\"\",\"\",\"31026\",0),(1,\"\",\"\",\"310410\",2),(1,\"\",\"\",\"310410\",0),,(0,1,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, NULL, NULL, (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, NULL, NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, NULL, NULL, (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Huawei E226", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_xu870 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (0,\"AT&T MicroCell\",\"AT&T MicroCell\",\"310410\",2)\r\n+COPS: (1,\"AT&T MicroCell\",\"AT&T MicroCell\",\"310410\",0)\r\n+COPS: (1,\"T-Mobile\",\"TMO\",\"31026\",0)\r\n";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_UNKNOWN, (gchar *) "AT&T MicroCell", (gchar *) "AT&T MicroCell", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T MicroCell", (gchar *) "AT&T MicroCell", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile", (gchar *) "TMO", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Novatel XU870", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gtultraexpress (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile US\",\"TMO US\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile US", (gchar *) "TMO US", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Option GlobeTrotter Ultra Express", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_n2720 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T - Mobile\",,\"31026\",0),\r\n(1,\"AT&T\",,\"310410\",0),,(0,1,3),(0,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T - Mobile", NULL, (gchar *)"31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", NULL, (gchar *)"310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Nokia 2720", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gobi (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (2,\"T-Mobile\",\"T-Mobile\",\"31026\",0),(1,\"AT&T\",\"AT&T\",\"310410\",2),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "T-Mobile", (gchar *) "T-Mobile", (gchar *) "31026", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Qualcomm Gobi", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_sek600i (void *f, gpointer d)
|
|
{
|
|
/* Phone is stupid enough to support 3G but not report cell technology,
|
|
* mixing together 2G and 3G cells without any way of distinguishing
|
|
* which is which...
|
|
*/
|
|
const char *reply = "+COPS: (2,\"blau\",\"\",\"26203\"),(2,\"blau\",\"\",\"26203\"),(3,\"\",\"\",\"26201\"),(3,\"\",\"\",\"26202\"),(3,\"\",\"\",\"26207\"),(3,\"\",\"\",\"26201\"),(3,\"\",\"\",\"26207\")";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "blau", NULL, (gchar *) "26203", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "blau", NULL, (gchar *) "26203", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "26201", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "26202", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "26207", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "26201", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_FORBIDDEN, NULL, NULL, (gchar *) "26207", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Sony-Ericsson K600i", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_samsung_z810 (void *f, gpointer d)
|
|
{
|
|
/* Ensure commas within quotes don't trip up the parser */
|
|
const char *reply = "+COPS: (1,\"T-Mobile USA, In\",\"T-Mobile\",\"310260\",0),(1,\"AT&T\",\"AT&T\",\"310410\",0),,(0,1,2,3,4),(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "T-Mobile USA, In", (gchar *) "T-Mobile", (gchar *) "310260", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "AT&T", (gchar *) "AT&T", (gchar *) "310410", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
};
|
|
|
|
test_cops_results ("Samsung Z810", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_ublox_lara (void *f, gpointer d)
|
|
{
|
|
/* strings in UCS2 */
|
|
const char *reply =
|
|
"+COPS: "
|
|
"(2,\"004D006F007600690073007400610072\",\"004D006F007600690073007400610072\",\"00320031003400300037\",7),"
|
|
"(1,\"0059004F00490047004F\",\"0059004F00490047004F\",\"00320031003400300034\",7),"
|
|
"(1,\"0076006F006400610066006F006E0065002000450053\",\"0076006F00640061002000450053\",\"00320031003400300031\",7),"
|
|
"(1,\"004F00720061006E00670065002000530050\",\"00450053005000520054\",\"00320031003400300033\",0),"
|
|
"(1,\"0076006F006400610066006F006E0065002000450053\",\"0076006F00640061002000450053\",\"00320031003400300031\",0),"
|
|
"(1,\"004F00720061006E00670065002000530050\",\"00450053005000520054\",\"00320031003400300033\",7)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_CURRENT, (gchar *) "Movistar", (gchar *) "Movistar", (gchar *) "21407", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "YOIGO", (gchar *) "YOIGO", (gchar *) "21404", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "vodafone ES", (gchar *) "voda ES", (gchar *) "21401", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Orange SP", (gchar *) "ESPRT", (gchar *) "21403", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "vodafone ES", (gchar *) "voda ES", (gchar *) "21401", MM_MODEM_ACCESS_TECHNOLOGY_GSM },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Orange SP", (gchar *) "ESPRT", (gchar *) "21403", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
};
|
|
|
|
test_cops_results ("u-blox LARA", reply, MM_MODEM_CHARSET_UCS2, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_em9191 (void *f, gpointer d)
|
|
{
|
|
const char *reply =
|
|
"+COPS: "
|
|
"(1,\"Telekom.de\",\"TDG\",\"26201\",12),"
|
|
"(1,\"Telekom.de\",\"Telekom.\",\"26201\",7),"
|
|
"(1,\"o2 - de\",\"o2 - de\",\"26203\",7),"
|
|
"(1,\"vodafone.de\",\"Vodafone\",\"26202\",7)"
|
|
/* these next ones will be ignored */
|
|
"(0,1,2,3,4),"
|
|
"(0,1,2)";
|
|
static MM3gppNetworkInfo expected[] = {
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Telekom.de", (gchar *) "TDG", (gchar *) "26201", MM_MODEM_ACCESS_TECHNOLOGY_5GNR },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "Telekom.de", (gchar *) "Telekom.", (gchar *) "26201", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "o2 - de", (gchar *) "o2 - de", (gchar *) "26203", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
{ MM_MODEM_3GPP_NETWORK_AVAILABILITY_AVAILABLE, (gchar *) "vodafone.de", (gchar *) "Vodafone", (gchar *) "26202", MM_MODEM_ACCESS_TECHNOLOGY_LTE },
|
|
};
|
|
|
|
test_cops_results ("EM9191", reply, MM_MODEM_CHARSET_GSM, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cops_response_gsm_invalid (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+COPS: (0,1,2,3),(1,2,3,4)";
|
|
GList *results;
|
|
GError *error = NULL;
|
|
|
|
results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, NULL, &error);
|
|
g_assert (results == NULL);
|
|
g_assert_no_error (error);
|
|
}
|
|
|
|
static void
|
|
test_cops_response_umts_invalid (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+COPS: (0,1,2,3,4),(1,2,3,4,5)";
|
|
GList *results;
|
|
GError *error = NULL;
|
|
|
|
results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, NULL, &error);
|
|
g_assert (results == NULL);
|
|
g_assert_no_error (error);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test COPS? responses */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
guint mode;
|
|
guint format;
|
|
const gchar *operator;
|
|
MMModemAccessTechnology act;
|
|
} CopsQueryData;
|
|
|
|
static void
|
|
test_cops_query_data (const CopsQueryData *item)
|
|
{
|
|
gboolean result;
|
|
GError *error = NULL;
|
|
guint mode = G_MAXUINT;
|
|
guint format = G_MAXUINT;
|
|
gchar *operator = NULL;
|
|
MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
|
|
|
result = mm_3gpp_parse_cops_read_response (item->str,
|
|
&mode,
|
|
&format,
|
|
&operator,
|
|
&act,
|
|
NULL,
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (result);
|
|
g_assert_cmpuint (mode, ==, item->mode);
|
|
g_assert_cmpuint (format, ==, item->format);
|
|
g_assert_cmpstr (operator, ==, item->operator);
|
|
g_assert_cmpuint (act, ==, item->act);
|
|
|
|
g_free (operator);
|
|
}
|
|
|
|
static const CopsQueryData cops_query_data[] = {
|
|
{
|
|
.str = "+COPS: 1,0,\"CHINA MOBILE\"",
|
|
.mode = 1,
|
|
.format = 0,
|
|
.operator = "CHINA MOBILE",
|
|
.act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN
|
|
},
|
|
{
|
|
.str = "+COPS: 1,0,\"CHINA MOBILE\",7",
|
|
.mode = 1,
|
|
.format = 0,
|
|
.operator = "CHINA MOBILE",
|
|
.act = MM_MODEM_ACCESS_TECHNOLOGY_LTE
|
|
},
|
|
{
|
|
.str = "+COPS: 1,2,\"46000\"",
|
|
.mode = 1,
|
|
.format = 2,
|
|
.operator = "46000",
|
|
.act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN
|
|
},
|
|
{
|
|
.str = "+COPS: 1,2,\"46000\",7",
|
|
.mode = 1,
|
|
.format = 2,
|
|
.operator = "46000",
|
|
.act = MM_MODEM_ACCESS_TECHNOLOGY_LTE
|
|
},
|
|
};
|
|
|
|
static void
|
|
test_cops_query (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cops_query_data); i++)
|
|
test_cops_query_data (&cops_query_data[i]);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *input;
|
|
MMModemCharset charset;
|
|
const gchar *normalized;
|
|
} NormalizeOperatorTest;
|
|
|
|
static const NormalizeOperatorTest normalize_operator_tests[] = {
|
|
/* charset unknown */
|
|
{ "Verizon", MM_MODEM_CHARSET_UNKNOWN, "Verizon" },
|
|
{ "311480", MM_MODEM_CHARSET_UNKNOWN, "311480" },
|
|
/* charset configured as IRA (ASCII) */
|
|
{ "Verizon", MM_MODEM_CHARSET_IRA, "Verizon" },
|
|
{ "311480", MM_MODEM_CHARSET_IRA, "311480" },
|
|
/* charset configured as GSM7 */
|
|
{ "Verizon", MM_MODEM_CHARSET_GSM, "Verizon" },
|
|
{ "311480", MM_MODEM_CHARSET_GSM, "311480" },
|
|
/* charset configured as UCS2 */
|
|
{ "0056006500720069007A006F006E", MM_MODEM_CHARSET_UCS2, "Verizon" },
|
|
{ "003300310031003400380030", MM_MODEM_CHARSET_UCS2, "311480" },
|
|
{ "Verizon", MM_MODEM_CHARSET_UCS2, "Verizon" },
|
|
{ "311480", MM_MODEM_CHARSET_UCS2, "311480" },
|
|
};
|
|
|
|
static void
|
|
common_test_normalize_operator (const NormalizeOperatorTest *t)
|
|
{
|
|
gchar *str;
|
|
|
|
str = g_strdup (t->input);
|
|
mm_3gpp_normalize_operator (&str, t->charset, NULL);
|
|
if (!t->normalized)
|
|
g_assert (!str);
|
|
else
|
|
g_assert_cmpstr (str, ==, t->normalized);
|
|
g_free (str);
|
|
}
|
|
|
|
static void
|
|
test_normalize_operator (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (normalize_operator_tests); i++)
|
|
common_test_normalize_operator (&normalize_operator_tests[i]);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CREG/CGREG responses and unsolicited messages */
|
|
|
|
typedef struct {
|
|
GRegex *solicited_creg;
|
|
GRegex *unsolicited_creg;
|
|
} RegTestData;
|
|
|
|
static RegTestData *
|
|
reg_test_data_new (void)
|
|
{
|
|
RegTestData *data;
|
|
|
|
data = g_malloc0 (sizeof (RegTestData));
|
|
data->solicited_creg = mm_3gpp_creg_regex_get (TRUE);
|
|
data->unsolicited_creg = mm_3gpp_creg_regex_get (FALSE);
|
|
return data;
|
|
}
|
|
|
|
static void
|
|
reg_test_data_free (RegTestData *data)
|
|
{
|
|
g_regex_unref (data->solicited_creg);
|
|
g_regex_unref (data->unsolicited_creg);
|
|
g_free (data);
|
|
}
|
|
|
|
typedef struct {
|
|
MMModem3gppRegistrationState state;
|
|
gulong lac;
|
|
gulong ci;
|
|
MMModemAccessTechnology act;
|
|
|
|
guint regex_num;
|
|
gboolean cgreg;
|
|
gboolean cereg;
|
|
gboolean c5greg;
|
|
} CregResult;
|
|
|
|
static void
|
|
test_creg_match (const char *test,
|
|
gboolean solicited,
|
|
const char *reply,
|
|
RegTestData *data,
|
|
const CregResult *result)
|
|
{
|
|
g_autoptr(GMatchInfo) info = NULL;
|
|
MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
|
MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
|
gulong lac = 0;
|
|
gulong ci = 0;
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
gboolean cgreg = FALSE;
|
|
gboolean cereg = FALSE;
|
|
gboolean c5greg = FALSE;
|
|
GRegex *regex;
|
|
|
|
g_assert (reply);
|
|
g_assert (test);
|
|
g_assert (data);
|
|
g_assert (result);
|
|
|
|
g_debug ("Testing '%s' +C%sREG %s response '%s'...",
|
|
test,
|
|
result->cgreg ? "G" : "",
|
|
solicited ? "solicited" : "unsolicited",
|
|
reply);
|
|
|
|
regex = solicited ? data->solicited_creg : data->unsolicited_creg;
|
|
if (!g_regex_match (regex, reply, 0, &info)) {
|
|
g_debug ("not matched");
|
|
g_assert (FALSE);
|
|
}
|
|
|
|
success = mm_3gpp_parse_creg_response (info, NULL, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &c5greg, &error);
|
|
|
|
g_assert (success);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (state, ==, result->state);
|
|
g_assert_cmpuint (lac, ==, result->lac);
|
|
g_assert_cmpuint (ci, ==, result->ci);
|
|
g_assert_cmpuint (access_tech, ==, result->act);
|
|
g_assert_cmpuint (cgreg, ==, result->cgreg);
|
|
g_assert_cmpuint (cereg, ==, result->cereg);
|
|
g_assert_cmpuint (c5greg, ==, result->c5greg);
|
|
}
|
|
|
|
static void
|
|
test_creg1_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 1,3";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CREG=1", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg1_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 3\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CREG=1", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg1_multidigit_stat_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 11\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CREG=1 with multidigit \"stat\" value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_mercury_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 1,1,84CD,00D30173";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x84cd, 0xd30173, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sierra Mercury CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_mercury_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 1,84CD,00D30156\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x84cd, 0xd30156, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sierra Mercury CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_multidigit_stat_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 11,\"33FE\",\"a3fb477\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x33FE, 0xa3fb477, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CREG=2 with multidigit \"stat\" value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_sek850i_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 2,1,\"CE00\",\"01CEAD8F\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0xce00, 0x01cead8f, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sony Ericsson K850i CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_sek850i_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 1,\"CE00\",\"00005449\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0xce00, 0x5449, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sony Ericsson K850i CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_e160g_solicited_unregistered (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 2,0,00,0";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Huawei E160G unregistered CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_e160g_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 2,1,8BE3,2BAF";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Huawei E160G CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_e160g_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 1,8BE3,2BAF\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Huawei E160G CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_tm506_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG: 2,1,\"8BE3\",\"00002BAF\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2BAF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
/* Test leading zeros in the CI */
|
|
test_creg_match ("Sony Ericsson TM-506 CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_xu870_unsolicited_unregistered (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 2,,\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Novatel XU870 unregistered CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_iridium_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG:002,001,\"18d8\",\"ffff\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x18D8, 0xFFFF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Iridium, CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_no_leading_zeros_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG:2,1,0001,0010";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("solicited CREG=2 with no leading zeros in integer fields", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_leading_zeros_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CREG:002,001,\"0001\",\"0010\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("solicited CREG=2 with leading zeros in integer fields", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_no_leading_zeros_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 1,0001,0010,0\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 5, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("unsolicited CREG=2 with no leading zeros in integer fields", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_leading_zeros_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 001,\"0001\",\"0010\",000\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 6, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("unsolicited CREG=2 with leading zeros in integer fields", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_multidigit_stat_no_leading_zeros_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 10,0001,0010,0\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 5, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("unsolicited CREG=2 with no leading zeros in integer fields and multidigit \"stat\" value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_multidigit_stat_leading_zeros_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 0011,\"0001\",\"0010\",000\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 6, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("unsolicited CREG=2 with leading zeros in integer fields and multidigit \"stat\" value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_ublox_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const gchar *reply = "\r\n+CREG: 2,6,\"8B37\",\"0A265185\",7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Ublox Toby-L2 solicited while on LTE", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_ublox_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const gchar *reply = "\r\n+CREG: 6,\"8B37\",\"0A265185\",7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Ublox Toby-L2 unsolicited while on LTE", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg1_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CGREG: 1,3";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CGREG=1", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg1_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 3\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CGREG=1", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_f3607gw_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CGREG: 2,1,\"8BE3\",\"00002B5D\",3";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 7, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Ericsson F3607gw CGREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_f3607gw_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 1,\"8BE3\",\"00002B5D\",3\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 5, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Ericsson F3607gw CGREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_md400_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 2,5,\"0502\",\"0404736D\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sony-Ericsson MD400 CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_md400_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 5,\"0502\",\"0404736D\",2\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UMTS, 5, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Sony-Ericsson MD400 CGREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg_cgreg_multi_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 5\r\n\r\n+CGREG: 0\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Multi CREG/CGREG", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg_cgreg_multi2_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 0\r\n\r\n+CREG: 5\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Multi CREG/CGREG #2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_x220_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 2,1, 81ED, 1A9CEB\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x81ED, 0x1A9CEB, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE, FALSE };
|
|
|
|
/* Tests random spaces in response */
|
|
test_creg_match ("Alcatel One-Touch X220D CGREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_s8500_wave_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 2,1,000B,2816, B, C2816\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 8, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Samsung Wave S8500 CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_s8500_wave_multidigit_stat_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 2,11,003F,8FE3, B, C2816\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x003F, 0x8FE3, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 8, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Samsung Wave S8500 CREG=2 with multidigit \"stat\" value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_s8500_wave_act_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 2,11,003F,8FE3, 10, C2816\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x003F, 0x8FE3, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 8, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Samsung Wave S8500 CREG=2 with act value", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_creg2_gobi_weird_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CREG: 2,1, 0 5, 2715\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0000, 0x2715, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Qualcomm Gobi 1000 CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_unsolicited_with_rac (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 1,\"1422\",\"00000142\",3,\"00\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1422, 0x0142, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 9, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CGREG=2 with RAC", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_multidigit_stat_with_rac_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 11,\"B092\",\"00000697\",3,\"00\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0xB092, 0x0697, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 9, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("CGREG=2 with multidigit \"stat\" value and RAC", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_multidigit_stat_no_leading_zeros_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CGREG:2,10,ebbd,f025";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED, 0xebbd, 0xf025, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("solicited CGREG=2 with no leading zeros in integer fields and multidigit \"stat\" value", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_multidigit_stat_leading_zeros_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CGREG:002,0011,\"0f0d\",\"14c3\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x0f0d, 0x14c3, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("solicited CGREG=2 with leading zeros in integer fields and multidigit \"stat\" value", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg1_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CEREG: 1,3";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=1", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg1_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 3\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=1", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 2,1, 1F00, 79D903 ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 1, 1F00, 79D903 ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_multidigit_stat_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 2,10,\"8d83\",\"671f98a\",7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED, 0x8d83, 0x671f98a, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=2 with multidigit \"stat\" value", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_multidigit_stat_with_rac_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 2,10, 2CA8, 20 ,B5583D ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED, 0x2ca8, 0xB5583D, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 11, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=2 with multidigit \"stat\" value and RAC", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_multidigit_stat_with_rac_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 11, 78FE, 20 ,14419E ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x78FE, 0x14419E, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 10, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("CEREG=2 with multidigit \"stat\" value and RAC", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_altair_lte_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 1, 2, 0001, 00000100, 7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("Altair LTE CEREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_altair_lte_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 2, 0001, 00000100, 7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("Altair LTE CEREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_novatel_lte_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 2,1, 1F00, 20 ,79D903 ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 11, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("Novatel LTE E362 CEREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cereg2_novatel_lte_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CEREG: 1, 1F00, 20 ,79D903 ,7\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 10, FALSE, TRUE, FALSE };
|
|
|
|
test_creg_match ("Novatel LTE E362 CEREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_thuraya_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+CGREG: 2, 1, \"0426\", \"F00F\"";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Thuraya solicited CREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_cgreg2_thuraya_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+CGREG: 1, \"0426\", \"F00F\"\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, TRUE, FALSE, FALSE };
|
|
|
|
test_creg_match ("Thuraya unsolicited CREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_c5greg1_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+C5GREG: 1,3";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE, TRUE };
|
|
|
|
test_creg_match ("C5GREG=1", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_c5greg1_multidigit_stat_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+C5GREG: 1, 10\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE, TRUE };
|
|
|
|
test_creg_match ("C5GREG=1 with multidigit \"stat\" value", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_c5greg1_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+C5GREG: 3\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, TRUE };
|
|
|
|
test_creg_match ("C5GREG=1", FALSE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_c5greg2_solicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "+C5GREG: 2,1,1F00,79D903,11,6,ABCDEF";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_5GNR, 13, FALSE, FALSE, TRUE };
|
|
|
|
test_creg_match ("C5GREG=2", TRUE, reply, data, &result);
|
|
}
|
|
|
|
static void
|
|
test_c5greg2_unsolicited (void *f, gpointer d)
|
|
{
|
|
RegTestData *data = (RegTestData *) d;
|
|
const char *reply = "\r\n+C5GREG: 1,1F00,79D903,11,6,ABCDEF\r\n";
|
|
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_5GNR, 12, FALSE, FALSE, TRUE };
|
|
|
|
test_creg_match ("C5GREG=2", FALSE, reply, data, &result);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CSCS responses */
|
|
|
|
static void
|
|
test_cscs_icon225_support_response (void *f, gpointer d)
|
|
{
|
|
const char *reply = "\r\n+CSCS: (\"IRA\",\"GSM\",\"UCS2\")\r\n";
|
|
MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
|
|
gboolean success;
|
|
|
|
success = mm_3gpp_parse_cscs_test_response (reply, &charsets);
|
|
g_assert (success);
|
|
|
|
g_assert (charsets == (MM_MODEM_CHARSET_IRA |
|
|
MM_MODEM_CHARSET_GSM |
|
|
MM_MODEM_CHARSET_UCS2));
|
|
}
|
|
|
|
static void
|
|
test_cscs_sierra_mercury_support_response (void *f, gpointer d)
|
|
{
|
|
const char *reply = "\r\n+CSCS: (\"IRA\",\"GSM\",\"UCS2\",\"PCCP437\")\r\n";
|
|
MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
|
|
gboolean success;
|
|
|
|
success = mm_3gpp_parse_cscs_test_response (reply, &charsets);
|
|
g_assert (success);
|
|
|
|
g_assert (charsets == (MM_MODEM_CHARSET_IRA |
|
|
MM_MODEM_CHARSET_GSM |
|
|
MM_MODEM_CHARSET_UCS2 |
|
|
MM_MODEM_CHARSET_PCCP437));
|
|
}
|
|
|
|
static void
|
|
test_cscs_buslink_support_response (void *f, gpointer d)
|
|
{
|
|
const char *reply = "\r\n+CSCS: (\"8859-1\",\"ASCII\",\"GSM\",\"UCS2\",\"UTF8\")\r\n";
|
|
MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
|
|
gboolean success;
|
|
|
|
success = mm_3gpp_parse_cscs_test_response (reply, &charsets);
|
|
g_assert (success);
|
|
|
|
g_assert (charsets == (MM_MODEM_CHARSET_8859_1 |
|
|
MM_MODEM_CHARSET_IRA |
|
|
MM_MODEM_CHARSET_GSM |
|
|
MM_MODEM_CHARSET_UCS2 |
|
|
MM_MODEM_CHARSET_UTF8));
|
|
}
|
|
|
|
static void
|
|
test_cscs_blackberry_support_response (void *f, gpointer d)
|
|
{
|
|
const char *reply = "\r\n+CSCS: \"IRA\"\r\n";
|
|
MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
|
|
gboolean success;
|
|
|
|
success = mm_3gpp_parse_cscs_test_response (reply, &charsets);
|
|
g_assert (success);
|
|
|
|
g_assert (charsets == MM_MODEM_CHARSET_IRA);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test Device Identifier builders */
|
|
|
|
typedef struct {
|
|
const char *devid;
|
|
const char *desc;
|
|
guint vid;
|
|
guint pid;
|
|
const char *ati;
|
|
const char *ati1;
|
|
const char *gsn;
|
|
const char *revision;
|
|
const char *model;
|
|
const char *manf;
|
|
} DevidItem;
|
|
|
|
static DevidItem devids[] = {
|
|
{ "36e7a8e78637fd380b2664507ea5de8fc317d05b",
|
|
"Huawei E1550",
|
|
0x12d1, 0x1001,
|
|
"\nManufacturer: huawei\n"
|
|
"Model: E1550\n"
|
|
"Revision: 11.608.09.01.21\n"
|
|
"IMEI: 235012412595195\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
NULL,
|
|
"\n235012412595195\n",
|
|
"\n11.608.09.01.21\n",
|
|
"\nE1550\n",
|
|
"\nhuawei\n"
|
|
},
|
|
{ "33b0fc4a06af5448df656ce12925979acf1cb600",
|
|
"Huawei EC121",
|
|
0x12d1, 0x1411,
|
|
"\nManufacturer: HUAWEI INCORPORATED\n"
|
|
"Model: EC121\n"
|
|
"Revision: 11.100.17.00.114\n"
|
|
"ESN: +GSN:12de4fa6\n"
|
|
"+CIS707-A, +MS, +ES, +DS, +FCLASS\n",
|
|
NULL,
|
|
"\n12de4fa6\n",
|
|
"\n11.100.17.00.114\n",
|
|
"\nEC121\n",
|
|
"\nHUAWEI INCORPORATED\n"
|
|
},
|
|
{ "d17f016a402354eaa1e24855f4308fafca9cadb1",
|
|
"Sierra USBConnect Mercury",
|
|
0x1199, 0x6880,
|
|
"\nManufacturer: Sierra Wireless, Inc.\n"
|
|
"Model: C885\n"
|
|
"Revision: J1_0_1_26AP C:/WS/FW/J1_0_1_26AP/MSM7200A/SRC/AMSS 2009/01/30 07:58:06\n"
|
|
"IMEI: 987866969112306\n"
|
|
"IMEI SV: 6\n"
|
|
"FSN: D603478104511\n"
|
|
"3GPP Release 6\n"
|
|
"+GCAP: +CGSM,+DS,+ES\n",
|
|
NULL,
|
|
"\n987866969112306\n",
|
|
"\nJ1_0_1_26AP C:/WS/FW/J1_0_1_26AP/MSM7200A/SRC/AMSS 2009/01/30 07:58:06\n",
|
|
"\nC885\n",
|
|
"\nSierra Wireless, Inc.\n"
|
|
},
|
|
{ "345e9eaad7624393aca85cde9bd859edf462414c",
|
|
"ZTE MF627",
|
|
0x19d2, 0x0031,
|
|
"\nManufacturer: ZTE INCORPORATED\n"
|
|
"Model: MF627\n"
|
|
"Revision: BD_3GHAP673A4V1.0.0B02\n"
|
|
"IMEI: 023589923858188\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
NULL,
|
|
"\n023589923858188\n",
|
|
"\nBD_3GHAP673A4V1.0.0B02\n",
|
|
"\nMF627\n",
|
|
"\nZTE INCORPORATED\n"
|
|
},
|
|
{ "69fa133a668b6f4dbf39b73500fd153ec240c73f",
|
|
"Sony-Ericsson MD300",
|
|
0x0fce, 0xd0cf,
|
|
"\nMD300\n",
|
|
"\nR3A018\n",
|
|
"\n349583712939483\n",
|
|
"\nR3A018\n",
|
|
"\nMD300\n",
|
|
"\nSony Ericsson\n"
|
|
},
|
|
{ "3dad89ed7d774938c38188cf29cf1c211e9d360b",
|
|
"Option iCON 7.2",
|
|
0x0af0, 0x6901,
|
|
"\nManufacturer: Option N.V.\n"
|
|
"Model: GTM378\n"
|
|
"Revision: 2.5.21Hd (Date: Jun 17 2008, Time: 12:30:47)\n",
|
|
NULL,
|
|
"\n129512359199159,SE393939TS\n",
|
|
"\n2.5.21Hd (Date: Jun 17 2008, Time: 12:30:47)\n",
|
|
"\nGTM378\n",
|
|
"\nOption N.V.\n"
|
|
},
|
|
{ "b0acccb956c9eaf2076e03697e74bf998dc44179",
|
|
"ZTE MF622",
|
|
0x19d2, 0x0001,
|
|
NULL,
|
|
NULL,
|
|
"\n235251122555115\n",
|
|
"\n3UKP671M3V1.0.0B08 3UKP671M3V1.0.0B08 1 [Jan 07 2008 16:00:00]\n",
|
|
"\nMF622\n",
|
|
"\nZTE INCORPORATED\n"
|
|
},
|
|
{ "29a5b258f1dc6f50c66a1a9a1ecdde97560799ab",
|
|
"Option 452",
|
|
0x0af0, 0x7901,
|
|
"\nManufacturer: Option N.V.\n"
|
|
"Model: GlobeTrotter HSUPA Modem\n"
|
|
"Revision: 2.12.0.0Hd (Date: Oct 29 2009, Time: 09:56:48)\n",
|
|
"\nManufacturer: Option N.V.\n"
|
|
"Model: GlobeTrotter HSUPA Modem\n"
|
|
"Revision: 2.12.0.0Hd (Date: Oct 29 2009, Time: 09:56:48)\n",
|
|
"\n000125491259519,PH2155R3TR\n",
|
|
"\n2.12.0.0Hd (Date: Oct 29 2009, Time: 09:56:48)\n",
|
|
"\nGlobeTrotter HSUPA Modem\n",
|
|
"\nOption N.V.\n"
|
|
},
|
|
{ "c756c67e960e693d5d221e381ea170b60bb9288f",
|
|
"Novatel XU870",
|
|
0x413c, 0x8118,
|
|
"\nManufacturer: Novatel Wireless Incorporated\n"
|
|
"Model: DELL XU870 ExpressCard\n"
|
|
"Revision: 9.5.05.01-02 [2006-10-20 17:19:09]\n"
|
|
"IMEI: 012051505051501\n"
|
|
"+GCAP: +CGSM,+DS\n",
|
|
"\nManufacturer: Novatel Wireless Incorporated\n"
|
|
"Model: DELL XU870 ExpressCard\n"
|
|
"Revision: 9.5.05.01-02 [2006-10-20 17:19:09]\n"
|
|
"IMEI: 012051505051501\n"
|
|
"+GCAP: +CGSM,+DS\n",
|
|
"\n012051505051501\n",
|
|
"\n9.5.05.01-02 [2006-10-20 17:19:09]\n",
|
|
"\nDELL XU870 ExpressCard\n",
|
|
"\nNovatel Wireless Incorporated\n"
|
|
},
|
|
{ "4162ba918ab54b7776bccc3830e6c6b7a6738244",
|
|
"Zoom 4596",
|
|
0x1c9e, 0x9603,
|
|
"\nManufacturer: Manufacturer\n"
|
|
"Model: HSPA USB MODEM\n"
|
|
"Revision: LQA0021.1.1_M573A\n"
|
|
"IMEI: 239664699635121\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
"\nManufacturer: Manufacturer\n"
|
|
"Model: HSPA USB MODEM\n"
|
|
"Revision: LQA0021.1.1_M573A\n"
|
|
"IMEI: 239664699635121\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
"\n239664699635121\n",
|
|
"\nLQA0021.1.1_M573A\n",
|
|
"\nHSPA USB MODEM\n",
|
|
"\nManufacturer\n"
|
|
},
|
|
{ "6d3a2fccd3588943a8962fd1e0d3ba752c706660",
|
|
"C-MOTECH CDX-650",
|
|
0x16d8, 0x6512,
|
|
"\nManufacturer: C-MOTECH Co., Ltd.\r\r\n"
|
|
"Model: CDX-650 \r\r\n"
|
|
"Revision: CDX65UAC03\r\r\n"
|
|
"Esn: 3B0C4B98\r\r\n"
|
|
"+GCAP: +CIS707A, +MS, +ES, +DS, +FCLASS\r\n",
|
|
"\nManufacturer: C-MOTECH Co., Ltd.\r\r\n"
|
|
"Model: CDX-650 \r\r\n"
|
|
"Revision: CDX65UAC03\r\r\n"
|
|
"Esn: 3B0C4B98\r\r\n"
|
|
"+GCAP: +CIS707A, +MS, +ES, +DS, +FCLASS\r\n",
|
|
"\n0x3B0C4B98\n",
|
|
"\nCDX65UAC03 1 [Oct 17 2007 13:30:00]\n",
|
|
"\nModel CDX-650 \n",
|
|
"\nC-MOTECH Co., Ltd.\n"
|
|
},
|
|
{ "cf50da63e6d48beb1d1c3b41d70ef6fa534c3e13",
|
|
"BUSlink SCWi275u",
|
|
0x22b8, 0x3802,
|
|
"\n144\n",
|
|
"\n000\n",
|
|
NULL,
|
|
"\n\"ADE_05_00_06032300I\"\n",
|
|
"\n\"GSM900\",\"GSM1800\",\"GSM1900\",\"GSM850\",\"MODEL=I250-000\"\n",
|
|
"\n\"Motorola CE, Copyright 2000\"\n"
|
|
},
|
|
{ "2aff568f2b60f3d6f3f6cac708ed5dce77b12b96",
|
|
"Motorola ROKR E2",
|
|
0x22b8, 0x3802,
|
|
NULL,
|
|
NULL,
|
|
"\n\"626936926396996\"\n",
|
|
"\n\"R564_G_12.00.47P\"\n",
|
|
"\n\"E2\"\n",
|
|
"\n\"Motorola\"\n"
|
|
},
|
|
{ "a7136c6067a43f055ca093cee75cb98ce6c9658e",
|
|
"Sony-Ericsson W580i",
|
|
0x0fce, 0xd089,
|
|
"\nSony Ericsson W580\n",
|
|
"\nCXC1123481\n",
|
|
"\n012505051512505\n",
|
|
"\nR8BE001 080115 1451 CXC1123481_NAM_1_LA\n",
|
|
"\nAAC-1052042-BV\n",
|
|
"\nSony Ericsson\n"
|
|
},
|
|
{ "b80ee70214bdf9672f2a268ce165ecfd9def5721",
|
|
"Huawei E226",
|
|
0x12d1, 0x1003,
|
|
"\nManufacturer: huawei\n"
|
|
"Model: E226\n"
|
|
"Revision: 11.310.15.00.150\n"
|
|
"IMEI: 232363662362362\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
"\nManufacturer: huawei\n"
|
|
"Model: E226\n"
|
|
"Revision: 11.310.15.00.150\n"
|
|
"IMEI: 232363662362362\n"
|
|
"+GCAP: +CGSM,+FCLASS,+DS\n",
|
|
"\n232363662362362\n",
|
|
"\n11.310.15.00.150\n",
|
|
"\nE226\n",
|
|
"\nhuawei\n"
|
|
},
|
|
{ "d902e1f234863aa107bfc2d0faefbee5ed6901f1",
|
|
"LG LX265",
|
|
0x1004, 0x6000,
|
|
"\nManufacturer: +GMI: LG Electronics Inc.\n"
|
|
"Model: +GMI: LG Electronics Inc.+GMM: Model:LG-LX265\n"
|
|
"Revision: +GMR: LX265V05, 50571\n"
|
|
"ESN: +GSN: 0x9235EB52\n"
|
|
"+GCAP: +CIS707-A, +MS, +ES, +DS, +FCLASS\n",
|
|
"\nManufacturer: +GMI: LG Electronics Inc.\n"
|
|
"Model: +GMI: LG Electronics Inc.+GMM: Model:LG-LX265\n"
|
|
"Revision: +GMR: LX265V05, 50571\n"
|
|
"ESN: +GSN: 0x9235EB52\n"
|
|
"+GCAP: +CIS707-A, +MS, +ES, +DS, +FCLASS\n",
|
|
"\n0x9235EB52\n",
|
|
"\nLX265V05, 50571\n",
|
|
"\nModel:LG-LX265\n",
|
|
"\nLG Electronics Inc.\n"
|
|
},
|
|
{ "543c2920e450e20a46368861fdec3a3b97ba8663",
|
|
"Nokia 2720a BT",
|
|
0x0000, 0x0000,
|
|
"\nNokia\n",
|
|
"\n012350150101501\n",
|
|
"\n012350150101501\n",
|
|
"\nV 08.62\n"
|
|
"24-07-09\n"
|
|
"RM-520\n"
|
|
"(c) Nokia \n",
|
|
"\nNokia 2720a-2b\n",
|
|
"\nNokia\n"
|
|
},
|
|
{ "6386ffa7a39ced3c9bfd1d693b90975661e54a86",
|
|
"Gobi 1000",
|
|
0x03f0, 0x1f1d,
|
|
"\nManufacturer: QUALCOMM INCORPORATED\n"
|
|
"Model: 88\n"
|
|
"Revision: D1020-SUUAASFA-4352 1 [Apr 14 2008 18:00:00]\n"
|
|
"IMEI: 239639269236269\n"
|
|
"+GCAP: +CGSM,+DS\n",
|
|
"\nManufacturer: QUALCOMM INCORPORATED\n"
|
|
"Model: 88\n"
|
|
"Revision: D1020-SUUAASFA-4352 1 [Apr 14 2008 18:00:00]\n"
|
|
"IMEI: 239639269236269\n"
|
|
"+GCAP: +CGSM,+DS\n",
|
|
"\n239639269236269\n",
|
|
"\nD1020-SUUAASFA-4352 1 [Apr 14 2008 18:00:00]\n",
|
|
"\n88\n",
|
|
"\nQUALCOMM INCORPORATED\n"
|
|
},
|
|
{ NULL }
|
|
};
|
|
|
|
static void
|
|
test_devid_item (void *f, gpointer d)
|
|
{
|
|
DevidItem *item = (DevidItem *) d;
|
|
char *devid;
|
|
|
|
g_debug ("%s... ", item->desc);
|
|
devid = mm_create_device_identifier (item->vid,
|
|
item->pid,
|
|
NULL,
|
|
item->ati,
|
|
item->ati1,
|
|
item->gsn,
|
|
item->revision,
|
|
item->model,
|
|
item->manf);
|
|
g_assert (devid);
|
|
if (strcmp (devid, item->devid))
|
|
g_message ("%s", devid);
|
|
g_assert (!strcmp (devid, item->devid));
|
|
g_free (devid);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CMER test responses */
|
|
|
|
static void
|
|
test_cmer_response (const gchar *str,
|
|
MM3gppCmerMode expected_modes,
|
|
MM3gppCmerInd expected_inds)
|
|
{
|
|
gboolean ret;
|
|
MM3gppCmerMode modes = MM_3GPP_CMER_MODE_NONE;
|
|
MM3gppCmerInd inds = MM_3GPP_CMER_IND_NONE;
|
|
GError *error = NULL;
|
|
|
|
ret = mm_3gpp_parse_cmer_test_response (str, NULL, &modes, &inds, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
|
|
g_assert_cmpuint (modes, ==, expected_modes);
|
|
g_assert_cmpuint (inds, ==, expected_inds);
|
|
}
|
|
|
|
static void
|
|
test_cmer_response_cinterion_pls8 (void)
|
|
{
|
|
static const gchar *str = "+CMER: (0-3),(0),(0),(0-1),(0-1)";
|
|
static const MM3gppCmerMode expected_modes = ( \
|
|
MM_3GPP_CMER_MODE_DISCARD_URCS | \
|
|
MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED | \
|
|
MM_3GPP_CMER_MODE_BUFFER_URCS_IF_LINK_RESERVED | \
|
|
MM_3GPP_CMER_MODE_FORWARD_URCS);
|
|
static const MM3gppCmerInd expected_inds = ( \
|
|
MM_3GPP_CMER_IND_DISABLE | \
|
|
MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND);
|
|
|
|
test_cmer_response (str, expected_modes, expected_inds);
|
|
}
|
|
|
|
static void
|
|
test_cmer_response_sierra_em7345 (void)
|
|
{
|
|
static const gchar *str = "+CMER: 1,0,0,(0-1),0";
|
|
static const MM3gppCmerMode expected_modes = ( \
|
|
MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED);
|
|
static const MM3gppCmerInd expected_inds = ( \
|
|
MM_3GPP_CMER_IND_DISABLE | \
|
|
MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND);
|
|
|
|
test_cmer_response (str, expected_modes, expected_inds);
|
|
}
|
|
|
|
static void
|
|
test_cmer_response_cinterion_ehs5 (void)
|
|
{
|
|
static const gchar *str = "+CMER: (1,2),0,0,(0-1),0";
|
|
static const MM3gppCmerMode expected_modes = ( \
|
|
MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED | \
|
|
MM_3GPP_CMER_MODE_BUFFER_URCS_IF_LINK_RESERVED);
|
|
static const MM3gppCmerInd expected_inds = ( \
|
|
MM_3GPP_CMER_IND_DISABLE | \
|
|
MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND);
|
|
|
|
test_cmer_response (str, expected_modes, expected_inds);
|
|
}
|
|
|
|
static void
|
|
test_cmer_request_cinterion_ehs5 (void)
|
|
{
|
|
gchar *str;
|
|
|
|
str = mm_3gpp_build_cmer_set_request (MM_3GPP_CMER_MODE_BUFFER_URCS_IF_LINK_RESERVED, MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND);
|
|
g_assert_cmpstr (str, ==, "+CMER=2,0,0,1");
|
|
g_free (str);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CIND responses */
|
|
|
|
typedef struct {
|
|
const char *desc;
|
|
const gint min;
|
|
const gint max;
|
|
} CindEntry;
|
|
|
|
static void
|
|
test_cind_results (const char *desc,
|
|
const char *reply,
|
|
CindEntry *expected_results,
|
|
guint32 expected_results_len)
|
|
{
|
|
guint i;
|
|
GError *error = NULL;
|
|
GHashTable *results;
|
|
|
|
g_debug ("Testing %s +CIND response...", desc);
|
|
|
|
results = mm_3gpp_parse_cind_test_response (reply, &error);
|
|
g_assert (results);
|
|
g_assert (error == NULL);
|
|
|
|
g_assert (g_hash_table_size (results) == expected_results_len);
|
|
|
|
for (i = 0; i < expected_results_len; i++) {
|
|
CindEntry *expected = &expected_results[i];
|
|
MM3gppCindResponse *compare;
|
|
|
|
compare = g_hash_table_lookup (results, expected->desc);
|
|
g_assert (compare);
|
|
g_assert_cmpint (i + 1, ==, mm_3gpp_cind_response_get_index (compare));
|
|
g_assert_cmpint (expected->min, ==, mm_3gpp_cind_response_get_min (compare));
|
|
g_assert_cmpint (expected->max, ==, mm_3gpp_cind_response_get_max (compare));
|
|
}
|
|
|
|
g_hash_table_destroy (results);
|
|
}
|
|
|
|
static void
|
|
test_cind_response_linktop_lw273 (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+CIND: (\"battchg\",(0-5)),(\"signal\",(0-5)),(\"batterywarning\",(0-1)),(\"chargerconnected\",(0-1)),(\"service\",(0-1)),(\"sounder\",(0-1)),(\"message\",(0-1)),()";
|
|
static CindEntry expected[] = {
|
|
{ "battchg", 0, 5 },
|
|
{ "signal", 0, 5 },
|
|
{ "batterywarning", 0, 1 },
|
|
{ "chargerconnected", 0, 1 },
|
|
{ "service", 0, 1 },
|
|
{ "sounder", 0, 1 },
|
|
{ "message", 0, 1 }
|
|
};
|
|
|
|
test_cind_results ("LW273", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cind_response_moto_v3m (void *f, gpointer d)
|
|
{
|
|
const char *reply = "+CIND: (\"Voice Mail\",(0,1)),(\"service\",(0,1)),(\"call\",(0,1)),(\"Roam\",(0-2)),(\"signal\",(0-5)),(\"callsetup\",(0-3)),(\"smsfull\",(0,1))";
|
|
static CindEntry expected[] = {
|
|
{ "voicemail", 0, 1 },
|
|
{ "service", 0, 1 },
|
|
{ "call", 0, 1 },
|
|
{ "roam", 0, 2 },
|
|
{ "signal", 0, 5 },
|
|
{ "callsetup", 0, 3 },
|
|
{ "smsfull", 0, 1 }
|
|
};
|
|
|
|
test_cind_results ("Motorola V3m", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CGEREP test responses */
|
|
|
|
static void
|
|
test_cgerep_response (const gchar *str,
|
|
MM3gppCgerepMode expected_modes)
|
|
{
|
|
gboolean ret;
|
|
MM3gppCgerepMode modes = MM_3GPP_CGEREP_MODE_NONE;
|
|
GError *error = NULL;
|
|
|
|
ret = mm_3gpp_parse_cgerep_test_response (str, NULL, &modes, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
|
|
g_assert_cmpuint (modes, ==, expected_modes);
|
|
}
|
|
|
|
static void
|
|
test_cgerep_response_telit_le910q1 (void)
|
|
{
|
|
static const gchar *str = "+CGEREP: (0,1),(0)";
|
|
static const MM3gppCgerepMode expected_modes = ( \
|
|
MM_3GPP_CGEREP_MODE_DISCARD_URCS | \
|
|
MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED);
|
|
|
|
test_cgerep_response (str, expected_modes);
|
|
}
|
|
|
|
static void
|
|
test_cgerep_response_telit_ln920 (void)
|
|
{
|
|
static const gchar *str = "+CGEREP: (0-2),(0,1)";
|
|
static const MM3gppCgerepMode expected_modes = ( \
|
|
MM_3GPP_CGEREP_MODE_DISCARD_URCS | \
|
|
MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED | \
|
|
MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED);
|
|
|
|
test_cgerep_response (str, expected_modes);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CGEV indication parsing */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
MM3gppCgev expected_type;
|
|
const gchar *expected_pdp_type;
|
|
const gchar *expected_pdp_addr;
|
|
guint expected_cid;
|
|
guint expected_parent_cid;
|
|
guint expected_event_type;
|
|
} CgevIndicationTest;
|
|
|
|
static const CgevIndicationTest cgev_indication_tests[] = {
|
|
{ "+CGEV: REJECT IP, 123.123.123.123", MM_3GPP_CGEV_REJECT, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "REJECT IP, 123.123.123.123", MM_3GPP_CGEV_REJECT, "IP", "123.123.123.123", 0, 0, 0 },
|
|
|
|
{ "+CGEV: NW REACT IP, 123.123.123.123", MM_3GPP_CGEV_NW_REACT, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "NW REACT IP, 123.123.123.123", MM_3GPP_CGEV_NW_REACT, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "+CGEV: NW REACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_NW_REACT, "IP", "123.123.123.123", 1, 0, 0 },
|
|
|
|
{ "NW DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_NW_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
{ "+CGEV: NW DEACT IP, 123.123.123.123", MM_3GPP_CGEV_NW_DEACT_PDP, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "NW DEACT IP, 123.123.123.123", MM_3GPP_CGEV_NW_DEACT_PDP, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "+CGEV: NW DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_NW_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
{ "NW DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_NW_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
|
|
{ "ME DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_ME_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
{ "+CGEV: ME DEACT IP, 123.123.123.123", MM_3GPP_CGEV_ME_DEACT_PDP, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "ME DEACT IP, 123.123.123.123", MM_3GPP_CGEV_ME_DEACT_PDP, "IP", "123.123.123.123", 0, 0, 0 },
|
|
{ "+CGEV: ME DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_ME_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
{ "ME DEACT IP, 123.123.123.123, 1", MM_3GPP_CGEV_ME_DEACT_PDP, "IP", "123.123.123.123", 1, 0, 0 },
|
|
|
|
{ "ME PDN ACT 2", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: ME PDN ACT 2", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
/* with ,<reason>[,<cid_other>]] */
|
|
{ "ME PDN ACT 2, 3", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: ME PDN ACT 2, 3", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "ME PDN ACT 2, 3, 4", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: ME PDN ACT 2, 3, 4", MM_3GPP_CGEV_ME_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
|
|
{ "ME PDN DEACT 2", MM_3GPP_CGEV_ME_DEACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: ME PDN DEACT 2", MM_3GPP_CGEV_ME_DEACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
|
|
{ "ME ACT 3, 2, 1", MM_3GPP_CGEV_ME_ACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
{ "+CGEV: ME ACT 3, 2, 1", MM_3GPP_CGEV_ME_ACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
|
|
{ "ME DEACT 3, 2, 1", MM_3GPP_CGEV_ME_DEACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
{ "+CGEV: ME DEACT 3, 2, 1", MM_3GPP_CGEV_ME_DEACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
|
|
{ "NW PDN ACT 2", MM_3GPP_CGEV_NW_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: NW PDN ACT 2", MM_3GPP_CGEV_NW_ACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
|
|
{ "NW PDN DEACT 2", MM_3GPP_CGEV_NW_DEACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
{ "+CGEV: NW PDN DEACT 2", MM_3GPP_CGEV_NW_DEACT_PRIMARY, NULL, NULL, 2, 0, 0 },
|
|
|
|
{ "NW ACT 3, 2, 1", MM_3GPP_CGEV_NW_ACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
{ "+CGEV: NW ACT 3, 2, 1", MM_3GPP_CGEV_NW_ACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
|
|
{ "NW DEACT 3, 2, 1", MM_3GPP_CGEV_NW_DEACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
{ "+CGEV: NW DEACT 3, 2, 1", MM_3GPP_CGEV_NW_DEACT_SECONDARY, NULL, NULL, 2, 3, 1 },
|
|
|
|
{ "+CGEV: NW DETACH", MM_3GPP_CGEV_NW_DETACH, NULL, NULL, 0, 0, 0 },
|
|
{ "NW DETACH", MM_3GPP_CGEV_NW_DETACH, NULL, NULL, 0, 0, 0 },
|
|
{ "+CGEV: ME DETACH", MM_3GPP_CGEV_ME_DETACH, NULL, NULL, 0, 0, 0 },
|
|
{ "ME DETACH", MM_3GPP_CGEV_ME_DETACH, NULL, NULL, 0, 0, 0 },
|
|
|
|
{ "+CGEV: NW CLASS A", MM_3GPP_CGEV_NW_CLASS, NULL, NULL, 0, 0, 0 },
|
|
{ "NW CLASS A", MM_3GPP_CGEV_NW_CLASS, NULL, NULL, 0, 0, 0 },
|
|
{ "+CGEV: ME CLASS A", MM_3GPP_CGEV_ME_CLASS, NULL, NULL, 0, 0, 0 },
|
|
{ "ME CLASS A", MM_3GPP_CGEV_ME_CLASS, NULL, NULL, 0, 0, 0 },
|
|
};
|
|
|
|
static void
|
|
test_cgev_indication (const CgevIndicationTest *t)
|
|
{
|
|
guint i;
|
|
GError *error = NULL;
|
|
gboolean ret;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cgev_indication_tests); i++) {
|
|
const CgevIndicationTest *test = &cgev_indication_tests[i];
|
|
MM3gppCgev type;
|
|
|
|
type = mm_3gpp_parse_cgev_indication_action (test->str);
|
|
g_assert_cmpuint (type, ==, test->expected_type);
|
|
|
|
g_debug ("[%u] type: %u", i, type);
|
|
|
|
switch (type) {
|
|
case MM_3GPP_CGEV_UNKNOWN:
|
|
case MM_3GPP_CGEV_NW_DETACH:
|
|
case MM_3GPP_CGEV_ME_DETACH:
|
|
break;
|
|
case MM_3GPP_CGEV_NW_ACT_PRIMARY:
|
|
case MM_3GPP_CGEV_ME_ACT_PRIMARY:
|
|
case MM_3GPP_CGEV_NW_DEACT_PRIMARY:
|
|
case MM_3GPP_CGEV_ME_DEACT_PRIMARY: {
|
|
guint cid;
|
|
|
|
g_debug ("[%u] parsing as primary", i);
|
|
ret = mm_3gpp_parse_cgev_indication_primary (test->str, type, &cid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
g_assert_cmpuint (cid, ==, test->expected_cid);
|
|
break;
|
|
}
|
|
case MM_3GPP_CGEV_NW_ACT_SECONDARY:
|
|
case MM_3GPP_CGEV_ME_ACT_SECONDARY:
|
|
case MM_3GPP_CGEV_NW_DEACT_SECONDARY:
|
|
case MM_3GPP_CGEV_ME_DEACT_SECONDARY: {
|
|
guint p_cid;
|
|
guint cid;
|
|
guint event_type;
|
|
|
|
g_debug ("[%u] parsing as secondary", i);
|
|
ret = mm_3gpp_parse_cgev_indication_secondary (test->str, type, &p_cid, &cid, &event_type, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
g_assert_cmpuint (cid, ==, test->expected_cid);
|
|
g_assert_cmpuint (p_cid, ==, test->expected_parent_cid);
|
|
g_assert_cmpuint (event_type, ==, test->expected_event_type);
|
|
break;
|
|
}
|
|
case MM_3GPP_CGEV_NW_DEACT_PDP:
|
|
case MM_3GPP_CGEV_ME_DEACT_PDP:
|
|
case MM_3GPP_CGEV_REJECT:
|
|
case MM_3GPP_CGEV_NW_REACT: {
|
|
gchar *pdp_type;
|
|
gchar *pdp_addr;
|
|
guint cid;
|
|
|
|
g_debug ("[%u] parsing as pdp", i);
|
|
ret = mm_3gpp_parse_cgev_indication_pdp (test->str, type, &pdp_type, &pdp_addr, &cid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
g_assert_cmpstr (pdp_type, ==, test->expected_pdp_type);
|
|
g_assert_cmpstr (pdp_addr, ==, test->expected_pdp_addr);
|
|
g_assert_cmpuint (cid, ==, test->expected_cid);
|
|
|
|
g_free (pdp_type);
|
|
g_free (pdp_addr);
|
|
break;
|
|
}
|
|
case MM_3GPP_CGEV_NW_CLASS:
|
|
case MM_3GPP_CGEV_ME_CLASS:
|
|
case MM_3GPP_CGEV_NW_MODIFY:
|
|
case MM_3GPP_CGEV_ME_MODIFY:
|
|
/* ignore */
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test ICCID parsing */
|
|
|
|
static void
|
|
test_iccid_parse_quoted_swap_19_digit (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "\"984402003576012594F9\"";
|
|
const char *expected = "8944200053671052499";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_unquoted_swap_20_digit (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "98231420326409614067";
|
|
const char *expected = "89324102234690160476";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_unquoted_unswapped_19_digit (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "8944200053671052499F";
|
|
const char *expected = "8944200053671052499";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_unquoted_unswapped_19_digit_no_f (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "8944200053671052499";
|
|
const char *expected = "8944200053671052499";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_quoted_unswapped_20_digit (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "\"89324102234690160476\"";
|
|
const char *expected = "89324102234690160476";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_quoted_unswapped_hex_account (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "\"898602F9091830030220\"";
|
|
const char *expected = "898602F9091830030220";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_quoted_unswapped_hex_account_2 (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "\"898602C0123456789012\"";
|
|
const char *expected = "898602C0123456789012";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (parsed, ==, expected);
|
|
g_free (parsed);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_short (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "982314203264096";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert (parsed == NULL);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
|
|
g_error_free (error);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_invalid_chars (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "98231420326pl9614067";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert (parsed == NULL);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
|
|
g_error_free (error);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_quoted_invalid_mii (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "\"0044200053671052499\"";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert (parsed == NULL);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
|
|
g_error_free (error);
|
|
}
|
|
|
|
static void
|
|
test_iccid_parse_unquoted_invalid_mii (void *f, gpointer d)
|
|
{
|
|
const char *raw_iccid = "0044200053671052499";
|
|
char *parsed;
|
|
GError *error = NULL;
|
|
|
|
parsed = mm_3gpp_parse_iccid (raw_iccid, &error);
|
|
g_assert (parsed == NULL);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
|
|
g_error_free (error);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test APN cmp */
|
|
|
|
typedef struct {
|
|
const gchar *existing;
|
|
const gchar *requested;
|
|
gboolean match_expected;
|
|
} TestApnCmp;
|
|
|
|
static const TestApnCmp test_apn_cmp[] = {
|
|
{ "", "", TRUE },
|
|
{ NULL, "", TRUE },
|
|
{ "", NULL, TRUE },
|
|
{ NULL, NULL, TRUE },
|
|
{ "m2m.com.attz", "m2m.com.attz", TRUE },
|
|
{ "m2m.com.attz", "M2M.COM.ATTZ", TRUE },
|
|
{ "M2M.COM.ATTZ", "m2m.com.attz", TRUE },
|
|
{ "m2m.com.attz.mnc170.mcc310.gprs", "m2m.com.attz", TRUE },
|
|
{ "ac.vodafone.es.MNC001.MCC214.GPRS", "ac.vodafone.es", TRUE },
|
|
{ "", "m2m.com.attz", FALSE },
|
|
{ "m2m.com.attz", "", FALSE },
|
|
{ "m2m.com.attz", "m2m.com.attz.mnc170.mcc310.gprs", FALSE },
|
|
{ "ac.vodafone.es", "ac.vodafone.es.MNC001.MCC214.GPRS", FALSE },
|
|
{ "internet.test", "internet", FALSE },
|
|
{ "internet.test", "INTERNET", FALSE },
|
|
{ "internet.test", "internet.tes", FALSE },
|
|
};
|
|
|
|
static void
|
|
test_cmp_apn_name (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_apn_cmp); i++) {
|
|
g_debug ("Comparing requested '%s' vs existing '%s': %s match",
|
|
test_apn_cmp[i].requested,
|
|
test_apn_cmp[i].existing,
|
|
test_apn_cmp[i].match_expected ? "should" : "shouldn't");
|
|
g_assert (mm_3gpp_cmp_apn_name (test_apn_cmp[i].requested, test_apn_cmp[i].existing) == test_apn_cmp[i].match_expected);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CGDCONT test responses */
|
|
|
|
static void
|
|
test_cgdcont_test_results (const gchar *desc,
|
|
const gchar *reply,
|
|
MM3gppPdpContextFormat *expected_results,
|
|
guint32 expected_results_len)
|
|
{
|
|
GList *l;
|
|
GError *error = NULL;
|
|
GList *results;
|
|
|
|
g_debug ("Testing %s +CGDCONT test response...", desc);
|
|
|
|
results = mm_3gpp_parse_cgdcont_test_response (reply, NULL, &error);
|
|
g_assert (results);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
|
|
|
|
for (l = results; l; l = g_list_next (l)) {
|
|
MM3gppPdpContextFormat *format = l->data;
|
|
gboolean found = FALSE;
|
|
guint i;
|
|
|
|
for (i = 0; !found && i < expected_results_len; i++) {
|
|
MM3gppPdpContextFormat *expected;
|
|
|
|
expected = &expected_results[i];
|
|
if (format->pdp_type == expected->pdp_type) {
|
|
found = TRUE;
|
|
|
|
g_assert_cmpuint (format->min_cid, ==, expected->min_cid);
|
|
g_assert_cmpuint (format->max_cid, ==, expected->max_cid);
|
|
}
|
|
}
|
|
|
|
g_assert (found == TRUE);
|
|
}
|
|
|
|
mm_3gpp_pdp_context_format_list_free (results);
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_test_response_single (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Single", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_test_response_multiple (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4 },
|
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV6 },
|
|
{ 1, 10, MM_BEARER_IP_FAMILY_IPV4V6 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Multiple", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_test_response_multiple_and_ignore (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: (1-16),\"IP\",,,(0-2),(0-4)\r\n"
|
|
"+CGDCONT: (1-16),\"PPP\",,,(0-2),(0-4)\r\n"
|
|
"+CGDCONT: (1-16),\"IPV6\",,,(0-2),(0-4)\r\n";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 16, MM_BEARER_IP_FAMILY_IPV4 },
|
|
/* PPP is ignored */
|
|
{ 1, 16, MM_BEARER_IP_FAMILY_IPV6 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Multiple and Ignore", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_test_response_single_context (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: (1),\"IP\",,,(0),(0)\r\n"
|
|
"+CGDCONT: (1),\"IPV6\",,,(0),(0)\r\n";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 1, MM_BEARER_IP_FAMILY_IPV4 },
|
|
{ 1, 1, MM_BEARER_IP_FAMILY_IPV6 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Single Context", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_test_response_thuraya (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: ( 1 ) , \"IP\" ,,, (0-2),(0-3)\r\n"
|
|
"+CGDCONT: , \"PPP\" ,,, (0-2),(0-3)\r\n";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 1, MM_BEARER_IP_FAMILY_IPV4 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Thuraya", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
|
|
static void
|
|
test_cgdcont_test_response_cinterion_phs8 (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: (1-17,101-116),\"IP\",,,(0),(0-4)\r\n";
|
|
static MM3gppPdpContextFormat expected[] = {
|
|
{ 1, 17, MM_BEARER_IP_FAMILY_IPV4 }
|
|
};
|
|
|
|
test_cgdcont_test_results ("Cinterion PHS8-USA REVISION 03.001", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Test CGDCONT read responses */
|
|
|
|
static void
|
|
test_cgdcont_read_results (const gchar *desc,
|
|
const gchar *reply,
|
|
MM3gppPdpContext *expected_results,
|
|
guint32 expected_results_len)
|
|
{
|
|
GList *l;
|
|
GError *error = NULL;
|
|
GList *results;
|
|
|
|
g_debug ("Testing %s +CGDCONT response...", desc);
|
|
|
|
results = mm_3gpp_parse_cgdcont_read_response (reply, &error);
|
|
g_assert (results);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
|
|
|
|
for (l = results; l; l = g_list_next (l)) {
|
|
MM3gppPdpContext *pdp = l->data;
|
|
gboolean found = FALSE;
|
|
guint i;
|
|
|
|
for (i = 0; !found && i < expected_results_len; i++) {
|
|
MM3gppPdpContext *expected;
|
|
|
|
expected = &expected_results[i];
|
|
if (pdp->cid == expected->cid) {
|
|
found = TRUE;
|
|
|
|
g_assert_cmpuint (pdp->pdp_type, ==, expected->pdp_type);
|
|
g_assert_cmpstr (pdp->apn, ==, expected->apn);
|
|
}
|
|
}
|
|
|
|
g_assert (found == TRUE);
|
|
}
|
|
|
|
mm_3gpp_pdp_context_list_free (results);
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_read_response_nokia (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CGDCONT: 1,\"IP\",,,0,0";
|
|
static MM3gppPdpContext expected[] = {
|
|
{ 1, MM_BEARER_IP_FAMILY_IPV4, NULL }
|
|
};
|
|
|
|
test_cgdcont_read_results ("Nokia", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_read_response_samsung (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: 1,\"IP\",\"nate.sktelecom.com\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"epc.tmobile.com\",\"\",0,0\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"MAXROAM.com\",\"\",0,0\r\n";
|
|
static MM3gppPdpContext expected[] = {
|
|
{ 1, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "nate.sktelecom.com" },
|
|
{ 2, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "epc.tmobile.com" },
|
|
{ 3, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "MAXROAM.com" }
|
|
};
|
|
|
|
test_cgdcont_read_results ("Samsung", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgdcont_read_response_simcom (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CGDCONT: 1,\"IP\",\"nate.sktelecom.com\"\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"epc.tmobile.com\"\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"MAXROAM.com\"\r\n";
|
|
static MM3gppPdpContext expected[] = {
|
|
{ 1, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "nate.sktelecom.com" },
|
|
{ 2, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "epc.tmobile.com" },
|
|
{ 3, MM_BEARER_IP_FAMILY_IPV4, (gchar *) "MAXROAM.com" }
|
|
};
|
|
|
|
test_cgdcont_read_results ("Simcom", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CGDCONT read responses */
|
|
|
|
static void
|
|
test_cgact_read_results (const gchar *desc,
|
|
const gchar *reply,
|
|
MM3gppPdpContextActive *expected_results,
|
|
guint32 expected_results_len)
|
|
{
|
|
GList *l;
|
|
GError *error = NULL;
|
|
GList *results;
|
|
|
|
g_debug ("Testing %s +CGACT response...", desc);
|
|
|
|
results = mm_3gpp_parse_cgact_read_response (reply, &error);
|
|
g_assert_no_error (error);
|
|
if (expected_results_len) {
|
|
g_assert (results);
|
|
g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
|
|
}
|
|
|
|
for (l = results; l; l = g_list_next (l)) {
|
|
MM3gppPdpContextActive *pdp = l->data;
|
|
gboolean found = FALSE;
|
|
guint i;
|
|
|
|
for (i = 0; !found && i < expected_results_len; i++) {
|
|
MM3gppPdpContextActive *expected;
|
|
|
|
expected = &expected_results[i];
|
|
if (pdp->cid == expected->cid) {
|
|
found = TRUE;
|
|
g_assert_cmpuint (pdp->active, ==, expected->active);
|
|
}
|
|
}
|
|
|
|
g_assert (found == TRUE);
|
|
}
|
|
|
|
mm_3gpp_pdp_context_active_list_free (results);
|
|
}
|
|
|
|
static void
|
|
test_cgact_read_response_none (void)
|
|
{
|
|
test_cgact_read_results ("none", "", NULL, 0);
|
|
}
|
|
|
|
static void
|
|
test_cgact_read_response_single_inactive (void)
|
|
{
|
|
const gchar *reply = "+CGACT: 1,0\r\n";
|
|
static MM3gppPdpContextActive expected[] = {
|
|
{ 1, FALSE },
|
|
};
|
|
|
|
test_cgact_read_results ("single inactive", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgact_read_response_single_active (void)
|
|
{
|
|
const gchar *reply = "+CGACT: 1,1\r\n";
|
|
static MM3gppPdpContextActive expected[] = {
|
|
{ 1, TRUE },
|
|
};
|
|
|
|
test_cgact_read_results ("single active", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
static void
|
|
test_cgact_read_response_multiple (void)
|
|
{
|
|
const gchar *reply =
|
|
"+CGACT: 1,0\r\n"
|
|
"+CGACT: 4,1\r\n"
|
|
"+CGACT: 5,0\r\n";
|
|
static MM3gppPdpContextActive expected[] = {
|
|
{ 1, FALSE },
|
|
{ 4, TRUE },
|
|
{ 5, FALSE },
|
|
};
|
|
|
|
test_cgact_read_results ("multiple", reply, &expected[0], G_N_ELEMENTS (expected));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* CID selection logic */
|
|
|
|
typedef struct {
|
|
const gchar *apn;
|
|
MMBearerIpFamily ip_family;
|
|
const gchar *cgdcont_test;
|
|
const gchar *cgdcont_query;
|
|
gint expected_profile_id;
|
|
gboolean expected_profile_id_reused;
|
|
gboolean expected_profile_id_overwritten;
|
|
} ProfileSelectionTest;
|
|
|
|
static const ProfileSelectionTest profile_selection_tests[] = {
|
|
/* Test: exact APN match */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"ac.vodafone.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 2,
|
|
.expected_profile_id_reused = TRUE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: exact APN match reported as activated */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"ac.vodafone.es.MNC001.MCC214.GPRS\",\"\",0,0\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 2,
|
|
.expected_profile_id_reused = TRUE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: first empty slot in between defined contexts */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 10,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 2,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: first empty slot in between defined contexts, different PDP types */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IPV6\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 10,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 2,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: first empty slot after last context found */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 3,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: first empty slot after last context found, different PDP types */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-10),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-10),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IPV6\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 3,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = FALSE
|
|
},
|
|
/* Test: no empty slot, rewrite context with empty APN */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-3),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-3),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-3),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"\",\"\",0,0\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 2,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = TRUE
|
|
},
|
|
/* Test: no empty slot, rewrite last context found */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = "+CGDCONT: (1-3),\"IP\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-3),\"IPV6\",,,(0,1),(0,1)\r\n"
|
|
"+CGDCONT: (1-3),\"IPV4V6\",,,(0,1),(0,1)\r\n",
|
|
.cgdcont_query = "+CGDCONT: 1,\"IP\",\"telefonica.es\",\"\",0,0\r\n"
|
|
"+CGDCONT: 2,\"IP\",\"vzwinternet\",\"\",0,0\r\n"
|
|
"+CGDCONT: 3,\"IP\",\"inet.es\",\"\",0,0\r\n",
|
|
.expected_profile_id = 3,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = TRUE
|
|
},
|
|
/* Test: CGDCONT? and CGDCONT=? failures, fallback to CID=1 (a.g. some Android phones) */
|
|
{
|
|
.apn = "ac.vodafone.es",
|
|
.ip_family = MM_BEARER_IP_FAMILY_IPV4,
|
|
.cgdcont_test = NULL,
|
|
.cgdcont_query = NULL,
|
|
.expected_profile_id = 1,
|
|
.expected_profile_id_reused = FALSE,
|
|
.expected_profile_id_overwritten = TRUE
|
|
},
|
|
};
|
|
|
|
static void
|
|
test_profile_selection (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (profile_selection_tests); i++) {
|
|
const ProfileSelectionTest *test;
|
|
GList *context_format_list;
|
|
GList *context_list;
|
|
GList *profile_list;
|
|
gint profile_id;
|
|
guint min_allowed_cid = 1;
|
|
guint max_allowed_cid = G_MAXINT - 1;
|
|
g_autoptr(MM3gppProfile) requested = NULL;
|
|
g_autoptr(MM3gppProfile) reused = NULL;
|
|
gboolean profile_id_overwritten;
|
|
|
|
test = &profile_selection_tests[i];
|
|
|
|
requested = mm_3gpp_profile_new ();
|
|
mm_3gpp_profile_set_apn (requested, test->apn);
|
|
mm_3gpp_profile_set_ip_type (requested, test->ip_family);
|
|
|
|
context_format_list = test->cgdcont_test ? mm_3gpp_parse_cgdcont_test_response (test->cgdcont_test, NULL, NULL) : NULL;
|
|
mm_3gpp_pdp_context_format_list_find_range (context_format_list, test->ip_family, &min_allowed_cid, &max_allowed_cid);
|
|
|
|
context_list = test->cgdcont_query ? mm_3gpp_parse_cgdcont_read_response (test->cgdcont_query, NULL) : NULL;
|
|
profile_list = mm_3gpp_profile_list_new_from_pdp_context_list (context_list);
|
|
|
|
profile_id = mm_3gpp_profile_list_find_best (profile_list,
|
|
requested,
|
|
(GEqualFunc)mm_3gpp_cmp_apn_name,
|
|
(MM_3GPP_PROFILE_CMP_FLAGS_NO_PROFILE_ID |
|
|
MM_3GPP_PROFILE_CMP_FLAGS_NO_AUTH |
|
|
MM_3GPP_PROFILE_CMP_FLAGS_NO_APN_TYPE),
|
|
min_allowed_cid,
|
|
max_allowed_cid,
|
|
NULL, /* log_object */
|
|
&reused,
|
|
&profile_id_overwritten);
|
|
|
|
g_assert_cmpuint (profile_id, ==, test->expected_profile_id);
|
|
g_assert_cmpuint (!!reused, ==, test->expected_profile_id_reused);
|
|
g_assert_cmpuint (profile_id_overwritten, ==, test->expected_profile_id_overwritten);
|
|
|
|
mm_3gpp_profile_list_free (profile_list);
|
|
mm_3gpp_pdp_context_format_list_free (context_format_list);
|
|
mm_3gpp_pdp_context_list_free (context_list);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CPMS responses */
|
|
|
|
static gboolean
|
|
is_storage_supported (GArray *supported,
|
|
MMSmsStorage storage)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < supported->len; i++) {
|
|
if (storage == g_array_index (supported, MMSmsStorage, i))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_cinterion (void *f, gpointer d)
|
|
{
|
|
/* Use different sets for each on purpose, even if weird */
|
|
const gchar *reply = "+CPMS: (\"ME\",\"MT\"),(\"ME\",\"SM\",\"MT\"),(\"SM\",\"MT\")";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing Cinterion +CPMS=? response...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 2);
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
|
|
g_assert_cmpuint (mem2->len, ==, 3);
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_ME));
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_SM));
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_MT));
|
|
g_assert_cmpuint (mem3->len, ==, 2);
|
|
g_assert (is_storage_supported (mem3, MM_SMS_STORAGE_SM));
|
|
g_assert (is_storage_supported (mem3, MM_SMS_STORAGE_MT));
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_huawei_mu609 (void *f, gpointer d)
|
|
{
|
|
/* Use different sets for each on purpose, even if weird */
|
|
const gchar *reply = "+CPMS: \"ME\",\"MT\",\"SM\"";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing Huawei MU609 +CPMS=? response...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 1);
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
|
|
g_assert_cmpuint (mem2->len, ==, 1);
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_MT));
|
|
g_assert_cmpuint (mem3->len, ==, 1);
|
|
g_assert (is_storage_supported (mem3, MM_SMS_STORAGE_SM));
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_nokia_c6 (void *f, gpointer d)
|
|
{
|
|
/* Use different sets for each on purpose, even if weird */
|
|
const gchar *reply = "+CPMS: (),(),()";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing Nokia C6 response...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 0);
|
|
g_assert_cmpuint (mem2->len, ==, 0);
|
|
g_assert_cmpuint (mem3->len, ==, 0);
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_mixed (void *f, gpointer d)
|
|
{
|
|
/*
|
|
* First: ("ME","MT") 2-item group
|
|
* Second: "ME" 1 item
|
|
* Third: ("SM") 1-item group
|
|
*/
|
|
const gchar *reply = "+CPMS: (\"ME\",\"MT\"),\"ME\",(\"SM\")";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing mixed +CPMS=? response...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 2);
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
|
|
g_assert_cmpuint (mem2->len, ==, 1);
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_ME));
|
|
g_assert_cmpuint (mem3->len, ==, 1);
|
|
g_assert (is_storage_supported (mem3, MM_SMS_STORAGE_SM));
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_mixed_spaces (void *f, gpointer d)
|
|
{
|
|
/* Test with whitespaces here and there */
|
|
const gchar *reply = "+CPMS: ( \"ME\" , \"MT\" ) , \"ME\" , ( \"SM\" )";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing mixed +CPMS=? response with spaces...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 2);
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
|
|
g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
|
|
g_assert_cmpuint (mem2->len, ==, 1);
|
|
g_assert (is_storage_supported (mem2, MM_SMS_STORAGE_ME));
|
|
g_assert_cmpuint (mem3->len, ==, 1);
|
|
g_assert (is_storage_supported (mem3, MM_SMS_STORAGE_SM));
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
static void
|
|
test_cpms_response_empty_fields (void *f, gpointer d)
|
|
{
|
|
/*
|
|
* First: () Empty group
|
|
* Second: Empty item
|
|
* Third: ( ) Empty group with spaces
|
|
*/
|
|
const gchar *reply = "+CPMS: (),,( )";
|
|
GArray *mem1 = NULL;
|
|
GArray *mem2 = NULL;
|
|
GArray *mem3 = NULL;
|
|
GError *error = NULL;
|
|
|
|
g_debug ("Testing mixed +CPMS=? response...");
|
|
|
|
g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (mem1->len, ==, 0);
|
|
g_assert_cmpuint (mem2->len, ==, 0);
|
|
g_assert_cmpuint (mem3->len, ==, 0);
|
|
|
|
g_array_unref (mem1);
|
|
g_array_unref (mem2);
|
|
g_array_unref (mem3);
|
|
}
|
|
|
|
typedef struct {
|
|
const gchar *query;
|
|
MMSmsStorage mem1_want;
|
|
MMSmsStorage mem2_want;
|
|
} CpmsQueryTest;
|
|
|
|
CpmsQueryTest cpms_query_test[] = {
|
|
{"+CPMS: \"ME\",1,100,\"MT\",5,100,\"TA\",1,100", 2, 3},
|
|
{"+CPMS: \"SM\",100,100,\"SR\",5,10,\"TA\",1,100", 1, 4},
|
|
{"+CPMS: \"XX\",100,100,\"BM\",5,10,\"TA\",1,100", 0, 5},
|
|
{"+CPMS: \"XX\",100,100,\"YY\",5,10,\"TA\",1,100", 0, 0},
|
|
{"+CPMS: \"MT\", 0, 100, \"MT\", 0, 100, \"MT\", 0, 100", 3, 3},
|
|
};
|
|
|
|
static void
|
|
test_cpms_query_response (void *f, gpointer d) {
|
|
MMSmsStorage mem1;
|
|
MMSmsStorage mem2;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cpms_query_test); i++){
|
|
ret = mm_3gpp_parse_cpms_query_response (cpms_query_test[i].query,
|
|
&mem1,
|
|
&mem2,
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (ret);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (cpms_query_test[i].mem1_want, ==, mem1);
|
|
g_assert_cmpuint (cpms_query_test[i].mem2_want, ==, mem2);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CNUM responses */
|
|
|
|
static void
|
|
test_cnum_results (const gchar *desc,
|
|
const gchar *reply,
|
|
const GStrv expected)
|
|
{
|
|
GStrv results;
|
|
guint i;
|
|
|
|
g_debug ("Testing +CNUM response (%s)...", desc);
|
|
|
|
results = mm_3gpp_parse_cnum_exec_response (reply);
|
|
g_assert (results);
|
|
g_assert_cmpuint (g_strv_length (results), ==, g_strv_length (expected));
|
|
|
|
for (i = 0; results[i]; i++) {
|
|
guint j;
|
|
|
|
for (j = 0; expected[j]; j++) {
|
|
if (g_str_equal (results[i], expected[j]))
|
|
break;
|
|
}
|
|
|
|
/* Ensure the result is found in the expected list */
|
|
g_assert (expected[j]);
|
|
}
|
|
|
|
g_strfreev (results);
|
|
}
|
|
|
|
static void
|
|
test_cnum_response_generic (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CNUM: \"something\",\"1234567890\",161";
|
|
const gchar *expected[] = {
|
|
"1234567890",
|
|
NULL
|
|
};
|
|
|
|
test_cnum_results ("Generic", reply, (GStrv)expected);
|
|
}
|
|
|
|
static void
|
|
test_cnum_response_generic_without_detail (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CNUM: ,\"1234567890\",161";
|
|
const gchar *expected[] = {
|
|
"1234567890",
|
|
NULL
|
|
};
|
|
|
|
test_cnum_results ("Generic, without detail", reply, (GStrv)expected);
|
|
}
|
|
|
|
static void
|
|
test_cnum_response_generic_detail_unquoted (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CNUM: something,\"1234567890\",161";
|
|
const gchar *expected[] = {
|
|
"1234567890",
|
|
NULL
|
|
};
|
|
|
|
test_cnum_results ("Generic, detail unquoted", reply, (GStrv)expected);
|
|
}
|
|
|
|
static void
|
|
test_cnum_response_generic_international_number (void *f, gpointer d)
|
|
{
|
|
const gchar *reply = "+CNUM: something,\"+34600000001\",145";
|
|
const gchar *expected[] = {
|
|
"+34600000001",
|
|
NULL
|
|
};
|
|
|
|
test_cnum_results ("Generic, international number", reply, (GStrv)expected);
|
|
}
|
|
|
|
static void
|
|
test_cnum_response_generic_multiple_numbers (void *f, gpointer d)
|
|
{
|
|
const gchar *reply =
|
|
"+CNUM: something,\"+34600000001\",145\r\n"
|
|
"+CNUM: ,\"+34600000002\",145\r\n"
|
|
"+CNUM: \"another\",\"1234567890\",161";
|
|
const gchar *expected[] = {
|
|
"+34600000001",
|
|
"+34600000002",
|
|
"1234567890",
|
|
NULL
|
|
};
|
|
|
|
test_cnum_results ("Generic, multiple numbers", reply, (GStrv)expected);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test operator ID parsing */
|
|
|
|
static void
|
|
common_parse_operator_id (const gchar *operator_id,
|
|
gboolean expected_success,
|
|
guint16 expected_mcc,
|
|
guint16 expected_mnc,
|
|
gboolean expected_three_digit_mnc)
|
|
{
|
|
guint16 mcc;
|
|
guint16 mnc;
|
|
gboolean three_digit_mnc;
|
|
gboolean result;
|
|
GError *error = NULL;
|
|
|
|
if (expected_mcc) {
|
|
g_debug ("Parsing Operator ID '%s' "
|
|
"(%" G_GUINT16_FORMAT ", %" G_GUINT16_FORMAT ", %s)...",
|
|
operator_id, expected_mcc, expected_mnc, expected_three_digit_mnc ? "TRUE" : "FALSE");
|
|
result = mm_3gpp_parse_operator_id (operator_id, &mcc, &mnc, &three_digit_mnc, &error);
|
|
} else {
|
|
g_debug ("Validating Operator ID '%s'...", operator_id);
|
|
result = mm_3gpp_parse_operator_id (operator_id, NULL, NULL, NULL, &error);
|
|
}
|
|
|
|
if (error)
|
|
g_debug ("Got %s error: %s...",
|
|
expected_success ? "unexpected" : "expected",
|
|
error->message);
|
|
|
|
g_assert (result == expected_success);
|
|
|
|
if (expected_success) {
|
|
g_assert_no_error (error);
|
|
if (expected_mcc) {
|
|
g_assert_cmpuint (expected_mcc, ==, mcc);
|
|
g_assert_cmpuint (expected_mnc, ==, mnc);
|
|
g_assert_cmpint (expected_three_digit_mnc, ==, three_digit_mnc);
|
|
}
|
|
} else {
|
|
g_assert (error != NULL);
|
|
g_error_free (error);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
test_parse_operator_id (void *f, gpointer d)
|
|
{
|
|
/* Valid MCC+MNC(2) */
|
|
common_parse_operator_id ("41201", TRUE, 412, 1, FALSE);
|
|
common_parse_operator_id ("41201", TRUE, 0, 0, FALSE);
|
|
/* Valid MCC+MNC(3) */
|
|
common_parse_operator_id ("342600", TRUE, 342, 600, TRUE);
|
|
common_parse_operator_id ("342600", TRUE, 0, 0, FALSE);
|
|
/* Valid MCC+MNC(2, == 0) */
|
|
common_parse_operator_id ("72400", TRUE, 724, 0, FALSE);
|
|
common_parse_operator_id ("72400", TRUE, 0, 0, FALSE);
|
|
/* Valid MCC+MNC(3, == 0) */
|
|
common_parse_operator_id ("724000", TRUE, 724, 0, TRUE);
|
|
common_parse_operator_id ("724000", TRUE, 0, 0, FALSE);
|
|
|
|
/* Invalid MCC=0 */
|
|
common_parse_operator_id ("000600", FALSE, 0, 0, FALSE);
|
|
/* Invalid, non-digits */
|
|
common_parse_operator_id ("000Z00", FALSE, 0, 0, FALSE);
|
|
/* Invalid, short */
|
|
common_parse_operator_id ("123", FALSE, 0, 0, FALSE);
|
|
/* Invalid, long */
|
|
common_parse_operator_id ("1234567", FALSE, 0, 0, FALSE);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CDS unsolicited message parsing */
|
|
|
|
static void
|
|
common_parse_cds (const gchar *str,
|
|
guint expected_pdu_len,
|
|
const gchar *expected_pdu)
|
|
{
|
|
g_autoptr(GMatchInfo) match_info = NULL;
|
|
g_autoptr(GRegex) regex = NULL;
|
|
g_autofree gchar *pdu_len_str = NULL;
|
|
g_autofree gchar *pdu = NULL;
|
|
|
|
regex = mm_3gpp_cds_regex_get ();
|
|
g_regex_match (regex, str, 0, &match_info);
|
|
g_assert (g_match_info_matches (match_info));
|
|
|
|
pdu_len_str = g_match_info_fetch (match_info, 1);
|
|
g_assert (pdu_len_str != NULL);
|
|
g_assert_cmpuint ((guint) atoi (pdu_len_str), == , expected_pdu_len);
|
|
|
|
pdu = g_match_info_fetch (match_info, 2);
|
|
g_assert (pdu != NULL);
|
|
|
|
g_assert_cmpstr (pdu, ==, expected_pdu);
|
|
}
|
|
|
|
static void
|
|
test_parse_cds (void *f, gpointer d)
|
|
{
|
|
/* <CR><LF>+CDS: 24<CR><LF>07914356060013F1065A098136395339F6219011700463802190117004638030<CR><LF> */
|
|
common_parse_cds ("\r\n+CDS: 24\r\n07914356060013F1065A098136395339F6219011700463802190117004638030\r\n",
|
|
24,
|
|
"07914356060013F1065A098136395339F6219011700463802190117004638030");
|
|
}
|
|
|
|
typedef struct {
|
|
const char *gsn;
|
|
const char *expected_imei;
|
|
const char *expected_esn;
|
|
const char *expected_meid;
|
|
gboolean expect_success;
|
|
} TestGsnItem;
|
|
|
|
static void
|
|
test_cdma_parse_gsn (void *f, gpointer d)
|
|
{
|
|
static const TestGsnItem items[] = {
|
|
{ "0x6744775\r\n", /* leading zeros skipped, no hex digits */
|
|
NULL,
|
|
"06744775",
|
|
NULL,
|
|
TRUE },
|
|
{ "0x2214A600\r\n",
|
|
NULL,
|
|
"2214A600",
|
|
NULL,
|
|
TRUE },
|
|
{ "0x80C98A1\r\n", /* leading zeros skipped, some hex digits */
|
|
NULL,
|
|
"080C98A1",
|
|
NULL,
|
|
TRUE },
|
|
{ "6030C012\r\n", /* no leading 0x */
|
|
NULL,
|
|
"6030C012",
|
|
NULL,
|
|
TRUE },
|
|
{ "45317471585658170:2161753034\r\n0x00A1000013FB653A:0x80D9BBCA\r\n",
|
|
NULL,
|
|
"80D9BBCA",
|
|
"A1000013FB653A",
|
|
TRUE },
|
|
{ "354237065082227\r\n", /* GSM IMEI */
|
|
"354237065082227",
|
|
NULL, NULL, TRUE },
|
|
{ "356936001568843,NL2A62Z0N5\r\n", /* IMEI + serial number */
|
|
"356936001568843",
|
|
NULL, NULL, TRUE },
|
|
{ "adsfasdfasdfasdf", NULL, NULL, FALSE },
|
|
{ "0x6030Cfgh", NULL, NULL, FALSE },
|
|
{ NULL }
|
|
};
|
|
|
|
const TestGsnItem *iter;
|
|
|
|
for (iter = &items[0]; iter && iter->gsn; iter++) {
|
|
char *imei = NULL, *esn = NULL, *meid = NULL;
|
|
gboolean success;
|
|
|
|
success = mm_parse_gsn (iter->gsn, &imei, &meid, &esn);
|
|
g_assert_cmpint (success, ==, iter->expect_success);
|
|
g_assert_cmpstr (iter->expected_imei, ==, imei);
|
|
g_assert_cmpstr (iter->expected_meid, ==, meid);
|
|
g_assert_cmpstr (iter->expected_esn, ==, esn);
|
|
g_free (imei);
|
|
g_free (meid);
|
|
g_free (esn);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static gboolean
|
|
find_mode_combination (GArray *modes,
|
|
MMModemMode allowed,
|
|
MMModemMode preferred)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < modes->len; i++) {
|
|
MMModemModeCombination *mode;
|
|
|
|
mode = &g_array_index (modes, MMModemModeCombination, i);
|
|
if (mode->allowed == allowed && mode->preferred == preferred)
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static GArray *
|
|
build_mode_all (MMModemMode all_mask)
|
|
{
|
|
MMModemModeCombination all_item;
|
|
GArray *all;
|
|
|
|
all_item.allowed = all_mask;
|
|
all_item.preferred = MM_MODEM_MODE_NONE;
|
|
all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
|
|
g_array_append_val (all, all_item);
|
|
return all;
|
|
}
|
|
|
|
static void
|
|
test_supported_mode_filter (void *f, gpointer d)
|
|
{
|
|
MMModemModeCombination mode;
|
|
GArray *all;
|
|
GArray *combinations;
|
|
GArray *filtered;
|
|
|
|
/* Build array 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);
|
|
/* 4G only */
|
|
mode.allowed = MM_MODEM_MODE_4G;
|
|
mode.preferred = MM_MODEM_MODE_NONE;
|
|
g_array_append_val (combinations, mode);
|
|
/* 3G and 4G */
|
|
mode.allowed = (MM_MODEM_MODE_3G | 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);
|
|
|
|
/* Only 2G supported */
|
|
all = build_mode_all (MM_MODEM_MODE_2G);
|
|
filtered = mm_filter_supported_modes (all, combinations, NULL);
|
|
g_assert_cmpuint (filtered->len, ==, 1);
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
|
|
g_array_unref (filtered);
|
|
g_array_unref (all);
|
|
|
|
/* Only 3G supported */
|
|
all = build_mode_all (MM_MODEM_MODE_3G);
|
|
filtered = mm_filter_supported_modes (all, combinations, NULL);
|
|
g_assert_cmpuint (filtered->len, ==, 1);
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
|
|
g_array_unref (filtered);
|
|
g_array_unref (all);
|
|
|
|
/* 2G and 3G supported */
|
|
all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
|
|
filtered = mm_filter_supported_modes (all, combinations, NULL);
|
|
g_assert_cmpuint (filtered->len, ==, 3);
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), MM_MODEM_MODE_NONE));
|
|
g_array_unref (filtered);
|
|
g_array_unref (all);
|
|
|
|
/* 3G and 4G supported */
|
|
all = build_mode_all (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
|
|
filtered = mm_filter_supported_modes (all, combinations, NULL);
|
|
g_assert_cmpuint (filtered->len, ==, 3);
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
|
|
g_array_unref (filtered);
|
|
g_array_unref (all);
|
|
|
|
/* 2G, 3G and 4G supported */
|
|
all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
|
|
filtered = mm_filter_supported_modes (all, combinations, NULL);
|
|
g_assert_cmpuint (filtered->len, ==, 6);
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
|
|
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
|
|
g_array_unref (filtered);
|
|
g_array_unref (all);
|
|
|
|
g_array_unref (combinations);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CCLK responses */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
gboolean ret;
|
|
gboolean test_iso8601;
|
|
gboolean test_tz;
|
|
const gchar *iso8601;
|
|
gint32 offset;
|
|
} CclkTest;
|
|
|
|
static const CclkTest cclk_tests[] = {
|
|
{ "+CCLK: \"14/08/05,04:00:21\"", TRUE, TRUE, FALSE,
|
|
"2014-08-05T04:00:21Z", 0 },
|
|
{ "+CCLK: \"14/08/05,04:00:21\"", TRUE, FALSE, TRUE,
|
|
"2014-08-05T04:00:21+00:00", 0 },
|
|
{ "+CCLK: \"14/08/05,04:00:21\"", TRUE, TRUE, TRUE,
|
|
"2014-08-05T04:00:21Z", 0 },
|
|
|
|
{ "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, FALSE,
|
|
"2014-08-05T04:00:21+10", 600 },
|
|
{ "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, FALSE, TRUE,
|
|
"2014-08-05T04:00:21+10:00", 600 },
|
|
{ "+CCLK: \"14/08/05,04:00:21+40\"", TRUE, TRUE, TRUE,
|
|
"2014-08-05T04:00:21+10", 600 },
|
|
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, FALSE,
|
|
"2015-02-28T20:30:40-08", -480 },
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, FALSE, TRUE,
|
|
"2015-02-28T20:30:40-08", -480 },
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, TRUE,
|
|
"2015-02-28T20:30:40-08", -480 },
|
|
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, TRUE, FALSE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, FALSE, TRUE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, TRUE, TRUE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, FALSE,
|
|
"2015-02-28T20:30:40-08", -480 },
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, FALSE, TRUE,
|
|
"2015-02-28T20:30:40-08:00", -480 },
|
|
{ "+CCLK: \"15/02/28,20:30:40-32\"", TRUE, TRUE, TRUE,
|
|
"2015-02-28T20:30:40-08", -480 },
|
|
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, TRUE, FALSE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, FALSE, TRUE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
{ "+CCLK: 17/07/26,11:42:15+01", TRUE, TRUE, TRUE,
|
|
"2017-07-26T11:42:15+00:15", 15 },
|
|
|
|
{ "+CCLK: \"XX/XX/XX,XX:XX:XX+XX\"", FALSE, TRUE, FALSE,
|
|
NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN },
|
|
|
|
{ NULL, FALSE, FALSE, FALSE, NULL, MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN }
|
|
};
|
|
|
|
static void
|
|
test_cclk_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; cclk_tests[i].str; i++) {
|
|
GError *error = NULL;
|
|
gchar *iso8601 = NULL;
|
|
MMNetworkTimezone *tz = NULL;
|
|
gboolean ret;
|
|
|
|
ret = mm_parse_cclk_response (cclk_tests[i].str,
|
|
cclk_tests[i].test_iso8601 ? &iso8601 : NULL,
|
|
cclk_tests[i].test_tz ? &tz : NULL,
|
|
&error);
|
|
|
|
g_assert (ret == cclk_tests[i].ret);
|
|
g_assert (ret == (error ? FALSE : TRUE));
|
|
|
|
g_clear_error (&error);
|
|
|
|
if (cclk_tests[i].test_iso8601)
|
|
g_assert_cmpstr (cclk_tests[i].iso8601, ==, iso8601);
|
|
|
|
if (cclk_tests[i].test_tz) {
|
|
g_assert (mm_network_timezone_get_offset (tz) == cclk_tests[i].offset);
|
|
g_assert (mm_network_timezone_get_dst_offset (tz) == MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN);
|
|
g_assert (mm_network_timezone_get_leap_seconds (tz) == MM_NETWORK_TIMEZONE_LEAP_SECONDS_UNKNOWN);
|
|
}
|
|
|
|
g_free (iso8601);
|
|
|
|
if (tz)
|
|
g_object_unref (tz);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CRSM responses */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
gboolean ret;
|
|
guint sw1;
|
|
guint sw2;
|
|
const gchar *hex;
|
|
} CrsmTest;
|
|
|
|
static const CrsmTest crsm_tests[] = {
|
|
{ "+CRSM: 144, 0, 0054485552415941FFFFFFFFFFFFFFFFFF", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" },
|
|
{ "+CRSM: 144, 0,0054485552415941FFFFFFFFFFFFFFFFFF", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" },
|
|
{ "+CRSM: 144, 0, \"0054485552415941FFFFFFFFFFFFFFFFFF\"", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" },
|
|
{ "+CRSM: 144, 0,\"0054485552415941FFFFFFFFFFFFFFFFFF\"", TRUE, 144, 0, "0054485552415941FFFFFFFFFFFFFFFFFF" },
|
|
{ NULL, FALSE, 0, 0, NULL }
|
|
};
|
|
|
|
static void
|
|
test_crsm_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; crsm_tests[i].str; i++) {
|
|
GError *error = NULL;
|
|
guint sw1 = 0;
|
|
guint sw2 = 0;
|
|
gchar *hex = 0;
|
|
gboolean ret;
|
|
|
|
ret = mm_3gpp_parse_crsm_response (crsm_tests[i].str,
|
|
&sw1,
|
|
&sw2,
|
|
&hex,
|
|
&error);
|
|
|
|
g_assert (ret == crsm_tests[i].ret);
|
|
g_assert (ret == (error ? FALSE : TRUE));
|
|
|
|
g_clear_error (&error);
|
|
|
|
g_assert (sw1 == crsm_tests[i].sw1);
|
|
g_assert (sw2 == crsm_tests[i].sw2);
|
|
|
|
g_assert_cmpstr (crsm_tests[i].hex, ==, hex);
|
|
|
|
g_free (hex);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CGCONTRDP=N responses */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
guint cid;
|
|
guint bearer_id;
|
|
const gchar *apn;
|
|
const gchar *local_address;
|
|
const gchar *subnet;
|
|
const gchar *gateway_address;
|
|
const gchar *dns_primary_address;
|
|
const gchar *dns_secondary_address;
|
|
} CgcontrdpResponseTest;
|
|
|
|
static const CgcontrdpResponseTest cgcontrdp_response_tests[] = {
|
|
/* Post TS 27.007 v9.4.0 format */
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49.255.255.255.255\",\"2.197.17.49\",\"10.207.43.46\",\"10.206.56.132\",\"0.0.0.0\",\"0.0.0.0\",0",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
.dns_primary_address = "10.207.43.46",
|
|
.dns_secondary_address = "10.206.56.132",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49.255.255.255.255\",\"2.197.17.49\",\"10.207.43.46\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
.dns_primary_address = "10.207.43.46",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49.255.255.255.255\",\"2.197.17.49\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49.255.255.255.255\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
},
|
|
/* Pre TS 27.007 v9.4.0 format */
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49\",\"255.255.255.255\",\"2.197.17.49\",\"10.207.43.46\",\"10.206.56.132\",\"0.0.0.0\",\"0.0.0.0\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
.dns_primary_address = "10.207.43.46",
|
|
.dns_secondary_address = "10.206.56.132",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49\",\"255.255.255.255\",\"2.197.17.49\",\"10.207.43.46\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
.dns_primary_address = "10.207.43.46",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49\",\"255.255.255.255\",\"2.197.17.49\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
.gateway_address = "2.197.17.49",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49\",\"255.255.255.255\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
.subnet = "255.255.255.255",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\",\"2.197.17.49\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
.local_address = "2.197.17.49",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 1,5,\"internetipv6.mnc003.mcc260.gprs\",\"254.128.0.0.0.0.0.0.0.0.0.37.88.136.248.1\",\"\",\"42.1.23.0.0.2.255.255.0.0.0.0.0.0.159.1\",\"42.1.23.0.0.3.255.255.0.0.0.0.0.0.152.34\",\"\",\"\",0,0",
|
|
.cid = 1,
|
|
.bearer_id = 5,
|
|
.apn = "internetipv6.mnc003.mcc260.gprs",
|
|
.local_address = "fe80::25:5888:f801",
|
|
.dns_primary_address = "2a01:1700:2:ffff::9f01",
|
|
.dns_secondary_address = "2a01:1700:3:ffff::9822"
|
|
},
|
|
{
|
|
/* Quectel EG915Q */
|
|
.str = "+CGCONTRDP: 2,6,\"fast.t-mobile.com\",\"38.7.251.144.154.37.192.120.172.57.189.17.176.171.138.245\",,\"253.0.151.106.0.0.0.0.0.0.0.0.0.0.0.9\",\"253.0.151.106.0.0.0.0.0.0.0.0.0.0.0.16\"",
|
|
.cid = 2,
|
|
.bearer_id = 6,
|
|
.apn = "fast.t-mobile.com",
|
|
.local_address = "2607:fb90:9a25:c078:ac39:bd11:b0ab:8af5",
|
|
.dns_primary_address = "fd00:976a::9",
|
|
.dns_secondary_address = "fd00:976a::10",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 1,0,\"fast.t-mobile.com\",\"2607:FB90:B59A:02C1:0AD3:1B57:4FD4:21F4\",\"FE80:0000:0000:0000:B46D:57FF:FE45:4545\",\"fd00:976a::9\",\"fd00:976a::10\"",
|
|
.cid = 1,
|
|
.bearer_id = 0,
|
|
.apn = "fast.t-mobile.com",
|
|
.local_address = "2607:fb90:b59a:2c1:ad3:1b57:4fd4:21f4",
|
|
.gateway_address = "fe80::b46d:57ff:fe45:4545",
|
|
.dns_primary_address = "fd00:976a::9",
|
|
.dns_secondary_address = "fd00:976a::10",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 2,6,\"fast.t-mobile.com\",,,\"253.0.151.106.0.0.0.0.0.0.0.0.0.0.0.9\",\"253.0.151.106.0.0.0.0.0.0.0.0.0.0.0.16\"",
|
|
.cid = 2,
|
|
.bearer_id = 6,
|
|
.apn = "fast.t-mobile.com",
|
|
.dns_primary_address = "fd00:976a::9",
|
|
.dns_secondary_address = "fd00:976a::10",
|
|
},
|
|
/* Common */
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"ibox.tim.it.mnc001.mcc222.gprs\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
.apn = "ibox.tim.it.mnc001.mcc222.gprs",
|
|
},
|
|
{
|
|
.str = "+CGCONTRDP: 4,5,\"\"",
|
|
.cid = 4,
|
|
.bearer_id = 5,
|
|
},
|
|
};
|
|
|
|
static void
|
|
test_cgcontrdp_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cgcontrdp_response_tests); i++) {
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
guint cid = G_MAXUINT;
|
|
guint bearer_id = G_MAXUINT;
|
|
gchar *apn = NULL;
|
|
gchar *local_address = NULL;
|
|
gchar *subnet = NULL;
|
|
gchar *gateway_address = NULL;
|
|
gchar *dns_primary_address = NULL;
|
|
gchar *dns_secondary_address = NULL;
|
|
|
|
success = mm_3gpp_parse_cgcontrdp_response (cgcontrdp_response_tests[i].str,
|
|
&cid,
|
|
&bearer_id,
|
|
&apn,
|
|
&local_address,
|
|
&subnet,
|
|
&gateway_address,
|
|
&dns_primary_address,
|
|
&dns_secondary_address,
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (success);
|
|
g_assert_cmpuint (cgcontrdp_response_tests[i].cid, ==, cid);
|
|
g_assert_cmpuint (cgcontrdp_response_tests[i].bearer_id, ==, bearer_id);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].apn, ==, apn);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].local_address, ==, local_address);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].subnet, ==, subnet);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].gateway_address, ==, gateway_address);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].dns_primary_address, ==, dns_primary_address);
|
|
g_assert_cmpstr (cgcontrdp_response_tests[i].dns_secondary_address, ==, dns_secondary_address);
|
|
|
|
g_free (apn);
|
|
g_free (local_address);
|
|
g_free (subnet);
|
|
g_free (gateway_address);
|
|
g_free (dns_primary_address);
|
|
g_free (dns_secondary_address);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test CFUN? response */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
guint state;
|
|
} CfunQueryTest;
|
|
|
|
static const CfunQueryTest cfun_query_tests[] = {
|
|
{ "+CFUN: 1", 1 },
|
|
{ "+CFUN: 1,0", 1 },
|
|
{ "+CFUN: 0", 0 },
|
|
{ "+CFUN: 0,0", 0 },
|
|
{ "+CFUN: 19", 19 },
|
|
{ "+CFUN: 19,0", 19 },
|
|
};
|
|
|
|
static void
|
|
test_cfun_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cfun_query_tests); i++) {
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
guint state = G_MAXUINT;
|
|
|
|
success = mm_3gpp_parse_cfun_query_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 +CESQ responses */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
|
|
gboolean gsm_info;
|
|
guint rxlev;
|
|
gdouble rssi;
|
|
guint ber;
|
|
|
|
gboolean umts_info;
|
|
guint rscp_level;
|
|
gdouble rscp;
|
|
guint ecn0_level;
|
|
gdouble ecio;
|
|
|
|
gboolean lte_info;
|
|
guint rsrq_level;
|
|
gdouble rsrq;
|
|
guint rsrp_level;
|
|
gdouble rsrp;
|
|
} CesqResponseTest;
|
|
|
|
static const CesqResponseTest cesq_response_tests[] = {
|
|
{
|
|
.str = "+CESQ: 99,99,255,255,20,80",
|
|
.gsm_info = FALSE, .rxlev = 99, .ber = 99,
|
|
.umts_info = FALSE, .rscp_level = 255, .ecn0_level = 255,
|
|
.lte_info = TRUE, .rsrq_level = 20, .rsrq = -10.0, .rsrp_level = 80, .rsrp = -61.0,
|
|
},
|
|
{
|
|
.str = "+CESQ: 99,99,95,40,255,255",
|
|
.gsm_info = FALSE, .rxlev = 99, .ber = 99,
|
|
.umts_info = TRUE, .rscp_level = 95, .rscp = -26.0, .ecn0_level = 40, .ecio = -4.5,
|
|
.lte_info = FALSE, .rsrq_level = 255, .rsrp_level = 255,
|
|
},
|
|
{
|
|
.str = "+CESQ: 10,6,255,255,255,255",
|
|
.gsm_info = TRUE, .rxlev = 10, .rssi = -101.0, .ber = 6,
|
|
.umts_info = FALSE, .rscp_level = 255, .ecn0_level = 255,
|
|
.lte_info = FALSE, .rsrq_level = 255, .rsrp_level = 255,
|
|
},
|
|
{
|
|
/* No space after ':' */
|
|
.str = "+CESQ:10,6,255,255,255,255",
|
|
.gsm_info = TRUE, .rxlev = 10, .rssi = -101.0, .ber = 6,
|
|
.umts_info = FALSE, .rscp_level = 255, .ecn0_level = 255,
|
|
.lte_info = FALSE, .rsrq_level = 255, .rsrp_level = 255,
|
|
}
|
|
};
|
|
|
|
static void
|
|
test_cesq_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cesq_response_tests); i++) {
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
guint rxlev = G_MAXUINT;
|
|
guint ber = G_MAXUINT;
|
|
guint rscp = G_MAXUINT;
|
|
guint ecn0 = G_MAXUINT;
|
|
guint rsrq = G_MAXUINT;
|
|
guint rsrp = G_MAXUINT;
|
|
|
|
success = mm_3gpp_parse_cesq_response (cesq_response_tests[i].str,
|
|
&rxlev, &ber,
|
|
&rscp, &ecn0,
|
|
&rsrq, &rsrp,
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (success);
|
|
|
|
g_assert_cmpuint (cesq_response_tests[i].rxlev, ==, rxlev);
|
|
g_assert_cmpuint (cesq_response_tests[i].ber, ==, ber);
|
|
g_assert_cmpuint (cesq_response_tests[i].rscp_level, ==, rscp);
|
|
g_assert_cmpuint (cesq_response_tests[i].ecn0_level, ==, ecn0);
|
|
g_assert_cmpuint (cesq_response_tests[i].rsrq_level, ==, rsrq);
|
|
g_assert_cmpuint (cesq_response_tests[i].rsrp_level, ==, rsrp);
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_cesq_response_to_signal (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cesq_response_tests); i++) {
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
MMSignal *gsm = NULL;
|
|
MMSignal *umts = NULL;
|
|
MMSignal *lte = NULL;
|
|
|
|
success = mm_3gpp_cesq_response_to_signal_info (cesq_response_tests[i].str,
|
|
NULL,
|
|
&gsm, &umts, <e,
|
|
&error);
|
|
g_assert_no_error (error);
|
|
g_assert (success);
|
|
|
|
if (cesq_response_tests[i].gsm_info) {
|
|
g_assert (gsm);
|
|
g_assert_cmpfloat_tolerance (mm_signal_get_rssi (gsm), cesq_response_tests[i].rssi, 0.1);
|
|
g_object_unref (gsm);
|
|
} else
|
|
g_assert (!gsm);
|
|
|
|
if (cesq_response_tests[i].umts_info) {
|
|
g_assert (umts);
|
|
g_assert_cmpfloat_tolerance (mm_signal_get_rscp (umts), cesq_response_tests[i].rscp, 0.1);
|
|
g_assert_cmpfloat_tolerance (mm_signal_get_ecio (umts), cesq_response_tests[i].ecio, 0.1);
|
|
g_object_unref (umts);
|
|
} else
|
|
g_assert (!umts);
|
|
|
|
if (cesq_response_tests[i].lte_info) {
|
|
g_assert (lte);
|
|
g_assert_cmpfloat_tolerance (mm_signal_get_rsrq (lte), cesq_response_tests[i].rsrq, 0.1);
|
|
g_assert_cmpfloat_tolerance (mm_signal_get_rsrp (lte), cesq_response_tests[i].rsrp, 0.1);
|
|
g_object_unref (lte);
|
|
} else
|
|
g_assert (!lte);
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
MMModemPowerState state;
|
|
} CfunQueryGenericTest;
|
|
|
|
static const CfunQueryGenericTest cfun_query_generic_tests[] = {
|
|
{ "+CFUN: 1", MM_MODEM_POWER_STATE_ON },
|
|
{ "+CFUN: 1,0", MM_MODEM_POWER_STATE_ON },
|
|
{ "+CFUN: 0", MM_MODEM_POWER_STATE_OFF },
|
|
{ "+CFUN: 0,0", MM_MODEM_POWER_STATE_OFF },
|
|
{ "+CFUN: 4", MM_MODEM_POWER_STATE_LOW },
|
|
{ "+CFUN: 4,0", MM_MODEM_POWER_STATE_LOW },
|
|
};
|
|
|
|
static void
|
|
test_cfun_generic_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (cfun_query_generic_tests); i++) {
|
|
GError *error = NULL;
|
|
gboolean success;
|
|
MMModemPowerState state = MM_MODEM_POWER_STATE_UNKNOWN;
|
|
|
|
success = mm_3gpp_parse_cfun_query_generic_response (cfun_query_generic_tests[i].str, &state, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (success);
|
|
g_assert_cmpuint (cfun_query_generic_tests[i].state, ==, state);
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
const gchar *response;
|
|
gint result;
|
|
const gchar *error_message;
|
|
} CSIMResponseTest;
|
|
|
|
static CSIMResponseTest csim_response_test_list [] = {
|
|
/* The parser expects that 2nd arg contains
|
|
* substring "63Cx" where x is an HEX string
|
|
* representing the retry value */
|
|
{"+CSIM:8,\"000063C1\"", 1, NULL},
|
|
{"+CSIM:8,\"000063CA\"", 10, NULL},
|
|
{"+CSIM:8,\"000063CF\"", 15, NULL},
|
|
/* The parser accepts spaces */
|
|
{"+CSIM:8, \"000063C1\"", 1, NULL},
|
|
{"+CSIM: 8, \"000063C1\"", 1, NULL},
|
|
{"+CSIM: 8, \"000063C1\"", 1, NULL},
|
|
/* the parser expects an int as first argument (2nd arg's length),
|
|
* but does not check if it is correct */
|
|
{"+CSIM: 10, \"63CF\"", 15, NULL},
|
|
/* Valid +CSIM Error codes */
|
|
{"+CSIM: 4, \"6300\"", -1, "SIM verification failed"},
|
|
{"+CSIM: 4, \"6983\"", -1, "SIM authentication method blocked"},
|
|
{"+CSIM: 4, \"6984\"", -1, "SIM reference data invalidated"},
|
|
{"+CSIM: 4, \"6A86\"", -1, "Incorrect parameters in SIM request"},
|
|
{"+CSIM: 4, \"6A88\"", -1, "SIM reference data not found"},
|
|
/* Test error: missing first argument */
|
|
{"+CSIM:000063CF\"", -1, "Could not recognize +CSIM response '+CSIM:000063CF\"'"},
|
|
/* Test error: missing quotation mark */
|
|
{"+CSIM: 8, 000063CF", -1, "Could not recognize +CSIM response '+CSIM: 8, 000063CF'"},
|
|
/* Test generic error */
|
|
{"+CSIM: 4, \"63BF\"", -1, "Unknown error returned '0x63bf'"},
|
|
{"+CSIM: 4, \"63D0\"", -1, "Unknown error returned '0x63d0'"}
|
|
};
|
|
|
|
static void
|
|
test_csim_response (void)
|
|
{
|
|
guint i;
|
|
gint res;
|
|
GError* error = NULL;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (csim_response_test_list); i++) {
|
|
res = mm_parse_csim_response (csim_response_test_list[i].response, &error);
|
|
|
|
if (csim_response_test_list[i].error_message == NULL) {
|
|
g_assert_no_error (error);
|
|
} else {
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
|
|
g_assert_cmpstr (error->message, ==, csim_response_test_list[i].error_message);
|
|
g_clear_error (&error);
|
|
}
|
|
|
|
g_assert_cmpint (res, ==, csim_response_test_list[i].result);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* +CLIP URC */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
const gchar *number;
|
|
guint type;
|
|
} ClipUrcTest;
|
|
|
|
static const ClipUrcTest clip_urc_tests[] = {
|
|
{ "\r\n+CLIP: \"123456789\",129\r\n", "123456789", 129 },
|
|
{ "\r\n+CLIP: \"123456789\",129,,,,0\r\n", "123456789", 129 },
|
|
};
|
|
|
|
static void
|
|
test_clip_indication (void)
|
|
{
|
|
g_autoptr(GRegex) r = NULL;
|
|
guint i;
|
|
|
|
r = mm_voice_clip_regex_get ();
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (clip_urc_tests); i++) {
|
|
g_autoptr(GMatchInfo) match_info = NULL;
|
|
g_autofree gchar *number = NULL;
|
|
guint type;
|
|
|
|
g_assert (g_regex_match (r, clip_urc_tests[i].str, 0, &match_info));
|
|
g_assert (g_match_info_matches (match_info));
|
|
|
|
number = mm_get_string_unquoted_from_match_info (match_info, 1);
|
|
g_assert_cmpstr (number, ==, clip_urc_tests[i].number);
|
|
|
|
g_assert (mm_get_uint_from_match_info (match_info, 2, &type));
|
|
g_assert_cmpuint (type, ==, clip_urc_tests[i].type);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* +CCWA URC */
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
const gchar *number;
|
|
guint type;
|
|
guint class;
|
|
} CcwaUrcTest;
|
|
|
|
static const CcwaUrcTest ccwa_urc_tests[] = {
|
|
{ "\r\n+CCWA: \"123456789\",129,1\r\n", "123456789", 129, 1 },
|
|
{ "\r\n+CCWA: \"123456789\",129,1,,0\r\n", "123456789", 129, 1 },
|
|
{ "\r\n+CCWA: \"123456789\",129,1,,0,,,\r\n", "123456789", 129, 1 },
|
|
};
|
|
|
|
static void
|
|
test_ccwa_indication (void)
|
|
{
|
|
g_autoptr(GRegex) r = NULL;
|
|
guint i;
|
|
|
|
r = mm_voice_ccwa_regex_get ();
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (ccwa_urc_tests); i++) {
|
|
g_autoptr(GMatchInfo) match_info = NULL;
|
|
g_autofree gchar *number = NULL;
|
|
guint type;
|
|
guint class;
|
|
|
|
g_assert (g_regex_match (r, ccwa_urc_tests[i].str, 0, &match_info));
|
|
g_assert (g_match_info_matches (match_info));
|
|
|
|
number = mm_get_string_unquoted_from_match_info (match_info, 1);
|
|
g_assert_cmpstr (number, ==, ccwa_urc_tests[i].number);
|
|
|
|
g_assert (mm_get_uint_from_match_info (match_info, 2, &type));
|
|
g_assert_cmpuint (type, ==, ccwa_urc_tests[i].type);
|
|
|
|
g_assert (mm_get_uint_from_match_info (match_info, 3, &class));
|
|
g_assert_cmpuint (class, ==, ccwa_urc_tests[i].class);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* +CCWA service query response testing */
|
|
|
|
static void
|
|
common_test_ccwa_response (const gchar *response,
|
|
gboolean expected_status,
|
|
gboolean expected_error)
|
|
{
|
|
gboolean status = FALSE;
|
|
GError *error = NULL;
|
|
gboolean result;
|
|
|
|
result = mm_3gpp_parse_ccwa_service_query_response (response, NULL, &status, &error);
|
|
|
|
if (expected_error) {
|
|
g_assert (!result);
|
|
g_assert (error);
|
|
g_error_free (error);
|
|
} else {
|
|
g_assert (result);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (status, ==, expected_status);
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
const gchar *response;
|
|
gboolean expected_status;
|
|
gboolean expected_error;
|
|
} TestCcwa;
|
|
|
|
static TestCcwa test_ccwa[] = {
|
|
{ "+CCWA: 0,255\r\n", FALSE, FALSE }, /* all disabled */
|
|
{ "+CCWA: 1,255\r\n", TRUE, FALSE }, /* all enabled */
|
|
{ "+CCWA: 0,1\r\n"
|
|
"+CCWA: 0,4\r\n", FALSE, FALSE }, /* voice and fax disabled */
|
|
{ "+CCWA: 1,1\r\n"
|
|
"+CCWA: 1,4\r\n", TRUE, FALSE }, /* voice and fax enabled */
|
|
{ "+CCWA: 0,2\r\n"
|
|
"+CCWA: 0,4\r\n"
|
|
"+CCWA: 0,8\r\n", FALSE, TRUE }, /* data, fax, sms disabled, voice not given */
|
|
{ "+CCWA: 1,2\r\n"
|
|
"+CCWA: 1,4\r\n"
|
|
"+CCWA: 1,8\r\n", FALSE, TRUE }, /* data, fax, sms enabled, voice not given */
|
|
{ "+CCWA: 2,1\r\n"
|
|
"+CCWA: 2,4\r\n", FALSE, TRUE }, /* voice and fax enabled but unexpected state */
|
|
};
|
|
|
|
static void
|
|
test_ccwa_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_ccwa); i++)
|
|
common_test_ccwa_response (test_ccwa[i].response, test_ccwa[i].expected_status, test_ccwa[i].expected_error);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CSCB channel lists */
|
|
|
|
typedef struct {
|
|
const gchar *response;
|
|
const MMCellBroadcastChannels *channels;
|
|
guint len;
|
|
gboolean error;
|
|
} TestCscb;
|
|
|
|
static void
|
|
common_test_cscb_response (const gchar *response, TestCscb *expected)
|
|
{
|
|
GError *error = NULL;
|
|
g_autoptr(GArray) result = NULL;
|
|
|
|
g_debug ("Testing '%s'", response);
|
|
result = mm_3gpp_parse_cscb_response (response, &error);
|
|
|
|
if (expected->error) {
|
|
g_assert (!result);
|
|
g_assert_nonnull (error);
|
|
g_error_free (error);
|
|
} else {
|
|
guint i;
|
|
|
|
g_assert_no_error (error);
|
|
g_assert (result);
|
|
g_assert_cmpint (result->len, ==, expected->len);
|
|
for (i = 0; i < expected->len; i++) {
|
|
MMCellBroadcastChannels ch = g_array_index (result, MMCellBroadcastChannels, i);
|
|
|
|
g_assert_cmpuint (ch.start, ==, expected->channels[i].start);
|
|
g_assert_cmpuint (ch.end, ==, expected->channels[i].end);
|
|
}
|
|
}
|
|
}
|
|
|
|
static const MMCellBroadcastChannels cscb_one_channel[] = {
|
|
{ .start = 0, .end = 0 },
|
|
};
|
|
|
|
static const MMCellBroadcastChannels cscb_all_channels[] = {
|
|
{ .start = 0, .end = 65535 },
|
|
};
|
|
|
|
static const MMCellBroadcastChannels cscb_interval_channels[] = {
|
|
{ .start = 0, .end = 1 },
|
|
{ .start = 100, .end = 200 },
|
|
};
|
|
|
|
static const MMCellBroadcastChannels cscb_dell5821e_channels[] = {
|
|
{ .start = 4383, .end = 4383 },
|
|
{ .start = 4400, .end = 4400 },
|
|
{ .start = 4370, .end = 4370 },
|
|
{ .start = 4371, .end = 4378 },
|
|
{ .start = 4384, .end = 4391 },
|
|
{ .start = 4396, .end = 4397 },
|
|
};
|
|
|
|
static TestCscb test_cscb[] = {
|
|
{ "\r\n+CSCB: 0, \"0\",\"\"\r\n\r\nOK\r\n", /* one channel */
|
|
cscb_one_channel,
|
|
G_N_ELEMENTS (cscb_all_channels),
|
|
FALSE },
|
|
{ "+CSCB: 0,\"0-65535\",\"\"\r\n", /* all channels */
|
|
cscb_all_channels,
|
|
G_N_ELEMENTS (cscb_all_channels),
|
|
FALSE },
|
|
{ "+CSCB: 0,\"0-1,100-200\",\"\"\r\n", /* intervals */
|
|
cscb_interval_channels,
|
|
G_N_ELEMENTS (cscb_interval_channels),
|
|
FALSE },
|
|
/* Dell 5821e/T77W968 defaults */
|
|
{ "+CSCB: 0, \"4383,4400,4370,4371-4378,4384-4391,4396-4397\",\"\"",
|
|
cscb_dell5821e_channels,
|
|
G_N_ELEMENTS (cscb_dell5821e_channels),
|
|
FALSE },
|
|
{ "+CSCB: 0,\"0-\",\"\"\r\n", /* broken interval */
|
|
NULL,
|
|
0,
|
|
TRUE },
|
|
};
|
|
|
|
static void
|
|
test_cscb_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_cscb); i++)
|
|
common_test_cscb_response (test_cscb[i].response, &test_cscb[i]);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CLCC URCs */
|
|
|
|
static void
|
|
common_test_clcc_response (const gchar *str,
|
|
const MMCallInfo *expected_call_info_list,
|
|
guint expected_call_info_list_size)
|
|
{
|
|
GError *error = NULL;
|
|
gboolean result;
|
|
GList *call_info_list = NULL;
|
|
GList *l;
|
|
|
|
result = mm_3gpp_parse_clcc_response (str, NULL, &call_info_list, &error);
|
|
g_assert_no_error (error);
|
|
g_assert (result);
|
|
|
|
g_debug ("found %u calls", g_list_length (call_info_list));
|
|
|
|
if (expected_call_info_list) {
|
|
g_assert (call_info_list);
|
|
g_assert_cmpuint (g_list_length (call_info_list), ==, expected_call_info_list_size);
|
|
} else
|
|
g_assert (!call_info_list);
|
|
|
|
for (l = call_info_list; l; l = g_list_next (l)) {
|
|
const MMCallInfo *call_info = (const MMCallInfo *)(l->data);
|
|
gboolean found = FALSE;
|
|
guint i;
|
|
|
|
g_debug ("call at index %u: direction %s, state %s, number %s",
|
|
call_info->index,
|
|
mm_call_direction_get_string (call_info->direction),
|
|
mm_call_state_get_string (call_info->state),
|
|
call_info->number ? call_info->number : "n/a");
|
|
|
|
for (i = 0; !found && i < expected_call_info_list_size; i++)
|
|
found = ((call_info->index == expected_call_info_list[i].index) &&
|
|
(call_info->direction == expected_call_info_list[i].direction) &&
|
|
(call_info->state == expected_call_info_list[i].state) &&
|
|
(g_strcmp0 (call_info->number, expected_call_info_list[i].number) == 0));
|
|
|
|
g_assert (found);
|
|
}
|
|
|
|
mm_3gpp_call_info_list_free (call_info_list);
|
|
}
|
|
|
|
static void
|
|
test_clcc_response_empty (void)
|
|
{
|
|
const gchar *response = "\r\n";
|
|
|
|
common_test_clcc_response (response, NULL, 0);
|
|
}
|
|
|
|
static void
|
|
test_clcc_response_single (void)
|
|
{
|
|
static const MMCallInfo expected_call_info_list[] = {
|
|
{ 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, (gchar *) "123456789" }
|
|
};
|
|
|
|
const gchar *response =
|
|
"+CLCC: 1,1,0,0,0,\"123456789\",161\r\n";
|
|
|
|
common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list));
|
|
}
|
|
|
|
static void
|
|
test_clcc_response_single_long (void)
|
|
{
|
|
static const MMCallInfo expected_call_info_list[] = {
|
|
{ 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_RINGING_IN, (gchar *) "123456789" }
|
|
};
|
|
|
|
/* NOTE: priority field is EMPTY */
|
|
const gchar *response =
|
|
"+CLCC: 1,1,4,0,0,\"123456789\",129,\"\",,0\r\n";
|
|
|
|
common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list));
|
|
}
|
|
|
|
static void
|
|
test_clcc_response_multiple (void)
|
|
{
|
|
static const MMCallInfo expected_call_info_list[] = {
|
|
{ 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, NULL },
|
|
{ 2, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, (gchar *) "123456789" },
|
|
{ 3, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, (gchar *) "987654321" },
|
|
{ 4, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, (gchar *) "000000000" },
|
|
{ 5, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_WAITING, (gchar *) "555555555" },
|
|
};
|
|
|
|
const gchar *response =
|
|
"+CLCC: 1,1,0,0,1\r\n" /* number unknown */
|
|
"+CLCC: 2,1,0,0,1,\"123456789\",161\r\n"
|
|
"+CLCC: 3,1,0,0,1,\"987654321\",161,\"Alice\"\r\n"
|
|
"+CLCC: 4,1,0,0,1,\"000000000\",161,\"Bob\",1\r\n"
|
|
"+CLCC: 5,1,5,0,0,\"555555555\",161,\"Mallory\",2,0\r\n";
|
|
|
|
common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list));
|
|
}
|
|
|
|
static void
|
|
test_clcc_response_ignore_non_voice (void)
|
|
{
|
|
static const MMCallInfo expected_call_info_list[] = {
|
|
{ 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_RINGING_IN, (gchar *) "987654321" },
|
|
{ 4, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_RINGING_IN, (gchar *) "111111111" },
|
|
{ 5, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_RINGING_IN, (gchar *) "222222222" },
|
|
{ 6, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_RINGING_IN, (gchar *) "333333333" },
|
|
};
|
|
|
|
const gchar *response =
|
|
"+CLCC: 1,1,4,0,0,\"987654321\",161\r\n" /* voice mode */
|
|
"+CLCC: 2,1,4,1,0,\"123456789\",161\r\n" /* data mode, skip */
|
|
"+CLCC: 3,1,4,2,0,\"000000000\",161\r\n" /* fax data, skip */
|
|
"+CLCC: 4,1,4,3,0,\"111111111\",161\r\n" /* voice followed by data, voice mode */
|
|
"+CLCC: 5,1,4,4,0,\"222222222\",161\r\n" /* alternating voice/data, voice mode */
|
|
"+CLCC: 6,1,4,5,0,\"333333333\",161\r\n" /* alternating voice/fax, voice mode */
|
|
"+CLCC: 7,1,4,6,0,\"444444444\",161\r\n" /* voice followed by data, data mode, skip */
|
|
"+CLCC: 8,1,4,7,0,\"555555555\",161\r\n" /* alternating voice/data, data mode, skip */
|
|
"+CLCC: 9,1,4,8,0,\"666666666\",161\r\n" /* alternating voice/fax, fax mode, skip */
|
|
"+CLCC: 10,1,4,9,0,\"777777777\",161\r\n"; /* unknown mode, skip */
|
|
|
|
common_test_clcc_response (response, expected_call_info_list, G_N_ELEMENTS (expected_call_info_list));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test +CRSM EF_ECC read data parsing */
|
|
|
|
#define MAX_EMERGENCY_NUMBERS 5
|
|
typedef struct {
|
|
const gchar *raw;
|
|
guint n_numbers;
|
|
const gchar *numbers[MAX_EMERGENCY_NUMBERS];
|
|
} EmergencyNumbersTest;
|
|
|
|
static const EmergencyNumbersTest emergency_numbers_tests[] = {
|
|
{ "", 0 },
|
|
{ "FFF", 0 },
|
|
{ "FFFFFF" "FFFFFF" "FFFFFF" "FFFFFF" "FFFFFF", 0 },
|
|
{ "00F0FF" "11F2FF" "88F8FF", 3, { "000", "112", "888" } },
|
|
{ "00F0FF" "11F2FF" "88F8FF" "FFFFFF" "FFFFFF", 3, { "000", "112", "888" } },
|
|
{ "00F0FF" "11F2FF" "88F8FF" "214365" "08FFFF", 5, { "000", "112", "888", "123456", "80" } },
|
|
};
|
|
|
|
static void
|
|
test_emergency_numbers (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (emergency_numbers_tests); i++) {
|
|
GStrv numbers;
|
|
g_autoptr(GError) error = NULL;
|
|
guint j;
|
|
|
|
g_debug (" testing %s...", emergency_numbers_tests[i].raw);
|
|
|
|
numbers = mm_3gpp_parse_emergency_numbers (emergency_numbers_tests[i].raw, &error);
|
|
if (!emergency_numbers_tests[i].n_numbers) {
|
|
g_assert (error);
|
|
g_assert (!numbers);
|
|
continue;
|
|
}
|
|
|
|
g_assert_no_error (error);
|
|
g_assert (numbers);
|
|
|
|
g_assert_cmpuint (emergency_numbers_tests[i].n_numbers, ==, g_strv_length (numbers));
|
|
for (j = 0; j < emergency_numbers_tests[i].n_numbers; j++)
|
|
g_assert_cmpstr (emergency_numbers_tests[i].numbers[j], ==, numbers[j]);
|
|
|
|
g_strfreev (numbers);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
gint expected_number_list[9];
|
|
} TestParseNumberList;
|
|
|
|
static const TestParseNumberList test_parse_number_list_item [] = {
|
|
{ "1-6", { 1, 2, 3, 4, 5, 6, -1 } },
|
|
{ "0,1,2,4,6", { 0, 1, 2, 4, 6, -1 } },
|
|
{ "1,3-5,7,9-11", { 1, 3, 4, 5, 7, 9, 10, 11, -1 } },
|
|
{ "9-11,7,3-5", { 3, 4, 5, 7, 9, 10, 11, -1 } },
|
|
{ "", { -1 } },
|
|
{ NULL, { -1 } },
|
|
};
|
|
|
|
static void
|
|
test_parse_uint_list (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_parse_number_list_item); i++) {
|
|
GArray *array;
|
|
GError *error = NULL;
|
|
guint j;
|
|
|
|
array = mm_parse_uint_list (test_parse_number_list_item[i].str, &error);
|
|
g_assert_no_error (error);
|
|
if (test_parse_number_list_item[i].expected_number_list[0] == -1) {
|
|
g_assert (!array);
|
|
continue;
|
|
}
|
|
|
|
g_assert (array);
|
|
for (j = 0; j < array->len; j++) {
|
|
g_assert_cmpint (test_parse_number_list_item[i].expected_number_list[j], !=, -1);
|
|
g_assert_cmpuint (test_parse_number_list_item[i].expected_number_list[j], ==, g_array_index (array, guint, j));
|
|
}
|
|
g_assert_cmpint (test_parse_number_list_item[i].expected_number_list[array->len], ==, -1);
|
|
g_array_unref (array);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const guint8 bcd[10];
|
|
gsize bcd_len;
|
|
const gchar *low_nybble_first_str;
|
|
const gchar *high_nybble_first_str;
|
|
} BcdToStringTest;
|
|
|
|
static const BcdToStringTest bcd_to_string_tests[] = {
|
|
{ { }, 0, "", "" },
|
|
{ { 0x01 }, 1, "10", "01" },
|
|
{ { 0x1F }, 1, "", "1" },
|
|
{ { 0xE2 }, 1, "2", "" },
|
|
{ { 0xD3 }, 1, "3", "" },
|
|
{ { 0xC4 }, 1, "4", "" },
|
|
{ { 0xB1, 0x23 }, 2, "1", "" },
|
|
{ { 0x01, 0x2A }, 2, "10", "012" },
|
|
{ { 0x01, 0x23, 0x45, 0x67 }, 4, "10325476", "01234567" },
|
|
{ { 0x01, 0x23, 0x45, 0xA7 }, 4, "1032547", "012345" },
|
|
{ { 0x01, 0x23, 0x45, 0x67 }, 2, "1032", "0123" },
|
|
};
|
|
|
|
static void
|
|
test_bcd_to_string (void *f, gpointer d)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (bcd_to_string_tests); i++) {
|
|
gchar *str;
|
|
|
|
str = mm_bcd_to_string (bcd_to_string_tests[i].bcd,
|
|
bcd_to_string_tests[i].bcd_len,
|
|
TRUE /* low_nybble_first */);
|
|
g_assert_cmpstr (str, ==, bcd_to_string_tests[i].low_nybble_first_str);
|
|
g_free (str);
|
|
|
|
str = mm_bcd_to_string (bcd_to_string_tests[i].bcd,
|
|
bcd_to_string_tests[i].bcd_len,
|
|
FALSE /* low_nybble_first */);
|
|
g_assert_cmpstr (str, ==, bcd_to_string_tests[i].high_nybble_first_str);
|
|
g_free (str);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *input;
|
|
const gchar *expected;
|
|
} AtQuoteStringTest;
|
|
|
|
static const AtQuoteStringTest at_quote_string_tests[] = {
|
|
{ "", "\"\"" },
|
|
{ "internet", "\"internet\"" },
|
|
{ "\"internet", "\"\\22internet\"" }, /* double quote is \22 */
|
|
{ "\r\ninternet", "\"\\0D\\0Ainternet\"" }, /* CRLF is \0D\0A */
|
|
{ "\r\ninternet\r\n", "\"\\0D\\0Ainternet\\0D\\0A\"" }, /* CRLF is \0D\0A */
|
|
};
|
|
|
|
static void
|
|
test_at_quote_string (void *f, gpointer d)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (at_quote_string_tests); i++) {
|
|
g_autofree gchar *str = NULL;
|
|
|
|
str = mm_at_quote_string (at_quote_string_tests[i].input);
|
|
g_assert_cmpstr (str, ==, at_quote_string_tests[i].expected);
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_remove_control_characters (void *f, gpointer d)
|
|
{
|
|
gchar str1[] = "hello\r\nworld";
|
|
gchar str2[] = "no_controls";
|
|
gchar str3[] = "\r\n\t";
|
|
|
|
mm_utils_remove_control_characters (str1);
|
|
g_assert_cmpstr (str1, ==, "helloworld");
|
|
|
|
mm_utils_remove_control_characters (str2);
|
|
g_assert_cmpstr (str2, ==, "no_controls");
|
|
|
|
mm_utils_remove_control_characters (str3);
|
|
g_assert_cmpstr (str3, ==, "");
|
|
|
|
mm_utils_remove_control_characters (NULL);
|
|
}
|
|
|
|
static void
|
|
test_is_valid_fqdn (void *f, gpointer d)
|
|
{
|
|
g_assert (mm_utils_is_valid_fqdn ("google.com"));
|
|
g_assert (mm_utils_is_valid_fqdn ("a.b.c.d"));
|
|
g_assert (mm_utils_is_valid_fqdn ("valid-host.com"));
|
|
g_assert (mm_utils_is_valid_fqdn ("123.com"));
|
|
g_assert (mm_utils_is_valid_fqdn ("a"));
|
|
|
|
g_assert (!mm_utils_is_valid_fqdn (NULL));
|
|
g_assert (!mm_utils_is_valid_fqdn (""));
|
|
g_assert (!mm_utils_is_valid_fqdn ("invalid host.com"));
|
|
g_assert (!mm_utils_is_valid_fqdn ("host;com"));
|
|
g_assert (!mm_utils_is_valid_fqdn ("host\rcom"));
|
|
g_assert (!mm_utils_is_valid_fqdn ("host/com"));
|
|
}
|
|
|
|
static void
|
|
test_is_numeric (void *f, gpointer d)
|
|
{
|
|
g_assert (mm_utils_is_numeric ("123456"));
|
|
g_assert (mm_utils_is_numeric ("0"));
|
|
g_assert (mm_utils_is_numeric ("0123456789"));
|
|
|
|
g_assert (!mm_utils_is_numeric (NULL));
|
|
g_assert (!mm_utils_is_numeric (""));
|
|
g_assert (!mm_utils_is_numeric ("123a45"));
|
|
g_assert (!mm_utils_is_numeric ("123 45"));
|
|
g_assert (!mm_utils_is_numeric ("123\r45"));
|
|
g_assert (!mm_utils_is_numeric ("+123"));
|
|
}
|
|
|
|
static void
|
|
test_is_valid_dial_number (void *f, gpointer d)
|
|
{
|
|
GError *error = NULL;
|
|
gboolean r;
|
|
|
|
r = mm_utils_is_valid_dial_number ("123456", &error);
|
|
g_assert (r);
|
|
g_assert_no_error (error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("+123456", &error);
|
|
g_assert (r);
|
|
g_assert_no_error (error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("*123#", &error);
|
|
g_assert (r);
|
|
g_assert_no_error (error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123,456", &error);
|
|
g_assert (r);
|
|
g_assert_no_error (error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123W456", &error);
|
|
g_assert (r);
|
|
g_assert_no_error (error);
|
|
|
|
r = mm_utils_is_valid_dial_number (NULL, &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("", &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123;456", &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123\r456", &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123\n456", &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
|
|
r = mm_utils_is_valid_dial_number ("123\x01" "456", &error);
|
|
g_assert (!r);
|
|
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
|
g_clear_error (&error);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *response;
|
|
gboolean expected_error;
|
|
guint expected_index;
|
|
const gchar *expected_operator_code;
|
|
gboolean expected_gsm_act;
|
|
gboolean expected_gsm_compact_act;
|
|
gboolean expected_utran_act;
|
|
gboolean expected_eutran_act;
|
|
gboolean expected_ngran_act;
|
|
guint expected_act_count;
|
|
} TestCpol;
|
|
|
|
static const TestCpol test_cpol[] = {
|
|
{ "+CPOL: 1,2,\"24412\",0,0,0,0", FALSE, 1, "24412", FALSE, FALSE, FALSE, FALSE, FALSE, 4 },
|
|
{ "+CPOL: 1,2,24412,0,0,0,0", FALSE, 1, "24412", FALSE, FALSE, FALSE, FALSE, FALSE, 4 },
|
|
{ "+CPOL: 1", TRUE },
|
|
{ "+CPOL: 1,2", TRUE },
|
|
{ "+CPOL: 1,1,\"Test\"", TRUE },
|
|
{ "+CPOL: 5,2,123456,0,0,0,0,1", FALSE, 5, "123456", FALSE, FALSE, FALSE, FALSE, TRUE, 5 },
|
|
{ "+CPOL: 99,2,\"63423\",1,0,1,0,1", FALSE, 99, "63423", TRUE, FALSE, TRUE, FALSE, TRUE, 5 },
|
|
{ "+CPOL: 101,2,\"63423\",1,1,1", FALSE, 101, "63423", TRUE, TRUE, TRUE, FALSE, FALSE, 3 },
|
|
{ "+CPOL: 101,2,\"24491\"", FALSE, 101, "24491", FALSE, FALSE, FALSE, FALSE, FALSE, 0 },
|
|
{ "+CPOL: X,2,\"24491\"", TRUE },
|
|
{ "+CPOL:1, 2, 12345, 1, 1, 1, 1, 1", FALSE, 1, "12345", TRUE, TRUE, TRUE, TRUE, TRUE, 5 }
|
|
};
|
|
|
|
static void
|
|
test_cpol_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_cpol); i++) {
|
|
guint index;
|
|
gchar *operator_code = NULL;
|
|
gboolean gsm_act;
|
|
gboolean gsm_compact_act;
|
|
gboolean utran_act;
|
|
gboolean eutran_act;
|
|
gboolean ngran_act;
|
|
guint act_count;
|
|
gboolean result;
|
|
GError *error = NULL;
|
|
|
|
result = mm_sim_parse_cpol_query_response (test_cpol[i].response,
|
|
&index,
|
|
&operator_code,
|
|
&gsm_act,
|
|
&gsm_compact_act,
|
|
&utran_act,
|
|
&eutran_act,
|
|
&ngran_act,
|
|
&act_count,
|
|
&error);
|
|
if (test_cpol[i].expected_error) {
|
|
g_assert (!result);
|
|
g_assert (error);
|
|
g_error_free (error);
|
|
} else {
|
|
g_assert (result);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpuint (index, ==, test_cpol[i].expected_index);
|
|
g_assert_cmpstr (operator_code, ==, test_cpol[i].expected_operator_code);
|
|
g_assert_cmpuint (gsm_act, ==, test_cpol[i].expected_gsm_act);
|
|
g_assert_cmpuint (gsm_compact_act, ==, test_cpol[i].expected_gsm_compact_act);
|
|
g_assert_cmpuint (utran_act, ==, test_cpol[i].expected_utran_act);
|
|
g_assert_cmpuint (eutran_act, ==, test_cpol[i].expected_eutran_act);
|
|
g_assert_cmpuint (ngran_act, ==, test_cpol[i].expected_ngran_act);
|
|
g_assert_cmpuint (act_count, ==, test_cpol[i].expected_act_count);
|
|
}
|
|
g_free (operator_code);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *response;
|
|
gboolean expected_empty;
|
|
const gchar *expected_groups[4];
|
|
} TestStringGroup;
|
|
|
|
static const TestStringGroup test_groups[] = {
|
|
{ "(\"SM\",\"ME\"),(\"SM\",\"ME\"),(\"SM\",\"ME\")", FALSE, { "\"SM\",\"ME\"", "\"SM\",\"ME\"", "\"SM\",\"ME\"", NULL } },
|
|
{ "\"SM\",\"SM\",\"SM\"", FALSE, { "\"SM\"", "\"SM\"", "\"SM\"", NULL } },
|
|
{ "\"SM\",(\"SM\",\"ME\"),(\"SM\",\"ME\")", FALSE, { "\"SM\"", "\"SM\",\"ME\"", "\"SM\",\"ME\"", NULL } },
|
|
{ "", FALSE, { "", NULL } },
|
|
{ ",,", FALSE, { "", "", "", NULL } },
|
|
{ "(A,B", FALSE, { "A,B", NULL } },
|
|
{ "A,B)", FALSE, { "A", "B)", NULL } },
|
|
{ NULL, TRUE, { NULL } },
|
|
};
|
|
|
|
static void
|
|
test_mm_split_string_groups (void)
|
|
{
|
|
guint i, j;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_groups); i++) {
|
|
g_auto(GStrv) groups = NULL;
|
|
|
|
groups = mm_split_string_groups (test_groups[i].response);
|
|
if (test_groups[i].expected_empty) {
|
|
g_assert_null (groups);
|
|
} else {
|
|
g_assert (groups);
|
|
g_assert_cmpint (g_strv_length (groups), ==, g_strv_length ((gchar **) test_groups[i].expected_groups));
|
|
for (j = 0; j < g_strv_length (groups); j++) {
|
|
g_assert_cmpstr (groups[j], ==, test_groups[i].expected_groups[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const guint8 bin_array[10];
|
|
gsize bin_len;
|
|
const gchar *expected_name;
|
|
gboolean expected_error;
|
|
} TestSpnData;
|
|
|
|
static const TestSpnData test_spn_data[] = {
|
|
{ { 0, 'T', 'e', 's', 't', 0xff, 0xff, 0xff, 0xff, 0xff }, 10, "Test", FALSE },
|
|
{ { 'T', 'e', 's', 't', 0xff, 0xff }, 6, "est", FALSE },
|
|
{ { 0, 0, '$', 'T', 'e', 's', 't' }, 7, "@¤Test", FALSE },
|
|
{ { 0 }, 0, "", TRUE },
|
|
{ { 0, 0xff }, 2, "", TRUE },
|
|
{ { 0xff, 0xff }, 2, "", TRUE },
|
|
};
|
|
|
|
static void
|
|
test_spn_to_utf8 (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_spn_data); i++) {
|
|
gchar *result = NULL;
|
|
GError *error = NULL;
|
|
|
|
result = mm_sim_convert_spn_to_utf8 (test_spn_data[i].bin_array,
|
|
test_spn_data[i].bin_len,
|
|
&error);
|
|
|
|
if (test_spn_data[i].expected_error) {
|
|
g_assert (!result);
|
|
g_assert (error);
|
|
g_error_free (error);
|
|
} else {
|
|
g_assert (result);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (result, ==, test_spn_data[i].expected_name);
|
|
g_free (result);
|
|
}
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
const guint8 bin_array[4];
|
|
gsize bin_len;
|
|
guint expected_length;
|
|
gboolean expected_error;
|
|
} TestMncData;
|
|
|
|
static const TestMncData test_mnc_data[] = {
|
|
{ { 0 }, 0, 0, TRUE },
|
|
{ { 0, 0, 0, 2 }, 3, 0, TRUE },
|
|
{ { 0, 0, 0, 2 }, 5, 2, FALSE },
|
|
{ { 0, 0, 0, 2 }, 4, 2, FALSE },
|
|
{ { 0, 0, 0, 3 }, 4, 3, FALSE },
|
|
{ { 0, 0, 0, 4 }, 4, 0, TRUE },
|
|
};
|
|
|
|
static void
|
|
test_mnc_length (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_mnc_data); i++) {
|
|
guint result;
|
|
GError *error = NULL;
|
|
|
|
result = mm_sim_validate_mnc_length (test_mnc_data[i].bin_array,
|
|
test_mnc_data[i].bin_len,
|
|
&error);
|
|
|
|
if (test_mnc_data[i].expected_error) {
|
|
g_assert (error);
|
|
g_error_free (error);
|
|
} else {
|
|
g_assert_no_error (error);
|
|
}
|
|
g_assert_cmpuint (result, ==, test_mnc_data[i].expected_length);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
const MMModemAccessTechnology act;
|
|
} TestActData;
|
|
|
|
static const TestActData test_act_data[] = {
|
|
{ "EDGE", MM_MODEM_ACCESS_TECHNOLOGY_EDGE },
|
|
/* Ensure WCDMA does not get counted as 3GPP2 CDMA */
|
|
{ "WCDMA", MM_MODEM_ACCESS_TECHNOLOGY_UMTS },
|
|
{ "CDMA-EVDO", MM_MODEM_ACCESS_TECHNOLOGY_1XRTT | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0 },
|
|
};
|
|
|
|
static void
|
|
test_string_to_access_tech (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_act_data); i++)
|
|
g_assert_cmpint (mm_string_to_access_tech (test_act_data[i].str), ==, test_act_data[i].act);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const gchar *str;
|
|
const gboolean expect_prefix;
|
|
const MMModemLock expected_lock;
|
|
} TestCpinResponse;
|
|
|
|
static const TestCpinResponse test_cpin_responses[] = {
|
|
{ "+CME ERROR: 100", TRUE, MM_MODEM_LOCK_UNKNOWN },
|
|
{ "+CPIN: SIM PIN", TRUE, MM_MODEM_LOCK_SIM_PIN },
|
|
{ "+CPIN: SIM PUK2", TRUE, MM_MODEM_LOCK_SIM_PUK2 },
|
|
{ " SIM PUK", FALSE, MM_MODEM_LOCK_SIM_PUK },
|
|
{ " SIM PUK2", FALSE, MM_MODEM_LOCK_SIM_PUK2 },
|
|
{ "+CPIN: \"SIM PIN\"", TRUE, MM_MODEM_LOCK_SIM_PIN },
|
|
{ "+CPIN: PH-NET PIN", TRUE, MM_MODEM_LOCK_PH_NET_PIN },
|
|
};
|
|
|
|
static void
|
|
test_cpin_response (void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_cpin_responses); i++) {
|
|
MMModemLock lock;
|
|
|
|
lock = mm_parse_cpin_response (test_cpin_responses[i].str, test_cpin_responses[i].expect_prefix);
|
|
g_assert_cmpint (lock, ==, test_cpin_responses[i].expected_lock);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
const char *desc;
|
|
const char *dtmf;
|
|
const char *expected[5];
|
|
} DtmfTestData;
|
|
|
|
static const DtmfTestData test_dtmf_data[] = {
|
|
{ "/MM/ModemHelpers/DTMF/empty", "", { NULL } },
|
|
{ "/MM/ModemHelpers/DTMF/one", "1", { "1", NULL } },
|
|
{ "/MM/ModemHelpers/DTMF/no-pause", "1234", { "1234", NULL } },
|
|
{ "/MM/ModemHelpers/DTMF/mid-pause", "123,,456", { "123", ",", ",", "456", NULL } },
|
|
{ "/MM/ModemHelpers/DTMF/end-pause", "123,,", { "123", ",", ",", NULL } },
|
|
};
|
|
|
|
static void
|
|
test_dtmf_split (gpointer user_data)
|
|
{
|
|
DtmfTestData *td = user_data;
|
|
g_autoptr(GPtrArray) split = NULL;
|
|
guint expected_len;
|
|
guint i;
|
|
|
|
split = mm_dtmf_split (td->dtmf);
|
|
|
|
expected_len = g_strv_length ((gchar **) td->expected);
|
|
if (expected_len == 0)
|
|
g_assert_true (split == NULL);
|
|
else {
|
|
g_assert_true (split != NULL);
|
|
g_assert_cmpint (split->len, ==, expected_len);
|
|
}
|
|
|
|
for (i = 0; i < expected_len; i++)
|
|
g_assert_cmpstr (td->expected[i], ==, g_ptr_array_index (split, i));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (GTestFixtureFunc) t, NULL)
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
GTestSuite *suite;
|
|
RegTestData *reg_data;
|
|
gint result;
|
|
DevidItem *item = &devids[0];
|
|
guint i;
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
suite = g_test_get_root ();
|
|
reg_data = reg_test_data_new ();
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_all_simple, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_all_groups, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_none_only, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_xon_xoff_only, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_rts_cts_only, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_no_xon_xoff, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_no_xon_xoff_in_ta, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_no_xon_xoff_in_te, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_no_rts_cts_simple, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_no_rts_cts_groups, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_all_simple_and_unknown, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ifc_response_all_groups_and_unknown, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_generic_2g3g4g, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_generic_2g3g, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_generic_2g3g_v2, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_cinterion, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_telit_le866, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_range_1, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ws46_response_range_2, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_tm506, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gt3gplus, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_ac881, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gtmax36, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_ac860, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gtm378, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_motoc, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_mf627a, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_mf627b, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_e160g, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_mercury, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_quicksilver, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_icon225, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_icon452, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_f3507g, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_f3607gw, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_mc8775, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_n80, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_e1550, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_mf622, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_e226, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_xu870, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gtultraexpress, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_n2720, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gobi, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_sek600i, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_samsung_z810, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_ublox_lara, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_em9191, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_gsm_invalid, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cops_response_umts_invalid, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cops_query, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_normalize_operator, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_creg1_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg1_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg1_multidigit_stat_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_mercury_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_mercury_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_multidigit_stat_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_sek850i_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_sek850i_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_solicited_unregistered, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_tm506_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_xu870_unsolicited_unregistered, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_md400_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_multidigit_stat_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_act_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_gobi_weird_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_iridium_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_no_leading_zeros_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_leading_zeros_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_no_leading_zeros_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_leading_zeros_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_multidigit_stat_no_leading_zeros_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_multidigit_stat_leading_zeros_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_ublox_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg2_ublox_unsolicited, reg_data));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg1_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg1_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_f3607gw_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_f3607gw_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_md400_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_x220_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_unsolicited_with_rac, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_multidigit_stat_with_rac_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_multidigit_stat_no_leading_zeros_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_multidigit_stat_leading_zeros_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_thuraya_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cgreg2_thuraya_unsolicited, reg_data));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cereg1_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg1_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_multidigit_stat_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_multidigit_stat_with_rac_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_multidigit_stat_with_rac_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_altair_lte_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_altair_lte_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_unsolicited, reg_data));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_c5greg1_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_c5greg1_multidigit_stat_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_c5greg1_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_c5greg2_solicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_c5greg2_unsolicited, reg_data));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi_unsolicited, reg_data));
|
|
g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi2_unsolicited, reg_data));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cscs_icon225_support_response, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cscs_sierra_mercury_support_response, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cscs_buslink_support_response, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cscs_blackberry_support_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cmer_response_cinterion_pls8, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmer_response_sierra_em7345, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmer_response_cinterion_ehs5, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cmer_request_cinterion_ehs5, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cind_response_linktop_lw273, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cind_response_moto_v3m, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgerep_response_telit_le910q1, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgerep_response_telit_ln920, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgev_indication, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_swap_19_digit, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_swap_20_digit, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_unswapped_19_digit, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_unswapped_19_digit_no_f, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_unswapped_20_digit, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_unswapped_hex_account, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_unswapped_hex_account_2, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_short, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_invalid_chars, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_invalid_mii, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_iccid_parse_unquoted_invalid_mii, NULL));
|
|
|
|
while (item->devid) {
|
|
g_test_suite_add (suite, TESTCASE (test_devid_item, (gconstpointer) item));
|
|
item++;
|
|
}
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_cinterion, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_huawei_mu609, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_nokia_c6, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_mixed, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_mixed_spaces, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_response_empty_fields, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cpms_query_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cmp_apn_name, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_single, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_multiple, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_multiple_and_ignore, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_single_context, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_thuraya, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_test_response_cinterion_phs8, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_nokia, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_samsung, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgdcont_read_response_simcom, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_profile_selection, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgact_read_response_none, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgact_read_response_single_inactive, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgact_read_response_single_active, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cgact_read_response_multiple, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cnum_response_generic, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cnum_response_generic_without_detail, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cnum_response_generic_detail_unquoted, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cnum_response_generic_international_number, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cnum_response_generic_multiple_numbers, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_parse_operator_id, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_parse_cds, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cdma_parse_gsn, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cmgl_response_generic, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmgl_response_generic_multiple, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmgl_response_pantech, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmgl_response_pantech_multiple, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cmgr_response_generic, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cmgr_response_telit, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_supported_mode_filter, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cclk_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_crsm_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cgcontrdp_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cfun_response, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cfun_generic_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_csim_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cesq_response, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_cesq_response_to_signal, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_clip_indication, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ccwa_indication, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_ccwa_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cscb_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_clcc_response_empty, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_clcc_response_single, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_clcc_response_single_long, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_clcc_response_multiple, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_clcc_response_ignore_non_voice, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_emergency_numbers, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_parse_uint_list, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_bcd_to_string, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_is_valid_fqdn, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_is_numeric, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_is_valid_dial_number, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_mm_split_string_groups, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_spn_to_utf8, NULL));
|
|
g_test_suite_add (suite, TESTCASE (test_mnc_length, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_string_to_access_tech, NULL));
|
|
|
|
g_test_suite_add (suite, TESTCASE (test_cpin_response, NULL));
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (test_dtmf_data); i++) {
|
|
g_test_add_data_func (test_dtmf_data[i].desc,
|
|
&test_dtmf_data[i],
|
|
(GTestDataFunc) test_dtmf_split);
|
|
}
|
|
|
|
result = g_test_run ();
|
|
|
|
reg_test_data_free (reg_data);
|
|
|
|
return result;
|
|
}
|