broadband-modem,modem-helpers: move +CPIN response parsing to modem helpers

Unit test it better, plus remove code duplication in various plugins.

Signed-off-by: Dan Williams <dan@ioncontrol.co>
This commit is contained in:
Dan Williams
2025-05-23 08:31:04 -05:00
parent c5a2cd3157
commit 757df26b29
5 changed files with 110 additions and 92 deletions
+6 -55
View File
@@ -1505,32 +1505,6 @@ modem_load_own_numbers (MMIfaceModem *self,
/*****************************************************************************/
/* Check if unlock required (Modem interface) */
typedef struct {
const gchar *result;
MMModemLock code;
} CPinResult;
static CPinResult unlock_results[] = {
/* Longer entries first so we catch the correct one with strcmp() */
{ "READY", MM_MODEM_LOCK_NONE },
{ "SIM PIN2", MM_MODEM_LOCK_SIM_PIN2 },
{ "SIM PUK2", MM_MODEM_LOCK_SIM_PUK2 },
{ "SIM PIN", MM_MODEM_LOCK_SIM_PIN },
{ "SIM PUK", MM_MODEM_LOCK_SIM_PUK },
{ "PH-NETSUB PIN", MM_MODEM_LOCK_PH_NETSUB_PIN },
{ "PH-NETSUB PUK", MM_MODEM_LOCK_PH_NETSUB_PUK },
{ "PH-FSIM PIN", MM_MODEM_LOCK_PH_FSIM_PIN },
{ "PH-FSIM PUK", MM_MODEM_LOCK_PH_FSIM_PUK },
{ "PH-CORP PIN", MM_MODEM_LOCK_PH_CORP_PIN },
{ "PH-CORP PUK", MM_MODEM_LOCK_PH_CORP_PUK },
{ "PH-SIM PIN", MM_MODEM_LOCK_PH_SIM_PIN },
{ "PH-NET PIN", MM_MODEM_LOCK_PH_NET_PIN },
{ "PH-NET PUK", MM_MODEM_LOCK_PH_NET_PUK },
{ "PH-SP PIN", MM_MODEM_LOCK_PH_SP_PIN },
{ "PH-SP PUK", MM_MODEM_LOCK_PH_SP_PUK },
{ NULL }
};
static MMModemLock
modem_load_unlock_required_finish (MMIfaceModem *self,
GAsyncResult *res,
@@ -1553,42 +1527,19 @@ cpin_query_ready (MMIfaceModem *self,
GTask *task)
{
MMModemLock lock = MM_MODEM_LOCK_UNKNOWN;
MMModemLock lock = MM_MODEM_LOCK_UNKNOWN;
const gchar *result;
GError *error = NULL;
GError *error = NULL;
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error) {
g_task_return_error (task, error);
g_object_unref (task);
return;
} else {
if (result)
lock = mm_parse_cpin_response (result, TRUE);
g_task_return_int (task, lock);
}
if (result &&
strstr (result, "+CPIN:")) {
CPinResult *iter = &unlock_results[0];
const gchar *str;
str = strstr (result, "+CPIN:") + 6;
/* Skip possible whitespaces after '+CPIN:' and before the response */
while (*str == ' ')
str++;
/* Some phones (Motorola EZX models) seem to quote the response */
if (str[0] == '"')
str++;
/* Translate the reply */
while (iter->result) {
if (g_str_has_prefix (str, iter->result)) {
lock = iter->code;
break;
}
iter++;
}
}
g_task_return_int (task, lock);
g_object_unref (task);
}
+64
View File
@@ -5807,3 +5807,67 @@ mm_string_uint_map_lookup (const MMStringUintMap *map,
}
return default_value;
}
/*****************************************************************************/
typedef struct {
const gchar *result;
const MMModemLock code;
} CPinResult;
static const CPinResult unlock_results[] = {
/* Longer entries first so we catch the correct one with strcmp() */
{ "READY", MM_MODEM_LOCK_NONE },
{ "SIM PIN2", MM_MODEM_LOCK_SIM_PIN2 },
{ "SIM PUK2", MM_MODEM_LOCK_SIM_PUK2 },
{ "SIM PIN", MM_MODEM_LOCK_SIM_PIN },
{ "SIM PUK", MM_MODEM_LOCK_SIM_PUK },
{ "PH-NETSUB PIN", MM_MODEM_LOCK_PH_NETSUB_PIN },
{ "PH-NETSUB PUK", MM_MODEM_LOCK_PH_NETSUB_PUK },
{ "PH-FSIM PIN", MM_MODEM_LOCK_PH_FSIM_PIN },
{ "PH-FSIM PUK", MM_MODEM_LOCK_PH_FSIM_PUK },
{ "PH-CORP PIN", MM_MODEM_LOCK_PH_CORP_PIN },
{ "PH-CORP PUK", MM_MODEM_LOCK_PH_CORP_PUK },
{ "PH-SIM PIN", MM_MODEM_LOCK_PH_SIM_PIN },
{ "PH-NET PIN", MM_MODEM_LOCK_PH_NET_PIN },
{ "PH-NET PUK", MM_MODEM_LOCK_PH_NET_PUK },
{ "PH-SP PIN", MM_MODEM_LOCK_PH_SP_PIN },
{ "PH-SP PUK", MM_MODEM_LOCK_PH_SP_PUK },
{ NULL }
};
MMModemLock
mm_parse_cpin_response (const gchar *response,
gboolean expect_cpin_prefix)
{
const CPinResult *iter = &unlock_results[0];
if (expect_cpin_prefix) {
const gchar *p;
p = strstr (response, "+CPIN:");
if (!p)
return MM_MODEM_LOCK_UNKNOWN;
/* Advance past the +CPIN: */
response = p + 6;
}
/* Skip possible whitespaces after '+CPIN:' and before the response */
while (*response == ' ')
response++;
/* Some phones (Motorola EZX models) seem to quote the response */
if (response[0] == '"')
response++;
/* Translate the reply */
while (iter->result) {
if (g_str_has_prefix (response, iter->result)) {
return iter->code;
}
iter++;
}
return MM_MODEM_LOCK_UNKNOWN;
}
+5
View File
@@ -638,4 +638,9 @@ guint mm_string_uint_map_lookup (const MMStringUintMap *map,
const gchar *str,
const guint default_value);
/*****************************************************************************/
MMModemLock mm_parse_cpin_response (const gchar *response,
gboolean expect_cpin_prefix);
#endif /* MM_MODEM_HELPERS_H */
@@ -72,31 +72,6 @@ struct _MMBroadbandModemSimtechPrivate {
MMModemLock sim_lock;
};
typedef struct {
const gchar *result;
MMModemLock code;
} CPinResult;
static CPinResult unlock_results[] = {
{ "READY", MM_MODEM_LOCK_NONE },
{ "SIM PIN2", MM_MODEM_LOCK_SIM_PIN2 },
{ "SIM PUK2", MM_MODEM_LOCK_SIM_PUK2 },
{ "SIM PIN", MM_MODEM_LOCK_SIM_PIN },
{ "SIM PUK", MM_MODEM_LOCK_SIM_PUK },
{ "PH-NETSUB PIN", MM_MODEM_LOCK_PH_NETSUB_PIN },
{ "PH-NETSUB PUK", MM_MODEM_LOCK_PH_NETSUB_PUK },
{ "PH-FSIM PIN", MM_MODEM_LOCK_PH_FSIM_PIN },
{ "PH-FSIM PUK", MM_MODEM_LOCK_PH_FSIM_PUK },
{ "PH-CORP PIN", MM_MODEM_LOCK_PH_CORP_PIN },
{ "PH-CORP PUK", MM_MODEM_LOCK_PH_CORP_PUK },
{ "PH-SIM PIN", MM_MODEM_LOCK_PH_SIM_PIN },
{ "PH-NET PIN", MM_MODEM_LOCK_PH_NET_PIN },
{ "PH-NET PUK", MM_MODEM_LOCK_PH_NET_PUK },
{ "PH-SP PIN", MM_MODEM_LOCK_PH_SP_PIN },
{ "PH-SP PUK", MM_MODEM_LOCK_PH_SP_PUK },
{ NULL }
};
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */
@@ -158,20 +133,10 @@ simtech_cpin_changed (MMPortSerialAt *port,
MMBroadbandModemSimtech *self)
{
g_autofree gchar *str = NULL;
CPinResult *iter;
str = mm_get_string_unquoted_from_match_info (match_info, 1);
if (str) {
iter = &unlock_results[0];
/* Translate the reply */
while (iter->result) {
if (g_str_has_prefix (str, iter->result)) {
self->priv->sim_lock = iter->code;
return;
}
iter++;
}
}
if (str)
self->priv->sim_lock = mm_parse_cpin_response (str, FALSE);
}
static void
+33
View File
@@ -5089,6 +5089,37 @@ test_string_to_access_tech (void)
/*****************************************************************************/
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);
}
}
/*****************************************************************************/
#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (GTestFixtureFunc) t, NULL)
int main (int argc, char **argv)
@@ -5351,6 +5382,8 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_string_to_access_tech, NULL));
g_test_suite_add (suite, TESTCASE (test_cpin_response, NULL));
result = g_test_run ();
reg_test_data_free (reg_data);