2 * This file is part of samsung-ril.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5 * Copyright (C) 2011-2012 Paul Kocialkowski <contact@oaulk.fr>
7 * samsung-ril is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * samsung-ril is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
22 #define LOG_TAG "RIL-SEC"
23 #include <utils/Log.h>
25 #include "samsung-ril.h"
28 SIM_Status ipc2ril_sim_status(struct ipc_sec_sim_status_response *pin_status)
30 switch(pin_status->status) {
31 case IPC_SEC_SIM_STATUS_INITIALIZING:
33 case IPC_SEC_SIM_STATUS_LOCK_SC:
34 switch(pin_status->facility_lock) {
35 case IPC_SEC_FACILITY_LOCK_TYPE_SC_UNLOCKED:
37 case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ:
39 case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ:
41 case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED:
44 LOGE("%s: unknown SC substate %d --> setting SIM_ABSENT", __FUNCTION__, pin_status->facility_lock);
48 case IPC_SEC_SIM_STATUS_LOCK_FD:
49 LOGE("%s: FD lock present (unhandled state --> setting SIM_ABSENT)", __FUNCTION__);
51 case IPC_SEC_SIM_STATUS_LOCK_PN:
52 return SIM_NETWORK_PERSO;
53 case IPC_SEC_SIM_STATUS_LOCK_PU:
54 return SIM_NETWORK_SUBSET_PERSO;
55 case IPC_SEC_SIM_STATUS_LOCK_PP:
56 return SIM_SERVICE_PROVIDER_PERSO;
57 case IPC_SEC_SIM_STATUS_LOCK_PC:
58 return SIM_CORPORATE_PERSO;
59 case IPC_SEC_SIM_STATUS_INIT_COMPLETE:
61 case IPC_SEC_SIM_STATUS_PB_INIT_COMPLETE:
62 /* Ignore phone book init complete */
63 return ril_state.sim_status;
64 case IPC_SEC_SIM_STATUS_SIM_LOCK_REQUIRED:
65 case IPC_SEC_SIM_STATUS_INSIDE_PF_ERROR:
66 case IPC_SEC_SIM_STATUS_CARD_NOT_PRESENT:
67 case IPC_SEC_SIM_STATUS_CARD_ERROR:
69 /* Catchall for locked, card error and unknown states */
75 * Update the radio state based on SIM status
77 * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
78 * Indicate when value of RIL_RadioState has changed
79 * Callee will invoke RIL_RadioStateRequest method on main thread
81 void ril_state_update(SIM_Status status)
83 RIL_RadioState radio_state;
85 /* If power mode isn't at least normal, don't update RIL state */
86 if(ril_state.power_mode < POWER_MODE_NORMAL)
89 ril_state.sim_status = status;
94 radio_state = RADIO_STATE_ON;
96 radio_state = RADIO_STATE_SIM_READY;
100 radio_state = RADIO_STATE_SIM_NOT_READY;
106 case SIM_NETWORK_PERSO:
107 case SIM_NETWORK_SUBSET_PERSO:
108 case SIM_CORPORATE_PERSO:
109 case SIM_SERVICE_PROVIDER_PERSO:
110 radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT;
113 radio_state = RADIO_STATE_SIM_NOT_READY;
118 ril_state.radio_state = radio_state;
122 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
125 void ipc2ril_card_status(struct ipc_sec_sim_status_response *pin_status, RIL_CardStatus *card_status)
127 SIM_Status sim_status;
128 int app_status_array_length;
132 static RIL_AppStatus app_status_array[] = {
134 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
135 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
136 /* SIM_NOT_READY = 1 */
137 { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
138 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
140 { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
141 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
143 { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
144 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
146 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
147 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
148 /* SIM_BLOCKED = 4 */
149 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
150 NULL, NULL, 0, RIL_PINSTATE_ENABLED_PERM_BLOCKED, RIL_PINSTATE_UNKNOWN },
151 /* SIM_NETWORK_PERSO = 6 */
152 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
153 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
154 /* SIM_NETWORK_SUBSET_PERSO = 7 */
155 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET,
156 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
157 /* SIM_CORPORATE_PERSO = 8 */
158 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_CORPORATE,
159 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
160 /* SIM_SERVICE_PROVIDER_PERSO = 9 */
161 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
162 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
165 app_status_array_length = sizeof(app_status_array) / sizeof(RIL_AppStatus);
167 if(app_status_array_length > RIL_CARD_MAX_APPS)
168 app_status_array_length = RIL_CARD_MAX_APPS;
170 sim_status = ipc2ril_sim_status(pin_status);
172 /* Card is assumed to be present if not explicitly absent */
173 if(sim_status == SIM_ABSENT) {
174 card_status->card_state = RIL_CARDSTATE_ABSENT;
176 card_status->card_state = RIL_CARDSTATE_PRESENT;
179 // FIXME: How do we know that?
180 card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
182 // Initialize the apps
183 for (i = 0 ; i < app_status_array_length ; i++) {
184 memcpy((void *) &(card_status->applications[i]), (void *) &(app_status_array[i]), sizeof(RIL_AppStatus));
186 for(i = app_status_array_length ; i < RIL_CARD_MAX_APPS ; i++) {
187 memset((void *) &(card_status->applications[i]), 0, sizeof(RIL_AppStatus));
190 // sim_status corresponds to the app index on the table
191 card_status->gsm_umts_subscription_app_index = (int) sim_status;
192 card_status->cdma_subscription_app_index = (int) sim_status;
193 card_status->num_applications = app_status_array_length;
195 LOGD("Selecting application #%d on %d", (int) sim_status, app_status_array_length);
198 void ril_tokens_pin_status_dump(void)
200 LOGD("ril_tokens_pin_status_dump:\n\
201 \tril_state.tokens.pin_status = 0x%p\n", ril_state.tokens.pin_status);
205 * In: IPC_SEC_SIM_STATUS
206 * Provides SIM initialization/lock status
208 * Out: RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED
209 * Indicates that SIM state changes.
210 * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread
212 * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
213 * Indicate when value of RIL_RadioState has changed
214 * Callee will invoke RIL_RadioStateRequest method on main thread
216 void ipc_sec_sim_status(struct ipc_message_info *info)
218 RIL_Token t = reqGetToken(info->aseq);
219 struct ipc_sec_sim_status_response *pin_status = (struct ipc_sec_sim_status_response *) info->data;
220 RIL_CardStatus card_status;
221 SIM_Status sim_status;
223 if(ril_state.power_mode == POWER_MODE_NORMAL && ril_state.tokens.radio_power != (RIL_Token) 0x00) {
224 RIL_onRequestComplete(ril_state.tokens.radio_power, RIL_E_SUCCESS, NULL, 0);
225 ril_state.tokens.radio_power = (RIL_Token) 0x00;
230 // Don't consider this if modem isn't in normal power mode
231 if(ril_state.power_mode < POWER_MODE_NORMAL)
234 LOGD("Got UNSOL PIN status message");
236 if(ril_state.tokens.pin_status != (RIL_Token) 0x00 && ril_state.tokens.pin_status != RIL_TOKEN_DATA_WAITING) {
237 LOGE("Another PIN status Req is in progress, skipping");
241 sim_status = ipc2ril_sim_status(pin_status);
242 ril_state_update(sim_status);
244 memcpy(&(ril_state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
246 ril_state.tokens.pin_status = RIL_TOKEN_DATA_WAITING;
247 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
250 LOGD("Got SOL PIN status message");
252 if(ril_state.tokens.pin_status != t)
253 LOGE("PIN status tokens mismatch");
255 sim_status = ipc2ril_sim_status(pin_status);
256 ril_state_update(sim_status);
258 // Better keeping this up to date
259 memcpy(&(ril_state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
261 ipc2ril_card_status(pin_status, &card_status);
262 RIL_onRequestComplete(t, RIL_E_SUCCESS, &card_status, sizeof(RIL_CardStatus));
264 if(ril_state.tokens.pin_status != RIL_TOKEN_DATA_WAITING)
265 ril_state.tokens.pin_status = (RIL_Token) 0x00;
268 LOGE("%s: unhandled ipc method: %d", __FUNCTION__, info->type);
272 ril_tokens_pin_status_dump();
276 * In: RIL_REQUEST_GET_SIM_STATUS
277 * Requests status of the SIM interface and the SIM card
279 void ril_request_get_sim_status(RIL_Token t)
281 struct ipc_sec_sim_status_response *pin_status;
282 RIL_CardStatus card_status;
283 SIM_Status sim_status;
285 if(ril_state.tokens.pin_status == RIL_TOKEN_DATA_WAITING) {
286 LOGD("Got RILJ request for UNSOL data");
287 hex_dump(&(ril_state.sim_pin_status), sizeof(struct ipc_sec_sim_status_response));
288 pin_status = &(ril_state.sim_pin_status);
290 ipc2ril_card_status(pin_status, &card_status);
292 RIL_onRequestComplete(t, RIL_E_SUCCESS, &card_status, sizeof(RIL_CardStatus));
294 ril_state.tokens.pin_status = (RIL_Token) 0x00;
295 } else if(ril_state.tokens.pin_status == (RIL_Token) 0x00) {
296 LOGD("Got RILJ request for SOL data");
298 /* Request data to the modem */
299 ril_state.tokens.pin_status = t;
301 ipc_fmt_send_get(IPC_SEC_SIM_STATUS, reqGetId(t));
303 LOGE("Another request is going on, returning UNSOL data");
305 pin_status = &(ril_state.sim_pin_status);
307 ipc2ril_card_status(pin_status, &card_status);
308 RIL_onRequestComplete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
311 ril_tokens_pin_status_dump();
315 * In: RIL_REQUEST_SIM_IO
316 * Request SIM I/O operation.
317 * This is similar to the TS 27.007 "restricted SIM" operation
318 * where it assumes all of the EF selection will be done by the
321 * Out: IPC_SEC_RSIM_ACCESS
322 * Performs a restricted SIM read operation
324 void ril_request_sim_io(RIL_Token t, void *data, size_t datalen)
326 const RIL_SIM_IO *sim_io;
327 unsigned char message[262];
328 struct ipc_sec_rsim_access_get *rsim_data;
330 unsigned char *rsim_payload;
333 sim_io = (const RIL_SIM_IO*)data;
334 rsim_payload = message + sizeof(*rsim_data);
336 /* Set up RSIM header */
337 rsim_data = (struct ipc_sec_rsim_access_get*)message;
338 rsim_data->command = sim_io->command;
339 rsim_data->fileid = sim_io->fileid;
340 rsim_data->p1 = sim_io->p1;
341 rsim_data->p2 = sim_io->p2;
342 rsim_data->p3 = sim_io->p3;
344 /* Add payload if present */
346 payload_length = (2 * strlen(sim_io->data));
348 if(sizeof(*rsim_data) + payload_length > sizeof(message))
351 hex2bin(sim_io->data, strlen(sim_io->data), rsim_payload);
354 ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, (unsigned char*)&message, sizeof(message), reqGetId(t));
358 * In: IPC_SEC_RSIM_ACCESS
359 * Provides restricted SIM read operation result
361 * Out: RIL_REQUEST_SIM_IO
362 * Request SIM I/O operation.
363 * This is similar to the TS 27.007 "restricted SIM" operation
364 * where it assumes all of the EF selection will be done by the
367 void ipc_sec_rsim_access(struct ipc_message_info *info)
369 struct ipc_sec_rsim_access_response *rsim_resp = (struct ipc_sec_rsim_access_response *) info->data;
370 const unsigned char *data_ptr = ((unsigned char *) info->data + sizeof(*rsim_resp));
372 RIL_SIM_IO_Response response;
374 response.sw1 = rsim_resp->sw1;
375 response.sw2 = rsim_resp->sw2;
378 sim_resp = (char*)malloc(rsim_resp->len * 2 + 1);
379 bin2hex(data_ptr, rsim_resp->len, sim_resp);
380 response.simResponse = sim_resp;
382 response.simResponse = malloc(1);
383 response.simResponse[0] = '\0';
386 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &response, sizeof(response));
388 free(response.simResponse);
392 * In: IPC_GEN_PHONE_RES
393 * Provides result of IPC_SEC_SIM_STATUS SET
395 * Out: RIL_REQUEST_ENTER_SIM_PIN
396 * Returns PIN SIM unlock result
398 void ipc_sec_sim_status_complete(struct ipc_message_info *info)
400 struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
405 rc = ipc_gen_phone_res_check(phone_res);
407 if((phone_res->code & 0x00ff) == 0x10) {
408 LOGE("Wrong password!");
409 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
410 } else if((phone_res->code & 0x00ff) == 0x0c) {
411 LOGE("Wrong password and no attempts left!");
414 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
416 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
418 LOGE("There was an error during pin status complete!");
419 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
424 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &attempts, sizeof(attempts));
428 * In: IPC_SEC_LOCK_INFO
429 * Provides number of retries left for a lock type
431 void ipc_sec_lock_info(struct ipc_message_info *info)
434 * FIXME: solid way of handling lockinfo and sim unlock response together
435 * so we can return the number of attempts left in respondSecPinStatus
438 struct ipc_sec_lock_info_response *lock_info = (struct ipc_sec_lock_info_response *) info->data;
440 if(lock_info->type == IPC_SEC_PIN_TYPE_PIN1) {
441 attempts = lock_info->attempts;
442 LOGD("%s: PIN1 %d attempts left", __FUNCTION__, attempts);
444 LOGE("%s: unhandled lock type %d", __FUNCTION__, lock_info->type);
449 * In: RIL_REQUEST_ENTER_SIM_PIN
450 * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state
452 * Out: IPC_SEC_SIM_STATUS SET
453 * Attempts to unlock SIM PIN1
455 * Out: IPC_SEC_LOCK_INFO
456 * Retrieves PIN1 lock status
458 void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t datalen)
460 struct ipc_sec_pin_status_set pin_status;
461 char *pin = ((char **) data)[0];
462 unsigned char buf[9];
465 if(strlen(data) > 16) {
466 LOGE("%s: pin exceeds maximum length", __FUNCTION__);
467 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
470 ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, NULL);
472 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SEC_SIM_STATUS,
473 ipc_sec_sim_status_complete);
475 ipc_fmt_send_set(IPC_SEC_SIM_STATUS, reqGetId(t), (unsigned char *) &pin_status, sizeof(pin_status));
477 /* 2. Get lock status */
478 // FIXME: This is not clean at all
479 memset(buf, 0, sizeof(buf));
481 buf[1] = IPC_SEC_PIN_TYPE_PIN1;
483 ipc_fmt_send(IPC_SEC_LOCK_INFO, IPC_TYPE_GET, buf, sizeof(buf), reqGetId(t));
486 void ril_request_change_sim_pin(RIL_Token t, void *data, size_t datalen)
488 char *password_old = ((char **) data)[0];
489 char *password_new = ((char **) data)[1];
490 struct ipc_sec_change_locking_pw locking_pw;
492 memset(&locking_pw, 0, sizeof(locking_pw));
494 locking_pw.facility = IPC_SEC_SIM_STATUS_LOCK_SC;
496 locking_pw.length_new = strlen(password_new) > sizeof(locking_pw.password_new)
497 ? sizeof(locking_pw.password_new)
498 : strlen(password_new);
500 memcpy(locking_pw.password_new, password_new, locking_pw.length_new);
502 locking_pw.length_old = strlen(password_old) > sizeof(locking_pw.password_old)
503 ? sizeof(locking_pw.password_old)
504 : strlen(password_old);
506 memcpy(locking_pw.password_old, password_old, locking_pw.length_old);
508 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SEC_CHANGE_LOCKING_PW,
509 ipc_sec_sim_status_complete);
511 ipc_fmt_send_set(IPC_SEC_CHANGE_LOCKING_PW, reqGetId(t), (unsigned char *) &locking_pw, sizeof(locking_pw));
514 void ril_request_enter_sim_puk(RIL_Token t, void *data, size_t datalen)
516 struct ipc_sec_pin_status_set pin_status;
517 char *puk = ((char **) data)[0];
518 char *pin = ((char **) data)[1];
520 ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, puk);
522 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SEC_SIM_STATUS,
523 ipc_sec_sim_status_complete);
525 ipc_fmt_send_set(IPC_SEC_SIM_STATUS, reqGetId(t), (unsigned char *) &pin_status, sizeof(pin_status));
529 * In: IPC_SEC_PHONE_LOCK
531 * Out: RIL_REQUEST_QUERY_FACILITY_LOCK
532 * Query the status of a facility lock state
534 void ipc_sec_phone_lock(struct ipc_message_info *info)
537 struct ipc_sec_phone_lock_response *lock = (struct ipc_sec_phone_lock_response *) info->data;
539 status = lock->status;
541 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &status, sizeof(status));
545 * In: RIL_REQUEST_QUERY_FACILITY_LOCK
546 * Query the status of a facility lock state
548 * Out: IPC_SEC_PHONE_LOCK GET
550 void ril_request_query_facility_lock(RIL_Token t, void *data, size_t datalen)
552 struct ipc_sec_phone_lock_get lock_request;
554 char *facility = ((char **) data)[0];
556 if(!strcmp(facility, "SC")) {
557 lock_request.facility = IPC_SEC_FACILITY_TYPE_SC;
558 } else if(!strcmp(facility, "FD")) {
559 lock_request.facility = IPC_SEC_FACILITY_TYPE_FD;
560 } else if(!strcmp(facility, "PN")) {
561 lock_request.facility = IPC_SEC_FACILITY_TYPE_PN;
562 } else if(!strcmp(facility, "PU")) {
563 lock_request.facility = IPC_SEC_FACILITY_TYPE_PU;
564 } else if(!strcmp(facility, "PP")) {
565 lock_request.facility = IPC_SEC_FACILITY_TYPE_PP;
566 } else if(!strcmp(facility, "PC")) {
567 lock_request.facility = IPC_SEC_FACILITY_TYPE_PC;
569 LOGE("%s: unsupported facility: %s", __FUNCTION__, facility);
570 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
572 ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, &lock_request, sizeof(lock_request), reqGetId(t));
575 // Both functions were the same
576 #define ipc_sec_phone_lock_complete \
577 ipc_sec_sim_status_complete
580 * In: RIL_REQUEST_SET_FACILITY_LOCK
581 * Enable/disable one facility lock
583 * Out: IPC_SEC_PHONE_LOCK SET
585 void ril_request_set_facility_lock(RIL_Token t, void *data, size_t datalen)
587 struct ipc_sec_phone_lock_set lock_request;
589 char *facility = ((char **) data)[0];
590 char *lock = ((char **) data)[1];
591 char *password = ((char **) data)[2];
592 char *class = ((char **) data)[3];
594 memset(&lock_request, 0, sizeof(lock_request));
596 if(!strcmp(facility, "SC")) {
597 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_SC;
598 } else if(!strcmp(facility, "FD")) {
599 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_FD;
600 } else if(!strcmp(facility, "PN")) {
601 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PN;
602 } else if(!strcmp(facility, "PU")) {
603 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PU;
604 } else if(!strcmp(facility, "PP")) {
605 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PP;
606 } else if(!strcmp(facility, "PC")) {
607 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PC;
609 LOGE("%s: unsupported facility: %s", __FUNCTION__, facility);
610 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
613 lock_request.lock = lock[0] == '1' ? 1 : 0;
614 lock_request.length = strlen(password) > sizeof(lock_request.password)
615 ? sizeof(lock_request.password)
618 memcpy(lock_request.password, password, lock_request.length);
620 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_SEC_PHONE_LOCK,
621 ipc_sec_phone_lock_complete);
623 ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, &lock_request, sizeof(lock_request), reqGetId(t));