gsm: common CREG/CGREG parsing function and testcases
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mm-errors.h"
|
||||
#include "mm-modem-helpers.h"
|
||||
@@ -201,3 +202,224 @@ mm_gsm_destroy_scan_data (gpointer data)
|
||||
g_ptr_array_free (results, TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
|
||||
#define CREG1 "\\+CG?REG:\\s*(\\d{1})"
|
||||
|
||||
/* +CREG: <n>,<stat> (GSM 07.07 CREG=1 solicited) */
|
||||
#define CREG2 "\\+CG?REG:\\s*(\\d{1}),\\s*(\\d{1})"
|
||||
|
||||
/* +CREG: <stat>,<lac>,<ci> (GSM 07.07 CREG=2 unsolicited) */
|
||||
#define CREG3 "\\+CG?REG:\\s*(\\d{1}),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
|
||||
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci> (GSM 07.07 solicited and some CREG=2 unsolicited) */
|
||||
#define CREG4 "\\+CG?REG:\\s*(\\d{1}),\\s*(\\d{1})\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
|
||||
|
||||
/* +CREG: <stat>,<lac>,<ci>,<AcT> (ETSI 27.007 CREG=2 unsolicited) */
|
||||
#define CREG5 "\\+CG?REG:\\s*(\\d{1})\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*(\\d{1,2})"
|
||||
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */
|
||||
#define CREG6 "\\+CG?REG:\\s*(\\d{1}),\\s*(\\d{1})\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*(\\d{1,2})"
|
||||
|
||||
GPtrArray *
|
||||
mm_gsm_creg_regex_get (gboolean solicited)
|
||||
{
|
||||
GPtrArray *array = g_ptr_array_sized_new (6);
|
||||
GRegex *regex;
|
||||
|
||||
/* #1 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG1 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* #2 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG2 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG2 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* #3 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG3 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG3 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* #4 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG4 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG4 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* #5 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG5 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG5 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* #6 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CREG6 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CREG6 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
void
|
||||
mm_gsm_creg_regex_destroy (GPtrArray *array)
|
||||
{
|
||||
g_ptr_array_foreach (array, (GFunc) g_regex_unref, NULL);
|
||||
g_ptr_array_free (array, TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static gulong
|
||||
parse_uint (char *str, int base, glong nmin, glong nmax, gboolean *valid)
|
||||
{
|
||||
gulong ret = 0;
|
||||
char *endquote;
|
||||
|
||||
*valid = FALSE;
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
/* Strip quotes */
|
||||
if (str[0] == '"')
|
||||
str++;
|
||||
endquote = strchr (str, '"');
|
||||
if (endquote)
|
||||
*endquote = '\0';
|
||||
|
||||
if (strlen (str)) {
|
||||
ret = strtol (str, NULL, base);
|
||||
if ((nmin == nmax) || (ret >= nmin && ret <= nmax))
|
||||
*valid = TRUE;
|
||||
}
|
||||
return *valid ? (guint) ret : 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_gsm_parse_creg_response (GMatchInfo *info,
|
||||
guint32 *out_reg_state,
|
||||
gulong *out_lac,
|
||||
gulong *out_ci,
|
||||
gint *out_act,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE, foo;
|
||||
gint n_matches, act = -1;
|
||||
gulong stat = 0, lac = 0, ci = 0;
|
||||
guint istat = 0, ilac = 0, ici = 0, iact = 0;
|
||||
char *str;
|
||||
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
g_return_val_if_fail (out_reg_state != NULL, FALSE);
|
||||
g_return_val_if_fail (out_lac != NULL, FALSE);
|
||||
g_return_val_if_fail (out_ci != NULL, FALSE);
|
||||
g_return_val_if_fail (out_act != NULL, FALSE);
|
||||
|
||||
/* Normally the number of matches could be used to determine what each
|
||||
* item is, but we have overlap in one case.
|
||||
*/
|
||||
n_matches = g_match_info_get_match_count (info);
|
||||
if (n_matches == 2) {
|
||||
/* CREG=1: +CREG: <stat> */
|
||||
istat = 1;
|
||||
} else if (n_matches == 3) {
|
||||
/* Solicited response: +CREG: <n>,<stat> */
|
||||
istat = 2;
|
||||
} else if (n_matches == 4) {
|
||||
/* CREG=2 (GSM 07.07): +CREG: <stat>,<lac>,<ci> */
|
||||
istat = 1;
|
||||
ilac = 2;
|
||||
ici = 3;
|
||||
} else if (n_matches == 5) {
|
||||
/* CREG=2 (ETSI 27.007): +CREG: <stat>,<lac>,<ci>,<AcT>
|
||||
* CREG=2 (non-standard): +CREG: <n>,<stat>,<lac>,<ci>
|
||||
*/
|
||||
|
||||
/* To distinguish, check length of the second match item. If it's
|
||||
* more than one digit or has quotes in it, then we have the first format.
|
||||
*/
|
||||
str = g_match_info_fetch (info, 2);
|
||||
if (str && (strchr (str, '"') || strlen (str) > 1)) {
|
||||
g_free (str);
|
||||
istat = 1;
|
||||
ilac = 2;
|
||||
ici = 3;
|
||||
iact = 4;
|
||||
} else {
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
}
|
||||
} else if (n_matches == 6) {
|
||||
/* CREG=2 (non-standard): +CREG: <n>,<stat>,<lac>,<ci>,<AcT> */
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
iact = 5;
|
||||
}
|
||||
|
||||
/* Status */
|
||||
str = g_match_info_fetch (info, istat);
|
||||
stat = parse_uint (str, 10, 0, 5, &success);
|
||||
g_free (str);
|
||||
if (!success) {
|
||||
g_set_error_literal (error,
|
||||
MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse the registration status response");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Location Area Code */
|
||||
if (ilac) {
|
||||
/* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
|
||||
* Sagem). Need to handle that.
|
||||
*/
|
||||
str = g_match_info_fetch (info, ilac);
|
||||
lac = parse_uint (str, 16, 1, 0xFFFF, &foo);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
/* Cell ID */
|
||||
if (ici) {
|
||||
str = g_match_info_fetch (info, ici);
|
||||
ci = parse_uint (str, 16, 1, 0x0FFFFFFE, &foo);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
/* Access Technology */
|
||||
if (iact) {
|
||||
str = g_match_info_fetch (info, iact);
|
||||
act = (gint) parse_uint (str, 10, 0, 7, &foo);
|
||||
g_free (str);
|
||||
if (!foo)
|
||||
act = -1;
|
||||
}
|
||||
|
||||
*out_reg_state = (guint32) stat;
|
||||
if (stat != 4) {
|
||||
/* Don't fill in lac/ci/act if the device's state is unknown */
|
||||
*out_lac = lac;
|
||||
*out_ci = ci;
|
||||
*out_act = act;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -27,5 +27,16 @@ GPtrArray *mm_gsm_parse_scan_response (const char *reply, GError **error);
|
||||
|
||||
void mm_gsm_destroy_scan_data (gpointer data);
|
||||
|
||||
GPtrArray *mm_gsm_creg_regex_get (gboolean solicited);
|
||||
|
||||
void mm_gsm_creg_regex_destroy (GPtrArray *array);
|
||||
|
||||
gboolean mm_gsm_parse_creg_response (GMatchInfo *info,
|
||||
guint32 *out_reg_state,
|
||||
gulong *out_lac,
|
||||
gulong *out_ci,
|
||||
gint *out_act,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_MODEM_HELPERS_H */
|
||||
|
||||
|
@@ -18,6 +18,11 @@
|
||||
|
||||
#include "mm-modem-helpers.h"
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *solicited_creg;
|
||||
GPtrArray *unsolicited_creg;
|
||||
} TestData;
|
||||
|
||||
#define MM_SCAN_TAG_STATUS "status"
|
||||
#define MM_SCAN_TAG_OPER_LONG "operator-long"
|
||||
#define MM_SCAN_TAG_OPER_SHORT "operator-short"
|
||||
@@ -35,10 +40,10 @@ typedef struct {
|
||||
#define ARRAY_LEN(i) (sizeof (i) / sizeof (i[0]))
|
||||
|
||||
static void
|
||||
test_results (const char *desc,
|
||||
const char *reply,
|
||||
OperEntry *expected_results,
|
||||
guint32 expected_results_len)
|
||||
test_cops_results (const char *desc,
|
||||
const char *reply,
|
||||
OperEntry *expected_results,
|
||||
guint32 expected_results_len)
|
||||
{
|
||||
guint i;
|
||||
GError *error = NULL;
|
||||
@@ -101,7 +106,7 @@ test_cops_response_tm506 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" }
|
||||
};
|
||||
|
||||
test_results ("TM-506", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("TM-506", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -113,7 +118,7 @@ test_cops_response_gt3gplus (void *f, gpointer d)
|
||||
{ "1", "Cingular", "Cingular", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("GlobeTrotter 3G+ (nozomi)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("GlobeTrotter 3G+ (nozomi)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -126,7 +131,7 @@ test_cops_response_ac881 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Sierra AirCard 881", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Sierra AirCard 881", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -139,7 +144,7 @@ test_cops_response_gtmax36 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Option GlobeTrotter MAX 3.6", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option GlobeTrotter MAX 3.6", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -152,7 +157,7 @@ test_cops_response_ac860 (void *f, gpointer d)
|
||||
{ "1", "Cingular", "Cinglr", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Sierra AirCard 860", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Sierra AirCard 860", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -165,7 +170,7 @@ test_cops_response_gtm378 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Option GTM378", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option GTM378", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -177,7 +182,7 @@ test_cops_response_motoc (void *f, gpointer d)
|
||||
{ "0", "Cingular Wireless", NULL, "310410", NULL },
|
||||
};
|
||||
|
||||
test_results ("BUSlink SCWi275u (Motorola C-series)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("BUSlink SCWi275u (Motorola C-series)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -189,7 +194,7 @@ test_cops_response_mf627a (void *f, gpointer d)
|
||||
{ "3", "Voicestream Wireless Corporation", "VSTREAM", "31026", "0" },
|
||||
};
|
||||
|
||||
test_results ("ZTE MF627 (A)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("ZTE MF627 (A)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -201,7 +206,7 @@ test_cops_response_mf627b (void *f, gpointer d)
|
||||
{ "3", NULL, NULL, "31026", "0" },
|
||||
};
|
||||
|
||||
test_results ("ZTE MF627 (B)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("ZTE MF627 (B)", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -213,7 +218,7 @@ test_cops_response_e160g (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Huawei E160G", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Huawei E160G", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -226,7 +231,7 @@ test_cops_response_mercury (void *f, gpointer d)
|
||||
{ "1", "T-Mobile", "TMO", "31026", "0" },
|
||||
};
|
||||
|
||||
test_results ("Sierra AT&T USBConnect Mercury", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Sierra AT&T USBConnect Mercury", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -239,7 +244,7 @@ test_cops_response_quicksilver (void *f, gpointer d)
|
||||
{ "1", "AT&T", NULL, "310260", "0" },
|
||||
};
|
||||
|
||||
test_results ("Option AT&T Quicksilver", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option AT&T Quicksilver", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -251,7 +256,7 @@ test_cops_response_icon225 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Option iCON 225", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option iCON 225", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -265,7 +270,7 @@ test_cops_response_icon452 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" }
|
||||
};
|
||||
|
||||
test_results ("Option iCON 452", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option iCON 452", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -278,7 +283,7 @@ test_cops_response_f3507g (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "2" }
|
||||
};
|
||||
|
||||
test_results ("Ericsson F3507g", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Ericsson F3507g", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -291,7 +296,7 @@ test_cops_response_f3607gw (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" }
|
||||
};
|
||||
|
||||
test_results ("Ericsson F3607gw", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Ericsson F3607gw", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -304,7 +309,7 @@ test_cops_response_mc8775 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" }
|
||||
};
|
||||
|
||||
test_results ("Sierra MC8775", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Sierra MC8775", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -317,7 +322,7 @@ test_cops_response_n80 (void *f, gpointer d)
|
||||
{ "1", "Cingular", NULL, "31041", NULL },
|
||||
};
|
||||
|
||||
test_results ("Nokia N80", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Nokia N80", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -329,7 +334,7 @@ test_cops_response_e1550 (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Huawei E1550", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Huawei E1550", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -341,7 +346,7 @@ test_cops_response_mf622 (void *f, gpointer d)
|
||||
{ "1", NULL, NULL, "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("ZTE MF622", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("ZTE MF622", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -354,7 +359,7 @@ test_cops_response_e226 (void *f, gpointer d)
|
||||
{ "1", NULL, NULL, "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Huawei E226", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Huawei E226", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -367,7 +372,7 @@ test_cops_response_xu870 (void *f, gpointer d)
|
||||
{ "1", "T-Mobile", "TMO", "31026", "0" },
|
||||
};
|
||||
|
||||
test_results ("Novatel XU870", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Novatel XU870", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -380,7 +385,7 @@ test_cops_response_gtultraexpress (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Option GlobeTrotter Ultra Express", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Option GlobeTrotter Ultra Express", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -392,7 +397,7 @@ test_cops_response_n2720 (void *f, gpointer d)
|
||||
{ "1", "AT&T", NULL, "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Nokia 2720", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Nokia 2720", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -405,7 +410,7 @@ test_cops_response_gobi (void *f, gpointer d)
|
||||
{ "1", "AT&T", "AT&T", "310410", "0" },
|
||||
};
|
||||
|
||||
test_results ("Qualcomm Gobi", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Qualcomm Gobi", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -426,7 +431,7 @@ test_cops_response_sek600i (void *f, gpointer d)
|
||||
{ "3", NULL, NULL, "26207", NULL },
|
||||
};
|
||||
|
||||
test_results ("Sony-Ericsson K600i", reply, &expected[0], ARRAY_LEN (expected));
|
||||
test_cops_results ("Sony-Ericsson K600i", reply, &expected[0], ARRAY_LEN (expected));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -453,6 +458,216 @@ test_cops_response_umts_invalid (void *f, gpointer d)
|
||||
g_assert (error == NULL);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
guint32 state;
|
||||
gulong lac;
|
||||
gulong ci;
|
||||
gint act;
|
||||
|
||||
guint regex_num;
|
||||
} CregResult;
|
||||
|
||||
static void
|
||||
test_creg_match (const char *test,
|
||||
gboolean solicited,
|
||||
const char *reply,
|
||||
TestData *data,
|
||||
const CregResult *result)
|
||||
{
|
||||
int i;
|
||||
GMatchInfo *info = NULL;
|
||||
guint32 state = 0;
|
||||
gulong lac = 0, ci = 0;
|
||||
gint access_tech = -1;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
guint regex_num = 0;
|
||||
GPtrArray *array;
|
||||
|
||||
g_assert (reply);
|
||||
g_assert (test);
|
||||
g_assert (data);
|
||||
g_assert (result);
|
||||
|
||||
g_print ("\nTesting %s +CREG %s response...\n",
|
||||
test,
|
||||
solicited ? "solicited" : "unsolicited");
|
||||
|
||||
array = solicited ? data->solicited_creg : data->unsolicited_creg;
|
||||
for (i = 0; i < array->len; i++) {
|
||||
GRegex *r = g_ptr_array_index (array, i);
|
||||
|
||||
if (g_regex_match (r, reply, 0, &info)) {
|
||||
regex_num = i + 1;
|
||||
break;
|
||||
}
|
||||
g_match_info_free (info);
|
||||
info = NULL;
|
||||
}
|
||||
|
||||
g_assert (info != NULL);
|
||||
g_assert (regex_num == result->regex_num);
|
||||
|
||||
success = mm_gsm_parse_creg_response (info, &state, &lac, &ci, &access_tech, &error);
|
||||
g_assert (success);
|
||||
g_assert (error == NULL);
|
||||
g_assert (state == result->state);
|
||||
g_assert (lac == result->lac);
|
||||
g_assert (ci == result->ci);
|
||||
g_assert (access_tech == result->act);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg1_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 1,3";
|
||||
const CregResult result = { 3, 0, 0, -1 , 2};
|
||||
|
||||
test_creg_match ("CREG=1", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg1_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CREG: 3\r\n";
|
||||
const CregResult result = { 3, 0, 0, -1 , 1};
|
||||
|
||||
test_creg_match ("CREG=1", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_mercury_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 0,1,84CD,00D30173";
|
||||
const CregResult result = { 1, 0x84cd, 0xd30173, -1 , 4};
|
||||
|
||||
test_creg_match ("Sierra Mercury CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_mercury_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CREG: 1,84CD,00D30156\r\n";
|
||||
const CregResult result = { 1, 0x84cd, 0xd30156, -1 , 3};
|
||||
|
||||
test_creg_match ("Sierra Mercury CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_sek850i_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 2,1,\"CE00\",\"01CEAD8F\"";
|
||||
const CregResult result = { 1, 0xce00, 0x01cead8f, -1 , 4};
|
||||
|
||||
test_creg_match ("Sony Ericsson K850i CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_sek850i_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CREG: 1,\"CE00\",\"00005449\"\r\n";
|
||||
const CregResult result = { 1, 0xce00, 0x5449, -1 , 3};
|
||||
|
||||
test_creg_match ("Sony Ericsson K850i CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_e160g_solicited_unregistered (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 2,0,00,0";
|
||||
const CregResult result = { 0, 0, 0, -1 , 4};
|
||||
|
||||
test_creg_match ("Huawei E160G unregistered CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_e160g_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 2,1,8BE3,2BAF";
|
||||
const CregResult result = { 1, 0x8be3, 0x2baf, -1 , 4};
|
||||
|
||||
test_creg_match ("Huawei E160G CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_e160g_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,8BE3,2BAF\r\n";
|
||||
const CregResult result = { 2, 0x8be3, 0x2baf, -1 , 3};
|
||||
|
||||
test_creg_match ("Huawei E160G CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_tm506_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CREG: 2,1,\"8BE3\",\"00002BAF\"";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2BAF, -1 , 4};
|
||||
|
||||
/* 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)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,,\r\n";
|
||||
const CregResult result = { 2, 0, 0, -1 , 3};
|
||||
|
||||
test_creg_match ("Novatel XU870 unregistered CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cgreg2_f3607gw_solicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "+CGREG: 2,1,\"8BE3\",\"00002B5D\",3";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, 3 , 6};
|
||||
|
||||
test_creg_match ("Ericsson F3607gw CGREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cgreg2_f3607gw_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
TestData *data = (TestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 1,\"8BE3\",\"00002B5D\",3\r\n";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, 3 , 5};
|
||||
|
||||
test_creg_match ("Ericsson F3607gw CGREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
|
||||
static TestData *
|
||||
test_data_new (void)
|
||||
{
|
||||
TestData *data;
|
||||
|
||||
data = g_malloc0 (sizeof (TestData));
|
||||
data->solicited_creg = mm_gsm_creg_regex_get (TRUE);
|
||||
data->unsolicited_creg = mm_gsm_creg_regex_get (FALSE);
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
test_data_free (TestData *data)
|
||||
{
|
||||
mm_gsm_creg_regex_destroy (data->solicited_creg);
|
||||
mm_gsm_creg_regex_destroy (data->unsolicited_creg);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*TCFunc)(void);
|
||||
|
||||
@@ -461,10 +676,13 @@ typedef void (*TCFunc)(void);
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GTestSuite *suite;
|
||||
TestData *data;
|
||||
gint result;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
suite = g_test_get_root ();
|
||||
data = test_data_new ();
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_cops_response_tm506, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_cops_response_gt3gplus, NULL));
|
||||
@@ -496,6 +714,24 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_cops_response_gsm_invalid, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_cops_response_umts_invalid, NULL));
|
||||
|
||||
return g_test_run ();
|
||||
g_test_suite_add (suite, TESTCASE (test_creg1_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg1_unsolicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_mercury_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_mercury_unsolicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_sek850i_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_sek850i_unsolicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_solicited_unregistered, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_e160g_unsolicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_tm506_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_xu870_unsolicited_unregistered, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cgreg2_f3607gw_solicited, data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cgreg2_f3607gw_unsolicited, data));
|
||||
|
||||
result = g_test_run ();
|
||||
|
||||
test_data_free (data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user