summaryrefslogtreecommitdiffstats
path: root/sec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sec.c')
-rw-r--r--sec.c981
1 files changed, 0 insertions, 981 deletions
diff --git a/sec.c b/sec.c
deleted file mode 100644
index 7d92f26..0000000
--- a/sec.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- * This file is part of Samsung-RIL.
- *
- * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
- * Copyright (C) 2011-2013 Paul Kocialkowski <contact@paulk.fr>
- *
- * Samsung-RIL is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Samsung-RIL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define LOG_TAG "RIL-SEC"
-#include <utils/Log.h>
-
-#include "samsung-ril.h"
-#include "util.h"
-
-#include <sim.h>
-
-ril_sim_state ipc2ril_sim_state(struct ipc_sec_sim_status_response *pin_status)
-{
- if (pin_status == NULL)
- return -EINVAL;
-
- switch (pin_status->status) {
- case IPC_SEC_SIM_STATUS_LOCK_SC:
- switch (pin_status->facility_lock) {
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_UNLOCKED:
- return SIM_STATE_READY;
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ:
- return SIM_STATE_PIN;
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ:
- return SIM_STATE_PUK;
- case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED:
- return SIM_STATE_BLOCKED;
- default:
- RIL_LOGE("Unknown SIM facility lock: 0x%x", pin_status->facility_lock);
- return SIM_STATE_ABSENT;
- }
- break;
- case IPC_SEC_SIM_STATUS_LOCK_FD:
- return SIM_STATE_ABSENT;
- case IPC_SEC_SIM_STATUS_LOCK_PN:
- return SIM_STATE_NETWORK_PERSO;
- case IPC_SEC_SIM_STATUS_LOCK_PU:
- return SIM_STATE_NETWORK_SUBSET_PERSO;
- case IPC_SEC_SIM_STATUS_LOCK_PP:
- return SIM_STATE_SERVICE_PROVIDER_PERSO;
- case IPC_SEC_SIM_STATUS_LOCK_PC:
- return SIM_STATE_CORPORATE_PERSO;
- case IPC_SEC_SIM_STATUS_READY:
- case IPC_SEC_SIM_STATUS_INIT_COMPLETE:
- case IPC_SEC_SIM_STATUS_PB_INIT_COMPLETE:
- return SIM_STATE_READY;
- case IPC_SEC_SIM_STATUS_SIM_LOCK_REQUIRED:
- case IPC_SEC_SIM_STATUS_INSIDE_PF_ERROR:
- case IPC_SEC_SIM_STATUS_CARD_NOT_PRESENT:
- case IPC_SEC_SIM_STATUS_CARD_ERROR:
- return SIM_STATE_ABSENT;
- default:
- RIL_LOGE("Unknown SIM status: 0x%x", pin_status->status);
- return SIM_STATE_ABSENT;
- }
-}
-
-void ril_state_update(ril_sim_state sim_state)
-{
- RIL_RadioState radio_state;
-
- ril_data.state.sim_state = sim_state;
-
- switch (sim_state) {
- case SIM_STATE_READY:
-#if RIL_VERSION >= 7
- radio_state = RADIO_STATE_ON;
-#else
- radio_state = RADIO_STATE_SIM_READY;
-#endif
- break;
- case SIM_STATE_NOT_READY:
- radio_state = RADIO_STATE_SIM_NOT_READY;
- break;
- case SIM_STATE_ABSENT:
- case SIM_STATE_PIN:
- case SIM_STATE_PUK:
- case SIM_STATE_BLOCKED:
- case SIM_STATE_NETWORK_PERSO:
- case SIM_STATE_NETWORK_SUBSET_PERSO:
- case SIM_STATE_CORPORATE_PERSO:
- case SIM_STATE_SERVICE_PROVIDER_PERSO:
- radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT;
- break;
- default:
- radio_state = RADIO_STATE_SIM_NOT_READY;
- break;
- }
-
- ril_radio_state_update(radio_state);
-}
-
-#if RIL_VERSION >= 6
-void ipc2ril_card_status(struct ipc_sec_sim_status_response *pin_status, RIL_CardStatus_v6 *card_status)
-#else
-void ipc2ril_card_status(struct ipc_sec_sim_status_response *pin_status, RIL_CardStatus *card_status)
-#endif
-{
- ril_sim_state sim_state;
- int app_status_array_length;
- int app_index;
- int i;
-
- if (pin_status == NULL || card_status == NULL)
- return;
-
- static RIL_AppStatus app_status_array[] = {
- /* SIM_ABSENT = 0 */
- { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
- NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
- /* SIM_NOT_READY = 1 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
- NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
- /* SIM_READY = 2 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
- NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
- /* SIM_PIN = 3 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
- /* SIM_PUK = 4 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
- /* SIM_BLOCKED = 4 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_PERM_BLOCKED, RIL_PINSTATE_UNKNOWN },
- /* SIM_NETWORK_PERSO = 6 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
- /* SIM_NETWORK_SUBSET_PERSO = 7 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
- /* SIM_CORPORATE_PERSO = 8 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_CORPORATE,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
- /* SIM_SERVICE_PROVIDER_PERSO = 9 */
- { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
- NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
- };
-
- app_status_array_length = sizeof(app_status_array) / sizeof(RIL_AppStatus);
-
- if (app_status_array_length > RIL_CARD_MAX_APPS)
- app_status_array_length = RIL_CARD_MAX_APPS;
-
- sim_state = ipc2ril_sim_state(pin_status);
-
- /* Card is assumed to be present if not explicitly absent */
- if (sim_state == SIM_STATE_ABSENT) {
- card_status->card_state = RIL_CARDSTATE_ABSENT;
- } else {
- card_status->card_state = RIL_CARDSTATE_PRESENT;
- }
-
- // FIXME: How do we know that?
- card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
-
- // Initialize the apps
- for (i = 0 ; i < app_status_array_length ; i++) {
- memcpy((void *) &(card_status->applications[i]), (void *) &(app_status_array[i]), sizeof(RIL_AppStatus));
- }
- for (i = app_status_array_length ; i < RIL_CARD_MAX_APPS ; i++) {
- memset((void *) &(card_status->applications[i]), 0, sizeof(RIL_AppStatus));
- }
-
- // sim_state corresponds to the app index on the table
- card_status->gsm_umts_subscription_app_index = (int) sim_state;
- card_status->cdma_subscription_app_index = (int) sim_state;
- card_status->num_applications = app_status_array_length;
-
- RIL_LOGD("Selecting application #%d on %d", (int) sim_state, app_status_array_length);
-}
-
-void ril_tokens_pin_status_dump(void)
-{
- RIL_LOGD("ril_tokens_pin_status_dump:\n\
- \tril_data.tokens.pin_status = %p\n", ril_data.tokens.pin_status);
-}
-
-void ipc_sec_sim_status(struct ipc_message_info *info)
-{
- struct ipc_sec_sim_status_response *pin_status;
- RIL_Token t;
-#if RIL_VERSION >= 6
- RIL_CardStatus_v6 card_status;
-#else
- RIL_CardStatus card_status;
-#endif
- ril_sim_state sim_state;
-
- if (info->data == NULL || info->length < sizeof(struct ipc_sec_sim_status_response))
- goto error;
-
- pin_status = (struct ipc_sec_sim_status_response *) info->data;
- t = ril_request_get_token(info->aseq);
-
- switch (info->type) {
- case IPC_TYPE_NOTI:
- if (ril_radio_state_complete(RADIO_STATE_OFF, RIL_TOKEN_NULL))
- return;
-
- RIL_LOGD("Got UNSOL PIN status message");
-
- if (ril_data.tokens.pin_status != RIL_TOKEN_NULL && ril_data.tokens.pin_status != RIL_TOKEN_DATA_WAITING) {
- RIL_LOGE("Another PIN status Req is in progress, skipping");
- return;
- }
-
- sim_state = ipc2ril_sim_state(pin_status);
- ril_state_update(sim_state);
-
- memcpy(&(ril_data.state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
-
- ril_data.tokens.pin_status = RIL_TOKEN_DATA_WAITING;
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
- break;
- case IPC_TYPE_RESP:
- RIL_LOGD("Got SOL PIN status message");
-
- if (ril_data.tokens.pin_status != t)
- RIL_LOGE("PIN status tokens mismatch");
-
- sim_state = ipc2ril_sim_state(pin_status);
- ril_state_update(sim_state);
-
- // Better keeping this up to date
- memcpy(&(ril_data.state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
-
- ipc2ril_card_status(pin_status, &card_status);
- ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
-
- if (ril_data.tokens.pin_status != RIL_TOKEN_DATA_WAITING)
- ril_data.tokens.pin_status = RIL_TOKEN_NULL;
- break;
- default:
- RIL_LOGE("%s: unhandled ipc method: %d", __func__, info->type);
- break;
- }
-
- ril_tokens_pin_status_dump();
-
- return;
-
-error:
- if (info != NULL)
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ril_request_get_sim_status(RIL_Token t)
-{
- struct ipc_sec_sim_status_response *pin_status;
-#if RIL_VERSION >= 6
- RIL_CardStatus_v6 card_status;
-#else
- RIL_CardStatus card_status;
-#endif
-
- if (ril_radio_state_complete(RADIO_STATE_OFF, t))
- return;
-
- if (ril_data.tokens.pin_status == RIL_TOKEN_DATA_WAITING) {
- RIL_LOGD("Got RILJ request for UNSOL data");
- hex_dump(&(ril_data.state.sim_pin_status), sizeof(struct ipc_sec_sim_status_response));
- pin_status = &(ril_data.state.sim_pin_status);
-
- ipc2ril_card_status(pin_status, &card_status);
-
- ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
-
- ril_data.tokens.pin_status = RIL_TOKEN_NULL;
- } else if (ril_data.tokens.pin_status == RIL_TOKEN_NULL) {
- RIL_LOGD("Got RILJ request for SOL data");
-
- /* Request data to the modem */
- ril_data.tokens.pin_status = t;
-
- ipc_fmt_send_get(IPC_SEC_SIM_STATUS, ril_request_get_id(t));
- } else {
- RIL_LOGE("Another request is going on, returning UNSOL data");
-
- pin_status = &(ril_data.state.sim_pin_status);
-
- ipc2ril_card_status(pin_status, &card_status);
- ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
- }
-
- ril_tokens_pin_status_dump();
-}
-
-void ipc_sec_sim_icc_type(struct ipc_message_info *info)
-{
- struct ipc_sec_sim_icc_type *sim_icc_type;
-
- if (info->data == NULL || info->length < sizeof(struct ipc_sec_sim_icc_type))
- goto error;
-
- sim_icc_type = (struct ipc_sec_sim_icc_type *) info->data;
-
- memcpy(&ril_data.state.sim_icc_type, sim_icc_type, sizeof(struct ipc_sec_sim_icc_type));
-
- return;
-
-error:
- if (info != NULL)
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-/*
- * SIM I/O
- */
-
-int ril_request_sim_io_register(RIL_Token t, unsigned char command, unsigned short fileid,
- unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length,
- struct ril_request_sim_io_info **sim_io_p)
-{
- struct ril_request_sim_io_info *sim_io;
- struct list_head *list_end;
- struct list_head *list;
-
- sim_io = calloc(1, sizeof(struct ril_request_sim_io_info));
- if (sim_io == NULL)
- return -1;
-
- sim_io->command = command;
- sim_io->fileid = fileid;
- sim_io->p1 = p1;
- sim_io->p2 = p2;
- sim_io->p3 = p3;
- sim_io->data = data;
- sim_io->length = length;
- sim_io->waiting = 1;
- sim_io->token = t;
-
- list_end = ril_data.sim_io;
- while (list_end != NULL && list_end->next != NULL)
- list_end = list_end->next;
-
- list = list_head_alloc((void *) sim_io, list_end, NULL);
-
- if (ril_data.sim_io == NULL)
- ril_data.sim_io = list;
-
- if (sim_io_p != NULL)
- *sim_io_p = sim_io;
-
- return 0;
-}
-
-void ril_request_sim_io_unregister(struct ril_request_sim_io_info *sim_io)
-{
- struct list_head *list;
-
- if (sim_io == NULL)
- return;
-
- list = ril_data.sim_io;
- while (list != NULL) {
- if (list->data == (void *) sim_io) {
- memset(sim_io, 0, sizeof(struct ril_request_sim_io_info));
- free(sim_io);
-
- if (list == ril_data.sim_io)
- ril_data.sim_io = list->next;
-
- list_head_free(list);
-
- break;
- }
-list_continue:
- list = list->next;
- }
-}
-
-struct ril_request_sim_io_info *ril_request_sim_io_info_find(void)
-{
- struct ril_request_sim_io_info *sim_io;
- struct list_head *list;
-
- list = ril_data.sim_io;
- while (list != NULL) {
- sim_io = (struct ril_request_sim_io_info *) list->data;
- if (sim_io == NULL)
- goto list_continue;
-
- return sim_io;
-
-list_continue:
- list = list->next;
- }
-
- return NULL;
-}
-
-struct ril_request_sim_io_info *ril_request_sim_io_info_find_token(RIL_Token t)
-{
- struct ril_request_sim_io_info *sim_io;
- struct list_head *list;
-
- list = ril_data.sim_io;
- while (list != NULL) {
- sim_io = (struct ril_request_sim_io_info *) list->data;
- if (sim_io == NULL)
- goto list_continue;
-
- if (sim_io->token == t)
- return sim_io;
-
-list_continue:
- list = list->next;
- }
-
- return NULL;
-}
-
-void ril_request_sim_io_info_clear(struct ril_request_sim_io_info *sim_io)
-{
- if (sim_io == NULL)
- return;
-
- if (sim_io->data != NULL)
- free(sim_io->data);
-}
-
-void ril_request_sim_io_next(void)
-{
- struct ril_request_sim_io_info *sim_io;
- int rc;
-
- ril_data.tokens.sim_io = RIL_TOKEN_NULL;
-
- sim_io = ril_request_sim_io_info_find();
- if (sim_io == NULL)
- return;
-
- sim_io->waiting = 0;
- ril_data.tokens.sim_io = sim_io->token;
-
- ril_request_sim_io_complete(sim_io->token, sim_io->command, sim_io->fileid,
- sim_io->p1, sim_io->p2, sim_io->p3, sim_io->data, sim_io->length);
-
- if (sim_io->data != NULL)
- free(sim_io->data);
- sim_io->data = NULL;
- sim_io->length = 0;
-}
-
-void ril_request_sim_io_complete(RIL_Token t, unsigned char command, unsigned short fileid,
- unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length)
-{
- struct ipc_sec_rsim_access_get *rsim_access = NULL;
- void *rsim_access_data = NULL;
- int rsim_access_length = 0;
-
- rsim_access_length += sizeof(struct ipc_sec_rsim_access_get);
-
- if (data != NULL && length > 0)
- rsim_access_length += length;
-
- rsim_access_data = calloc(1, rsim_access_length);
- rsim_access = (struct ipc_sec_rsim_access_get *) rsim_access_data;
-
- rsim_access->command = command;
- rsim_access->fileid = fileid;
- rsim_access->p1 = p1;
- rsim_access->p2 = p2;
- rsim_access->p3 = p3;
-
- if (data != NULL && length > 0)
- memcpy((void *) ((int) rsim_access_data + sizeof(struct ipc_sec_rsim_access_get)), data, length);
-
- ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, rsim_access_data, rsim_access_length, ril_request_get_id(t));
-
- free(rsim_access_data);
-}
-
-void ril_request_sim_io(RIL_Token t, void *data, int length)
-{
- struct ril_request_sim_io_info *sim_io_info = NULL;
-#if RIL_VERSION >= 6
- RIL_SIM_IO_v6 *sim_io = NULL;
-#else
- RIL_SIM_IO *sim_io = NULL;
-#endif
- void *sim_io_data = NULL;
- int sim_io_data_length = 0;
- int rc;
-
- if (data == NULL || length < (int) sizeof(*sim_io))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_SIM_NOT_READY, t))
- return;
-
-#if RIL_VERSION >= 6
- sim_io = (RIL_SIM_IO_v6 *) data;
-#else
- sim_io = (RIL_SIM_IO *) data;
-#endif
-
- // SIM IO data should be a string if present
- if (sim_io->data != NULL) {
- sim_io_data_length = strlen(sim_io->data) / 2;
- if (sim_io_data_length > 0) {
- sim_io_data = calloc(1, sim_io_data_length);
- hex2bin(sim_io->data, sim_io_data_length * 2, sim_io_data);
- }
- }
-
- rc = ril_request_sim_io_register(t, sim_io->command, sim_io->fileid,
- sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length,
- &sim_io_info);
- if (rc < 0 || sim_io_info == NULL) {
- RIL_LOGE("Unable to add the request to the list");
-
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- if (sim_io_data != NULL)
- free(sim_io_data);
-
- // Send the next SIM I/O in the list
- ril_request_sim_io_next();
- }
-
- if (ril_data.tokens.sim_io != RIL_TOKEN_NULL) {
- RIL_LOGD("Another SIM I/O is being processed, adding to the list");
- return;
- }
-
- sim_io_info->waiting = 0;
- ril_data.tokens.sim_io = t;
-
- ril_request_sim_io_complete(t, sim_io->command, sim_io->fileid,
- sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length);
-
- if (sim_io_data != NULL)
- free(sim_io_data);
- sim_io_info->data = NULL;
- sim_io_info->length = 0;
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ipc_sec_rsim_access(struct ipc_message_info *info)
-{
- struct ril_request_sim_io_info *sim_io_info;
- struct sim_file_response sim_file_response;
- RIL_SIM_IO_Response sim_io_response;
- struct ipc_sec_rsim_access_response *rsim_access = NULL;
- struct ipc_sec_rsim_access_response_data *rsim_data = NULL;
- void *rsim_access_data = NULL;
- char *sim_response = NULL;
- unsigned char *buf = NULL;
- int offset;
- int i;
-
- if (info->data == NULL || info->length < sizeof(struct ipc_sec_rsim_access_response))
- goto error;
-
- sim_io_info = ril_request_sim_io_info_find_token(ril_request_get_token(info->aseq));
- if (sim_io_info == NULL) {
- RIL_LOGE("Unable to find SIM I/O in the list!");
-
- // Send the next SIM I/O in the list
- ril_request_sim_io_next();
-
- return;
- }
-
- rsim_access = (struct ipc_sec_rsim_access_response *) info->data;
- rsim_access_data = (void *) ((int) info->data + sizeof(struct ipc_sec_rsim_access_response));
-
- memset(&sim_io_response, 0, sizeof(sim_io_response));
- sim_io_response.sw1 = rsim_access->sw1;
- sim_io_response.sw2 = rsim_access->sw2;
-
- switch (sim_io_info->command) {
- case SIM_COMMAND_READ_BINARY:
- case SIM_COMMAND_READ_RECORD:
- if (rsim_access->len <= 0)
- break;
-
- // Copy the data as-is
- sim_response = (char *) malloc(rsim_access->len * 2 + 1);
- bin2hex(rsim_access_data, rsim_access->len, sim_response);
- sim_io_response.simResponse = sim_response;
- break;
- case SIM_COMMAND_GET_RESPONSE:
- if (rsim_access->len < sizeof(struct ipc_sec_rsim_access_response_data))
- break;
-
- // SIM ICC type 1 requires direct copy
- if (ril_data.state.sim_icc_type.type == 1) {
- sim_response = (char *) malloc(rsim_access->len * 2 + 1);
- bin2hex(rsim_access_data, rsim_access->len, sim_response);
- sim_io_response.simResponse = sim_response;
- break;
- }
-
- rsim_data = (struct ipc_sec_rsim_access_response_data *)
- rsim_access_data;
-
- memset(&sim_file_response, 0, sizeof(sim_file_response));
-
- buf = (unsigned char *) rsim_data;
- buf += sizeof(struct ipc_sec_rsim_access_response_data);
- buf += rsim_data->offset - 2;
- if (((int) buf + 1 - (int) rsim_access_data) > rsim_access->len)
- break;
-
- sim_file_response.file_id[0] = buf[0];
- sim_file_response.file_id[1] = buf[1];
-
- buf = (unsigned char *) rsim_data;
- buf += rsim_access->len - 2;
- while ((int) buf > (int) rsim_data + 2) {
- if (buf[0] == 0x88) {
- buf -= 2;
- break;
- }
- buf--;
- }
-
- if ((int) buf <= (int) rsim_data + 2)
- break;
-
- sim_file_response.file_size[0] = buf[0];
- sim_file_response.file_size[1] = buf[1];
-
- // Fallback to EF
- sim_file_response.file_type = SIM_FILE_TYPE_EF;
- for (i = 0 ; i < sim_file_ids_count ; i++) {
- if (sim_io_info->fileid == sim_file_ids[i].file_id) {
- sim_file_response.file_type = sim_file_ids[i].type;
- break;
- }
- }
-
- sim_file_response.access_condition[0] = 0x00;
- sim_file_response.access_condition[1] = 0xff;
- sim_file_response.access_condition[2] = 0xff;
-
- sim_file_response.file_status = 0x01;
- sim_file_response.file_length = 0x02;
-
- switch (rsim_data->file_structure) {
- case IPC_SEC_RSIM_FILE_STRUCTURE_TRANSPARENT:
- sim_file_response.file_structure = SIM_FILE_STRUCTURE_TRANSPARENT;
- break;
- case IPC_SEC_RSIM_FILE_STRUCTURE_LINEAR_FIXED:
- default:
- sim_file_response.file_structure = SIM_FILE_STRUCTURE_LINEAR_FIXED;
- break;
- }
-
- sim_file_response.record_length = rsim_data->record_length;
-
- sim_response = (char *) malloc(sizeof(struct sim_file_response) * 2 + 1);
- bin2hex((void *) &sim_file_response, sizeof(struct sim_file_response), sim_response);
- sim_io_response.simResponse = sim_response;
- break;
- case SIM_COMMAND_UPDATE_BINARY:
- case SIM_COMMAND_UPDATE_RECORD:
- case SIM_COMMAND_SEEK:
- default:
- sim_io_response.simResponse = NULL;
- break;
- }
-
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &sim_io_response, sizeof(sim_io_response));
-
- if (sim_io_response.simResponse != NULL) {
- RIL_LOGD("SIM response: %s", sim_io_response.simResponse);
- free(sim_io_response.simResponse);
- }
-
- ril_request_sim_io_unregister(sim_io_info);
-
- // Send the next SIM I/O in the list
- ril_request_sim_io_next();
-
- return;
-
-error:
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ipc_sec_sim_status_complete(struct ipc_message_info *info)
-{
- struct ipc_gen_phone_res *phone_res;
- int attempts = -1;
- int rc;
-
- phone_res = (struct ipc_gen_phone_res *) info->data;
-
- rc = ipc_gen_phone_res_check(phone_res);
- if (rc < 0) {
- if ((phone_res->code & 0x00ff) == 0x10) {
- RIL_LOGE("Wrong password!");
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
- } else if ((phone_res->code & 0x00ff) == 0x0c) {
- RIL_LOGE("Wrong password and no attempts left!");
-
- attempts = 0;
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
-
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
- } else {
- RIL_LOGE("There was an error during pin status complete!");
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
- }
- return;
- }
-
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &attempts, sizeof(attempts));
-}
-
-void ipc_sec_lock_info(struct ipc_message_info *info)
-{
- struct ipc_sec_lock_info_response *lock_info;
- int attempts;
-
- if (info->data == NULL || info->length < sizeof(struct ipc_sec_lock_info_response))
- return;
-
- lock_info = (struct ipc_sec_lock_info_response *) info->data;
-
- /*
- * FIXME: solid way of handling lockinfo and sim unlock response together
- * so we can return the number of attempts left in respondSecPinStatus
- */
-
- if (lock_info->type == IPC_SEC_PIN_TYPE_PIN1) {
- attempts = lock_info->attempts;
- RIL_LOGD("%s: PIN1 %d attempts left", __func__, attempts);
- } else {
- RIL_LOGE("%s: unhandled lock type %d", __func__, lock_info->type);
- }
-}
-
-void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t length)
-{
- struct ipc_sec_pin_status_set pin_status;
- char *pin = ((char **) data)[0];
- unsigned char buf[9];
-
- if (data == NULL || length < (int) sizeof(char *))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_OFF, t))
- return;
-
- // 1. Send PIN
- if (strlen(data) > 16) {
- RIL_LOGE("%s: pin exceeds maximum length", __func__);
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- }
-
- ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, NULL);
-
- ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_SIM_STATUS, ipc_sec_sim_status_complete);
-
- ipc_fmt_send_set(IPC_SEC_SIM_STATUS, ril_request_get_id(t), (unsigned char *) &pin_status, sizeof(pin_status));
-
- // 2. Get lock status
- // FIXME: This is not clean at all
- memset(buf, 0, sizeof(buf));
- buf[0] = 1;
- buf[1] = IPC_SEC_PIN_TYPE_PIN1;
-
- ipc_fmt_send(IPC_SEC_LOCK_INFO, IPC_TYPE_GET, buf, sizeof(buf), ril_request_get_id(t));
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ril_request_change_sim_pin(RIL_Token t, void *data, size_t length)
-{
- char *password_old;
- char *password_new;
- struct ipc_sec_change_locking_pw_set locking_pw;
-
- if (data == NULL || length < (int) (2 * sizeof(char *)))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_SIM_NOT_READY, t))
- return;
-
- password_old = ((char **) data)[0];
- password_new = ((char **) data)[1];
-
- memset(&locking_pw, 0, sizeof(locking_pw));
-
- locking_pw.facility = IPC_SEC_SIM_STATUS_LOCK_SC;
-
- locking_pw.length_new = strlen(password_new) > sizeof(locking_pw.password_new)
- ? sizeof(locking_pw.password_new)
- : strlen(password_new);
-
- memcpy(locking_pw.password_new, password_new, locking_pw.length_new);
-
- locking_pw.length_old = strlen(password_old) > sizeof(locking_pw.password_old)
- ? sizeof(locking_pw.password_old)
- : strlen(password_old);
-
- memcpy(locking_pw.password_old, password_old, locking_pw.length_old);
-
- ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_CHANGE_LOCKING_PW,
- ipc_sec_sim_status_complete);
-
- ipc_fmt_send_set(IPC_SEC_CHANGE_LOCKING_PW, ril_request_get_id(t), (unsigned char *) &locking_pw, sizeof(locking_pw));
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ril_request_enter_sim_puk(RIL_Token t, void *data, size_t length)
-{
- struct ipc_sec_pin_status_set pin_status;
- char *puk;
- char *pin;
-
- if (data == NULL || length < (int) (2 * sizeof(char *)))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_OFF, t))
- return;
-
- puk = ((char **) data)[0];
- pin = ((char **) data)[1];
-
- ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, puk);
-
- ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_SIM_STATUS,
- ipc_sec_sim_status_complete);
-
- ipc_fmt_send_set(IPC_SEC_SIM_STATUS, ril_request_get_id(t), (unsigned char *) &pin_status, sizeof(pin_status));
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ipc_sec_phone_lock(struct ipc_message_info *info)
-{
- int status;
- struct ipc_sec_phone_lock_response *lock;
-
- if (info->data == NULL || info->length < sizeof(struct ipc_sec_phone_lock_response))
- goto error;
-
- lock = (struct ipc_sec_phone_lock_response *) info->data;
- status = lock->status;
-
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &status, sizeof(status));
-
- return;
-
-error:
- ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-void ril_request_query_facility_lock(RIL_Token t, void *data, size_t length)
-{
- struct ipc_sec_phone_lock_get lock_request;
- char *facility;
-
- if (data == NULL || length < sizeof(char *))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_SIM_NOT_READY, t))
- return;
-
- facility = ((char **) data)[0];
-
- if (!strcmp(facility, "SC")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_SC;
- } else if (!strcmp(facility, "FD")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_FD;
- } else if (!strcmp(facility, "PN")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_PN;
- } else if (!strcmp(facility, "PU")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_PU;
- } else if (!strcmp(facility, "PP")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_PP;
- } else if (!strcmp(facility, "PC")) {
- lock_request.facility = IPC_SEC_FACILITY_TYPE_PC;
- } else {
- RIL_LOGE("%s: unsupported facility: %s", __func__, facility);
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- }
-
- ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, (void *) &lock_request, sizeof(lock_request), ril_request_get_id(t));
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}
-
-// Both functions were the same
-#define ipc_sec_phone_lock_complete \
- ipc_sec_sim_status_complete
-
-void ril_request_set_facility_lock(RIL_Token t, void *data, size_t length)
-{
- struct ipc_sec_phone_lock_set lock_request;
- char *facility;
- char *lock;
- char *password;
- char *class;
-
- if (data == NULL || length < (int) (4 * sizeof(char *)))
- goto error;
-
- if (ril_radio_state_complete(RADIO_STATE_SIM_NOT_READY, t))
- return;
-
- facility = ((char **) data)[0];
- lock = ((char **) data)[1];
- password = ((char **) data)[2];
- class = ((char **) data)[3];
-
- memset(&lock_request, 0, sizeof(lock_request));
-
- if (!strcmp(facility, "SC")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_SC;
- } else if (!strcmp(facility, "FD")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_FD;
- } else if (!strcmp(facility, "PN")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PN;
- } else if (!strcmp(facility, "PU")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PU;
- } else if (!strcmp(facility, "PP")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PP;
- } else if (!strcmp(facility, "PC")) {
- lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PC;
- } else {
- RIL_LOGE("%s: unsupported facility: %s", __func__, facility);
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- }
-
- lock_request.lock = lock[0] == '1' ? 1 : 0;
- lock_request.length = strlen(password) > sizeof(lock_request.password)
- ? sizeof(lock_request.password)
- : strlen(password);
-
- memcpy(lock_request.password, password, lock_request.length);
-
- ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_PHONE_LOCK,
- ipc_sec_phone_lock_complete);
-
- ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, (void *) &lock_request, sizeof(lock_request), ril_request_get_id(t));
-
- return;
-
-error:
- ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
-}