aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGjermund Hodnebrog <gjermund.hodnebrog@stericsson.com>2011-04-28 11:35:40 +0200
committerSverre Vegge <sverre.vegge@stericsson.com>2011-05-19 09:19:47 +0200
commitf0b40a37827b4fc7f8bf13a1e68315b55d9a2005 (patch)
tree92281799d472baf4bb2ced6498ae7185dc729a25
parent22101ad2c410620bc52ce28b76df8620e81c3f4a (diff)
downloadu300-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.c116
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;