diff options
author | Gjermund Hodnebrog <gjermund.hodnebrog@stericsson.com> | 2011-04-28 11:35:40 +0200 |
---|---|---|
committer | Sverre Vegge <sverre.vegge@stericsson.com> | 2011-05-19 09:19:47 +0200 |
commit | f0b40a37827b4fc7f8bf13a1e68315b55d9a2005 (patch) | |
tree | 92281799d472baf4bb2ced6498ae7185dc729a25 | |
parent | 22101ad2c410620bc52ce28b76df8620e81c3f4a (diff) | |
download | u300-f0b40a37827b4fc7f8bf13a1e68315b55d9a2005.tar.gz |
SIM: Distinguish between PUK1/PUK2 permanently blocked
When either PUK1 or PUK2 is blocked, AT+CPIN? responds
+CPIN: BLOCKED. RIL needs to issue AT*EPINR to distinguish if PUK1
or PUK2 is permanently blocked when reporting to Android.
Signed-off-by: Sverre Vegge <sverre.vegge@stericsson.com>
-rw-r--r-- | u300-ril-sim.c | 116 |
1 files changed, 65 insertions, 51 deletions
diff --git a/u300-ril-sim.c b/u300-ril-sim.c index 7edf58f..014d4e5 100644 --- a/u300-ril-sim.c +++ b/u300-ril-sim.c @@ -68,6 +68,7 @@ typedef enum { SIM_SERVICE_PROVIDER_PERSO_PUK = 17,/* Service Provider Perso. PUK */ SIM_CORPORATE_PERSO_PUK = 18, /* Corporate Personalization PUK */ SIM_SIM_PERSO_PUK = 19, /* SIM Personalization PUK (unused) */ + SIM_PUK2_PERM_BLOCKED = 20 /* PUK2 is permanently blocked */ } SIM_Status; /* @@ -241,6 +242,14 @@ static const RIL_AppStatus app_status_array[] = { NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN + }, + /* SIM_PUK2_PERM_BLOCKED = 20 */ + { + RIL_APPTYPE_SIM, RIL_APPSTATE_UNKNOWN, + RIL_PERSOSUBSTATE_UNKNOWN, + NULL, NULL, 0, + RIL_PINSTATE_UNKNOWN, + RIL_PINSTATE_ENABLED_PERM_BLOCKED } }; @@ -394,6 +403,55 @@ error: goto finally; } +/** + * Get the number of retries left for pin functions + */ +static int getNumRetries(int request) +{ + ATResponse *atresponse = NULL; + int err = 0; + char *cmd = NULL; + char *line = NULL; + int num_retries = -1; + int type; + + switch (request) { + case RIL_REQUEST_ENTER_SIM_PIN: + case RIL_REQUEST_CHANGE_SIM_PIN: + type = SIM_PIN_VERIFICATION; + break; + case RIL_REQUEST_ENTER_SIM_PIN2: + case RIL_REQUEST_CHANGE_SIM_PIN2: + type = SIM_PIN2_VERIFICATION; + break; + case RIL_REQUEST_ENTER_SIM_PUK: + type = SIM_PUK_VERIFICATION; + break; + case RIL_REQUEST_ENTER_SIM_PUK2: + type = SIM_PUK2_VERIFICATION; + break; + default: + num_retries = -1; + LOGE("%s(): Unknown request type", __func__); + goto exit; + } + + asprintf(&cmd, "AT*EPINR=%d", type); + err = at_send_command_singleline(cmd, "*EPINR:", &atresponse); + free(cmd); + if (err < 0 || atresponse->success == 0) { + LOGE("%s(): AT*EPINR error", __func__); + goto exit; + } + + line = atresponse->p_intermediates->line; + sscanf(line, "*EPINR: %d", &num_retries); + +exit: + at_response_free(atresponse); + return num_retries; +} + /** Returns one of SIM_*. Returns SIM_NOT_READY on error. */ static SIM_Status getSIMStatus() { @@ -503,7 +561,11 @@ static SIM_Status getSIMStatus() } else if (0 == strcmp(cpinResult, "PH-ESL PIN")) { ret = SIM_STERICSSON_LOCK; } else if (0 == strcmp(cpinResult, "BLOCKED")) { - ret = SIM_PERM_BLOCKED; + int numRetries = getNumRetries(RIL_REQUEST_ENTER_SIM_PUK); + if (numRetries == -1 || numRetries == 0) + ret = SIM_PERM_BLOCKED; + else + ret = SIM_PUK2_PERM_BLOCKED; } else if (0 == strcmp(cpinResult, "PH-SIM PIN")) { /* * Should not happen since lock must first be set from the phone. @@ -653,6 +715,7 @@ void pollSIMState(void *param) case SIM_PIN2: case SIM_PUK2: + case SIM_PUK2_PERM_BLOCKED: case SIM_READY: setRadioState(RADIO_STATE_SIM_READY); return; @@ -680,56 +743,6 @@ void pollSIMState(void *param) } /** - * Get the number of retries left for pin functions - */ -static int getNumRetries(int request) -{ - ATResponse *atresponse = NULL; - int err = 0; - char *cmd = NULL; - char *line = NULL; - int num_retries = -1; - int type; - - switch (request) { - case RIL_REQUEST_ENTER_SIM_PIN: - case RIL_REQUEST_CHANGE_SIM_PIN: - type = SIM_PIN_VERIFICATION; - break; - case RIL_REQUEST_ENTER_SIM_PIN2: - case RIL_REQUEST_CHANGE_SIM_PIN2: - type = SIM_PIN2_VERIFICATION; - break; - case RIL_REQUEST_ENTER_SIM_PUK: - type = SIM_PUK_VERIFICATION; - break; - case RIL_REQUEST_ENTER_SIM_PUK2: - type = SIM_PUK2_VERIFICATION; - break; - default: - num_retries = -1; - goto error; - } - - asprintf(&cmd, "AT*EPINR=%d", type); - err = at_send_command_singleline(cmd, "*EPINR:", &atresponse); - free(cmd); - if (err < 0 || atresponse->success == 0) - goto error; - - line = atresponse->p_intermediates->line; - sscanf(line, "*EPINR: %d", &num_retries); - -finally: - at_response_free(atresponse); - return num_retries; - -error: - LOGE("ERROR in getNumRetries()"); - goto finally; -} - -/** * RIL_REQUEST_GET_SIM_STATUS * * Requests status of the SIM interface and the SIM card. @@ -1522,6 +1535,7 @@ void requestEnterSimPin(void *data, size_t datalen, RIL_Token t, int request) case CME_INCORRECT_PASSWORD: case CME_SIM_PIN2_REQUIRED: case CME_SIM_PUK2_REQUIRED: + case CME_SIM_FAILURE: num_retries = getNumRetries(request); RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &num_retries, sizeof(int *)); goto finally; |