core: keep track of all PIN retry counts
Added a PinRetryCounts property on org.freedesktop.ModemManager.Modem. This is dictionary that records the number of PIN tries remaining for each of the possible PIN code types for which the modem is capable of reporting the count. Also, these counts are kept up to date across ChangePin and EnablePin operations, not just when an unlock is attempted.
This commit is contained in:
committed by
Dan Williams
parent
71598a6289
commit
e7b6b2dc1c
@@ -511,15 +511,23 @@ get_access_technology (MMGenericGsm *modem,
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
parse_num (const char *str, guint32 *out_num, guint32 min, guint32 max)
|
||||
parse_match_as_num (GMatchInfo *match_info,
|
||||
guint idx,
|
||||
guint32 *out_num,
|
||||
guint32 min,
|
||||
guint32 max)
|
||||
{
|
||||
unsigned long int tmp;
|
||||
char *str;
|
||||
|
||||
str = g_match_info_fetch (match_info, idx);
|
||||
if (!str || !strlen (str))
|
||||
return FALSE;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtoul (str, NULL, 10);
|
||||
g_free (str);
|
||||
|
||||
if (errno != 0 || tmp < min || tmp > max)
|
||||
return FALSE;
|
||||
*out_num = (guint32) tmp;
|
||||
@@ -535,10 +543,12 @@ send_huawei_cpin_done (MMAtSerialPort *port,
|
||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||
GRegex *r = NULL;
|
||||
GMatchInfo *match_info = NULL;
|
||||
const char *pin_type;
|
||||
guint32 attempts_left = 0;
|
||||
char *str = NULL;
|
||||
guint32 num = 0;
|
||||
guint32 i = 0;
|
||||
gboolean success = FALSE;
|
||||
GArray *retry_counts;
|
||||
PinRetryCount ur[4] = {
|
||||
{"sim-puk", 0}, {"sim-pin", 0}, {"sim-puk2", 0}, {"sim-pin2", 0}
|
||||
};
|
||||
|
||||
/* If the modem has already been removed, return without
|
||||
* scheduling callback */
|
||||
@@ -550,9 +560,7 @@ send_huawei_cpin_done (MMAtSerialPort *port,
|
||||
goto done;
|
||||
}
|
||||
|
||||
pin_type = mm_callback_info_get_data (info, "pin_type");
|
||||
|
||||
r = g_regex_new ("\\^CPIN:\\s*([^,]+),[^,]*,(\\d+),(\\d+),(\\d+),(\\d+)", G_REGEX_UNGREEDY, 0, NULL);
|
||||
r = g_regex_new ("\\^CPIN:\\s*([^,]+),[^,]*,(\\d+),(\\d+),(\\d+),(\\d+)", G_REGEX_UNGREEDY, 0, NULL);
|
||||
if (!r) {
|
||||
g_set_error_literal (&info->error,
|
||||
MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
@@ -567,37 +575,21 @@ send_huawei_cpin_done (MMAtSerialPort *port,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK))
|
||||
num = 2;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN))
|
||||
num = 3;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK2))
|
||||
num = 4;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN2))
|
||||
num = 5;
|
||||
else {
|
||||
mm_dbg ("unhandled pin type '%s'", pin_type);
|
||||
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unhandled PIN type");
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
gboolean success = FALSE;
|
||||
|
||||
str = g_match_info_fetch (match_info, num);
|
||||
if (str) {
|
||||
success = parse_num (str, &attempts_left, 0, 10);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
success = parse_match_as_num (match_info, i + 2, &ur[i].count, 0, 10);
|
||||
if (!success) {
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR,
|
||||
MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse ^CPIN results (missing or invalid match info).");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mm_callback_info_set_result (info, GUINT_TO_POINTER (attempts_left), NULL);
|
||||
if (success) {
|
||||
retry_counts = g_array_sized_new (FALSE, TRUE, sizeof (PinRetryCount), 4);
|
||||
g_array_append_vals (retry_counts, &ur, 4);
|
||||
mm_callback_info_set_result (info, retry_counts, NULL);
|
||||
}
|
||||
|
||||
done:
|
||||
if (match_info)
|
||||
@@ -610,15 +602,12 @@ done:
|
||||
|
||||
static void
|
||||
get_unlock_retries (MMModemGsmCard *modem,
|
||||
const char *pin_type,
|
||||
MMModemUIntFn callback,
|
||||
MMModemArrayFn callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMAtSerialPort *port;
|
||||
char *command;
|
||||
MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
|
||||
|
||||
mm_dbg ("pin type '%s'", pin_type);
|
||||
MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data);
|
||||
|
||||
/* Ensure we have a usable port to use for the command */
|
||||
port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
|
||||
@@ -641,8 +630,6 @@ get_unlock_retries (MMModemGsmCard *modem,
|
||||
mm_at_serial_port_queue_command (port, command, 3, NULL, NULL);
|
||||
g_free (command);
|
||||
|
||||
mm_callback_info_set_data (info, "pin_type", g_strdup (pin_type), g_free);
|
||||
|
||||
command = g_strdup_printf ("^CPIN?");
|
||||
mm_at_serial_port_queue_command (port, command, 3, send_huawei_cpin_done, info);
|
||||
g_free (command);
|
||||
|
||||
+21
-29
@@ -867,8 +867,11 @@ send_epin_done (MMAtSerialPort *port,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||
const char *pin_type;
|
||||
int attempts_left = 0;
|
||||
int matched;
|
||||
GArray *retry_counts;
|
||||
PinRetryCount ur[4] = {
|
||||
{"sim-pin", 0}, {"sim-puk", 0}, {"sim-pin2", 0}, {"sim-puk2", 0}
|
||||
};
|
||||
|
||||
/* If the modem has already been removed, return without
|
||||
* scheduling callback */
|
||||
@@ -880,29 +883,23 @@ send_epin_done (MMAtSerialPort *port,
|
||||
goto done;
|
||||
}
|
||||
|
||||
pin_type = mm_callback_info_get_data (info, "pin_type");
|
||||
matched = sscanf (response->str, "*EPIN: %d, %d, %d, %d",
|
||||
&ur[0].count, &ur[1].count, &ur[2].count, &ur[3].count);
|
||||
if (matched == 4) {
|
||||
if (ur[0].count > 998) {
|
||||
info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Invalid PIN attempts left %d", ur[0].count);
|
||||
ur[0].count = 0;
|
||||
}
|
||||
|
||||
if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN))
|
||||
sscanf (response->str, "*EPIN: %d", &attempts_left);
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK))
|
||||
sscanf (response->str, "*EPIN: %*d, %d", &attempts_left);
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN2))
|
||||
sscanf (response->str, "*EPIN: %*d, %*d, %d", &attempts_left);
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK2))
|
||||
sscanf (response->str, "*EPIN: %*d, %*d, %*d, %d", &attempts_left);
|
||||
else {
|
||||
mm_dbg ("unhandled pin type '%s'", pin_type);
|
||||
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unhandled PIN type");
|
||||
retry_counts = g_array_sized_new (FALSE, TRUE, sizeof (PinRetryCount), 4);
|
||||
g_array_append_vals (retry_counts, &ur, 4);
|
||||
mm_callback_info_set_result (info, retry_counts, NULL);
|
||||
} else {
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse PIN retries results");
|
||||
}
|
||||
|
||||
if (attempts_left < 0 || attempts_left > 998) {
|
||||
info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Invalid PIN attempts left %d", attempts_left);
|
||||
attempts_left = 0;
|
||||
}
|
||||
|
||||
mm_callback_info_set_result (info, GUINT_TO_POINTER (attempts_left), NULL);
|
||||
|
||||
done:
|
||||
mm_serial_port_close (MM_SERIAL_PORT (port));
|
||||
mm_callback_info_schedule (info);
|
||||
@@ -910,15 +907,12 @@ done:
|
||||
|
||||
static void
|
||||
mbm_get_unlock_retries (MMModemGsmCard *modem,
|
||||
const char *pin_type,
|
||||
MMModemUIntFn callback,
|
||||
MMModemArrayFn callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMAtSerialPort *port;
|
||||
char *command;
|
||||
MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
|
||||
|
||||
mm_dbg ("pin type '%s'", pin_type);
|
||||
MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data);
|
||||
|
||||
/* Ensure we have a usable port to use for the command */
|
||||
port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
|
||||
@@ -941,8 +935,6 @@ mbm_get_unlock_retries (MMModemGsmCard *modem,
|
||||
mm_at_serial_port_queue_command (port, command, 3, NULL, NULL);
|
||||
g_free (command);
|
||||
|
||||
mm_callback_info_set_data (info, "pin_type", g_strdup (pin_type), g_free);
|
||||
|
||||
command = g_strdup_printf ("*EPIN?");
|
||||
mm_at_serial_port_queue_command (port, command, 3, send_epin_done, info);
|
||||
g_free (command);
|
||||
|
||||
@@ -270,22 +270,6 @@ get_band (MMModemGsmNetwork *modem,
|
||||
mm_at_serial_port_queue_command (port, "AT%IPBM?", 3, get_band_done, info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_samsung_num (const char *str, guint32 *out_num, guint32 min, guint32 max)
|
||||
{
|
||||
unsigned long int tmp;
|
||||
|
||||
if (!str || !strlen (str))
|
||||
return FALSE;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtoul (str, NULL, 10);
|
||||
if (errno != 0 || tmp < min || tmp > max)
|
||||
return FALSE;
|
||||
*out_num = (guint32) tmp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
send_samsung_pinnum_done (MMAtSerialPort *port,
|
||||
GString *response,
|
||||
@@ -293,12 +277,11 @@ send_samsung_pinnum_done (MMAtSerialPort *port,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||
GRegex *r = NULL;
|
||||
GMatchInfo *match_info = NULL;
|
||||
const char *pin_type;
|
||||
guint32 attempts_left = 0;
|
||||
char *str = NULL;
|
||||
guint32 num = 0;
|
||||
int matched;
|
||||
GArray *retry_counts;
|
||||
PinRetryCount ur[4] = {
|
||||
{"sim-pin", 0}, {"sim-puk", 0}, {"sim-pin2", 0}, {"sim-puk2", 0}
|
||||
};
|
||||
|
||||
/* If the modem has already been removed, return without
|
||||
* scheduling callback */
|
||||
@@ -310,58 +293,24 @@ send_samsung_pinnum_done (MMAtSerialPort *port,
|
||||
goto done;
|
||||
}
|
||||
|
||||
pin_type = mm_callback_info_get_data (info, "pin_type");
|
||||
|
||||
r = g_regex_new ("\\%PINNUM:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)", G_REGEX_UNGREEDY, 0, NULL);
|
||||
if (!r) {
|
||||
g_set_error_literal (&info->error,
|
||||
MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse %PINNUM results (error creating regex).");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!g_regex_match_full (r, response->str, response->len, 0, 0, &match_info, &info->error)) {
|
||||
g_set_error_literal (&info->error,
|
||||
MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse %PINNUM results (match failed).");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN))
|
||||
num = 1;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK))
|
||||
num = 2;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PIN2))
|
||||
num = 3;
|
||||
else if (strstr (pin_type, MM_MODEM_GSM_CARD_SIM_PUK2))
|
||||
num = 4;
|
||||
else {
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unhandled PIN type");
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
gboolean success = FALSE;
|
||||
|
||||
str = g_match_info_fetch (match_info, num);
|
||||
if (str) {
|
||||
success = parse_samsung_num (str, &attempts_left, 0, 10);
|
||||
g_free (str);
|
||||
matched = sscanf (response->str, "%%PINNUM: %d, %d, %d, %d",
|
||||
&ur[0].count, &ur[1].count, &ur[2].count, &ur[3].count);
|
||||
if (matched == 4) {
|
||||
if (ur[0].count > 998) {
|
||||
info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Invalid PIN attempts left %d", ur[0].count);
|
||||
ur[0].count = 0;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR,
|
||||
MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse %PINNUM results (missing or invalid match info).");
|
||||
}
|
||||
retry_counts = g_array_sized_new (FALSE, TRUE, sizeof (PinRetryCount), 4);
|
||||
g_array_append_vals (retry_counts, &ur, 4);
|
||||
mm_callback_info_set_result (info, retry_counts, NULL);
|
||||
} else {
|
||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||
"Could not parse PIN retries results");
|
||||
}
|
||||
|
||||
mm_callback_info_set_result (info, GUINT_TO_POINTER (attempts_left), NULL);
|
||||
|
||||
done:
|
||||
if (match_info)
|
||||
g_match_info_free (match_info);
|
||||
if (r)
|
||||
g_regex_unref (r);
|
||||
mm_serial_port_close (MM_SERIAL_PORT (port));
|
||||
mm_callback_info_schedule (info);
|
||||
}
|
||||
@@ -385,14 +334,13 @@ reset (MMModem *modem,
|
||||
|
||||
static void
|
||||
get_unlock_retries (MMModemGsmCard *modem,
|
||||
const char *pin_type,
|
||||
MMModemUIntFn callback,
|
||||
MMModemArrayFn callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMAtSerialPort *port;
|
||||
MMCallbackInfo *info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
|
||||
MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data);
|
||||
|
||||
mm_dbg ("pin type '%s'", pin_type);
|
||||
mm_dbg ("get_unlock_retries");
|
||||
|
||||
/* Ensure we have a usable port to use for the command */
|
||||
port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
|
||||
@@ -412,7 +360,6 @@ get_unlock_retries (MMModemGsmCard *modem,
|
||||
|
||||
/* if the modem have not yet been enabled we need to make sure echoing is turned off */
|
||||
mm_at_serial_port_queue_command (port, "E0", 3, NULL, NULL);
|
||||
mm_callback_info_set_data (info, "pin_type", g_strdup (pin_type), g_free);
|
||||
mm_at_serial_port_queue_command (port, "%PINNUM?", 3, send_samsung_pinnum_done, info);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user