2 * This file is part of hayes-ril.
4 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
6 * Parts of this code are based on htcgeneric-ril, reference-ril:
7 * Copyright 2006-2011, htcgeneric-ril contributors
8 * Copyright 2006, The Android Open Source Project
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #define LOG_TAG "RIL-SIM"
26 #include <utils/Log.h>
27 #include <telephony/ril.h>
29 #include <hayes-ril.h>
31 RIL_RadioState at2ril_sim_status(int status, char *error, char **data, int data_count)
36 if(status == AT_STATUS_CME_ERROR && error != NULL) {
39 case AT_CME_ERROR_PH_SIM_PIN_REQD:
40 case AT_CME_ERROR_PH_SIM_PUK_REQD:
41 case AT_CME_ERROR_PH_FSIM_PIN_REQD:
42 case AT_CME_ERROR_PH_FSIM_PUK_REQD:
43 case AT_CME_ERROR_SIM_NOT_INSERTED:
44 case AT_CME_ERROR_SIM_PIN_REQD:
45 case AT_CME_ERROR_SIM_PUK_REQD:
46 case AT_CME_ERROR_SIM_PIN2_REQD:
47 case AT_CME_ERROR_SIM_PUK2_REQD:
48 case AT_CME_ERROR_SIM_BLOCKED:
49 return RADIO_STATE_SIM_LOCKED_OR_ABSENT;
50 case AT_CME_ERROR_SIM_FAILURE:
51 case AT_CME_ERROR_SIM_BUSY:
52 case AT_CME_ERROR_SIM_WRONG:
53 case AT_CME_ERROR_SIM_POWERED_DOWN:
55 return RADIO_STATE_SIM_NOT_READY;
57 } else if(status == AT_STATUS_OK) {
58 if(data != NULL && data_count > 0) {
59 for(i=0 ; i < data_count ; i++) {
60 if(at_strings_raw_compare("SIM PIN", data[i])) {
61 return RADIO_STATE_SIM_LOCKED_OR_ABSENT;
62 } else if(at_strings_raw_compare("SIM PUK", data[i])) {
63 return RADIO_STATE_SIM_LOCKED_OR_ABSENT;
64 } else if(at_strings_raw_compare("READY", data[i])) {
65 return RADIO_STATE_SIM_READY;
71 return RADIO_STATE_SIM_NOT_READY;
73 // Various error codes, not helping here, don't change anything
74 return ril_globals.radio_state;
79 RIL_RadioState at2ril_card_status(RIL_CardStatus *card_status, int status, char *error, char **data, int data_count)
81 RIL_RadioState radio_state;
84 int app_status_array_length = 0;
88 static RIL_AppStatus app_status_array[] = {
90 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
91 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
93 { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
94 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
96 { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
97 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
99 { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
100 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
102 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
103 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
105 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
106 NULL, NULL, 0, RIL_PINSTATE_ENABLED_PERM_BLOCKED, RIL_PINSTATE_UNKNOWN },
107 // SIM_NETWORK_PERSO = 6
108 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
109 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
110 // SIM_NETWORK_SUBSET_PERSO = 7
111 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET,
112 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
113 // SIM_CORPORATE_PERSO = 8
114 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_CORPORATE,
115 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
116 // SIM_SERVICE_PROVIDER_PERSO = 9
117 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
118 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
121 app_status_array_length = sizeof(app_status_array) / sizeof(RIL_AppStatus);
123 if(app_status_array_length > RIL_CARD_MAX_APPS)
124 app_status_array_length = RIL_CARD_MAX_APPS;
126 radio_state = at2ril_sim_status(status, error, data, data_count);
128 if(status == AT_STATUS_CME_ERROR && error != NULL) {
132 case AT_CME_ERROR_SIM_NOT_INSERTED:
133 card_status->card_state = RIL_CARDSTATE_ABSENT;
134 card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
137 case AT_CME_ERROR_PH_SIM_PIN_REQD:
138 case AT_CME_ERROR_PH_FSIM_PIN_REQD:
139 case AT_CME_ERROR_SIM_PIN_REQD:
140 card_status->card_state = RIL_CARDSTATE_PRESENT;
141 card_status->universal_pin_state = RIL_PINSTATE_ENABLED_NOT_VERIFIED;
144 case AT_CME_ERROR_PH_SIM_PUK_REQD:
145 case AT_CME_ERROR_PH_FSIM_PUK_REQD:
146 case AT_CME_ERROR_SIM_PUK_REQD:
147 card_status->card_state = RIL_CARDSTATE_PRESENT;
148 card_status->universal_pin_state = RIL_PINSTATE_ENABLED_BLOCKED;
151 case AT_CME_ERROR_SIM_PIN2_REQD:
152 case AT_CME_ERROR_SIM_PUK2_REQD:
153 case AT_CME_ERROR_SIM_BLOCKED:
154 card_status->card_state = RIL_CARDSTATE_PRESENT;
155 card_status->universal_pin_state = RIL_PINSTATE_ENABLED_PERM_BLOCKED;
158 case AT_CME_ERROR_SIM_FAILURE:
159 case AT_CME_ERROR_SIM_BUSY:
160 case AT_CME_ERROR_SIM_WRONG:
161 case AT_CME_ERROR_SIM_POWERED_DOWN:
163 card_status->card_state = RIL_CARDSTATE_PRESENT;
164 card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
168 } else if(status == AT_STATUS_OK) {
169 if(data != NULL && data_count > 0) {
170 for(i=0 ; i < data_count ; i++) {
171 if(at_strings_raw_compare("SIM PIN", data[i])) {
172 card_status->card_state = RIL_CARDSTATE_PRESENT;
173 card_status->universal_pin_state = RIL_PINSTATE_ENABLED_NOT_VERIFIED;
175 } else if(at_strings_raw_compare("SIM PUK", data[i])) {
176 card_status->card_state = RIL_CARDSTATE_PRESENT;
177 card_status->universal_pin_state = RIL_PINSTATE_ENABLED_BLOCKED;
179 } else if(at_strings_raw_compare("READY", data[i])) {
180 card_status->card_state = RIL_CARDSTATE_PRESENT;
181 card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
189 if(app_index == -1) {
190 card_status->card_state = RIL_CARDSTATE_PRESENT;
191 card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
195 // Initialize the apps
196 for (i = 0 ; i < app_status_array_length ; i++) {
197 memcpy((void *) &(card_status->applications[i]), (void *) &(app_status_array[i]), sizeof(RIL_AppStatus));
199 for(i = app_status_array_length ; i < RIL_CARD_MAX_APPS ; i++) {
200 memset((void *) &(card_status->applications[i]), 0, sizeof(RIL_AppStatus));
203 card_status->gsm_umts_subscription_app_index = app_index;
204 card_status->cdma_subscription_app_index = app_index;
205 card_status->num_applications = app_status_array_length;
207 LOGD("Selecting application #%d on %d", app_index, app_status_array_length);
212 int at_cpin_expect(struct at_response *response, void *data, RIL_Token t)
214 RIL_CardStatus card_status;
215 RIL_RadioState radio_state;
217 if(response->status == AT_STATUS_UNDEF)
218 return AT_RESPONSE_UNHANDELD_REASON_STATUS;
220 if(t != (RIL_Token) 0x0000) {
221 radio_state = at2ril_card_status(&card_status, response->status, response->error, response->data, response->data_count);
222 ril_globals.radio_state = radio_state;
224 RIL_onRequestComplete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
226 radio_state = at2ril_sim_status(response->status, response->error, response->data, response->data_count);
227 if(ril_globals.radio_state != radio_state) {
228 ril_globals.radio_state = radio_state;
229 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
233 LOGD("Handled AT+CPIN response");
235 return AT_RESPONSE_HANDLED_OK;
238 void ril_request_get_sim_status(RIL_Token t, void *data, size_t length)
240 at_send_expect_to_func("AT+CPIN?", NULL, NULL, t, at_cpin_expect);