SIM: Added SIM PIN unlock
authorPaul Kocialkowski <contact@paulk.fr>
Fri, 27 Jul 2012 23:23:39 +0000 (01:23 +0200)
committerPaul Kocialkowski <contact@paulk.fr>
Fri, 27 Jul 2012 23:23:39 +0000 (01:23 +0200)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
hayes-ril.c
hayes-ril.h
sim.c

index bebd802..ff36106 100644 (file)
@@ -40,6 +40,9 @@ void ril_on_request(int request, void *data, size_t length, RIL_Token t)
                case RIL_REQUEST_GET_SIM_STATUS:
                        ril_request_get_sim_status(t, data, length);
                        break;
+               case RIL_REQUEST_ENTER_SIM_PIN:
+                       ril_request_enter_sim_pin(t, data, length);
+                       break;
                // Call
                case RIL_REQUEST_GET_CURRENT_CALLS:
                        ril_request_get_current_calls(t, data, length);
index 55368d5..13efa0e 100644 (file)
@@ -147,5 +147,6 @@ void ril_request_radio_power(RIL_Token t, void *data, size_t length);
 // SIM
 int at_cpin_expect(struct at_response *response, void *data, RIL_Token t);
 void ril_request_get_sim_status(RIL_Token t, void *data, size_t length);
+void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t length);
 
 #endif
diff --git a/sim.c b/sim.c
index 1f1237a..2d39a78 100644 (file)
--- a/sim.c
+++ b/sim.c
@@ -46,11 +46,12 @@ RIL_RadioState at2ril_sim_status(int status, char *error, char **data, int data_
                        case AT_CME_ERROR_SIM_PIN2_REQD:
                        case AT_CME_ERROR_SIM_PUK2_REQD:
                        case AT_CME_ERROR_SIM_BLOCKED:
+                       case AT_CME_ERROR_INCORRECT_PASSWORD:
                                return RADIO_STATE_SIM_LOCKED_OR_ABSENT;
                        case AT_CME_ERROR_SIM_FAILURE:
                        case AT_CME_ERROR_SIM_BUSY:
-                       case AT_CME_ERROR_SIM_WRONG:
                        case AT_CME_ERROR_SIM_POWERED_DOWN:
+                       case AT_CME_ERROR_SIM_WRONG:
                        default:
                                return RADIO_STATE_SIM_NOT_READY;
                }
@@ -137,6 +138,7 @@ RIL_RadioState at2ril_card_status(RIL_CardStatus *card_status, int status, char
                        case AT_CME_ERROR_PH_SIM_PIN_REQD:
                        case AT_CME_ERROR_PH_FSIM_PIN_REQD:
                        case AT_CME_ERROR_SIM_PIN_REQD:
+                       case AT_CME_ERROR_INCORRECT_PASSWORD:
                                card_status->card_state = RIL_CARDSTATE_PRESENT;
                                card_status->universal_pin_state = RIL_PINSTATE_ENABLED_NOT_VERIFIED;
                                app_index = 3;
@@ -157,8 +159,8 @@ RIL_RadioState at2ril_card_status(RIL_CardStatus *card_status, int status, char
                                break;
                        case AT_CME_ERROR_SIM_FAILURE:
                        case AT_CME_ERROR_SIM_BUSY:
-                       case AT_CME_ERROR_SIM_WRONG:
                        case AT_CME_ERROR_SIM_POWERED_DOWN:
+                       case AT_CME_ERROR_SIM_WRONG:
                        default:
                                card_status->card_state = RIL_CARDSTATE_PRESENT;
                                card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
@@ -224,10 +226,9 @@ int at_cpin_expect(struct at_response *response, void *data, RIL_Token t)
                RIL_onRequestComplete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
        } else {
                radio_state = at2ril_sim_status(response->status, response->error, response->data, response->data_count);
-               if(ril_globals.radio_state != radio_state) {
-                       ril_globals.radio_state = radio_state;
-                       RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
-               }
+               ril_globals.radio_state = radio_state;
+
+               RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
        }
 
        LOGD("Handled AT+CPIN response");
@@ -235,7 +236,41 @@ int at_cpin_expect(struct at_response *response, void *data, RIL_Token t)
        return AT_RESPONSE_HANDLED_OK;
 }
 
+int at_cpin_unlock_expect(struct at_response *response, void *data, RIL_Token t)
+{
+       int tries = -1;
+       int code = 0;
+
+       if(response->status == AT_STATUS_UNDEF)
+               return AT_RESPONSE_UNHANDELD_REASON_STATUS;
+
+       if(at_status_error(response->status)) {
+               if(response->status == AT_STATUS_CME_ERROR && response->error != NULL) {
+                       code = atoi(response->error);
+
+                       if(code == AT_CME_ERROR_INCORRECT_PASSWORD)
+                               RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &tries, sizeof(int *));
+               } else {
+                       RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
+               }
+       } else {
+               RIL_onRequestComplete(t, RIL_E_SUCCESS, &tries, sizeof(int *));
+       }
+
+       // Update radio state
+       at_send_expect_to_func("AT+CPIN?", NULL, NULL, 0x0000, at_cpin_expect);
+
+       return AT_RESPONSE_HANDLED_OK;
+}
+
 void ril_request_get_sim_status(RIL_Token t, void *data, size_t length)
 {
        at_send_expect_to_func("AT+CPIN?", NULL, NULL, t, at_cpin_expect);
 }
+
+void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t length)
+{
+       char *pin = ((char **) data)[0];
+
+       at_send_expect_to_func("AT+CPIN", pin, NULL, t, at_cpin_unlock_expect);
+}