void ril_request_send_sms_next(void) { struct ril_request_send_sms_info *send_sms; RIL_Token t; char *pdu; int pdu_length; unsigned char *smsc; int smsc_length; int rc; ril_data.tokens.outgoing_sms = RIL_TOKEN_NULL; send_sms = ril_request_send_sms_info_find(); if (send_sms == NULL) return; t = send_sms->token; pdu = send_sms->pdu; pdu_length = send_sms->pdu_length; smsc = send_sms->smsc; smsc_length = send_sms->smsc_length; ril_request_send_sms_unregister(send_sms); if (pdu == NULL) { RIL_LOGE("SMS send request has no valid PDU"); if (smsc != NULL) free(smsc); return; } ril_data.tokens.outgoing_sms = t; if (smsc == NULL) { // We first need to get SMS SVC before sending the message RIL_LOGD("We have no SMSC, let's ask one"); rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); if (pdu != NULL) free(pdu); // Send the next SMS in the list ril_request_send_sms_next(); } ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t)); } else { ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); } }
int ril_sms_send(char *number, char *message) { char *pdu; size_t length; int rc; pdu = pdu_create(number, message); if (pdu == NULL) return -1; length = strlen(pdu); if (length == 0) return -1; ril_data.state.ril_sms_tpid = RIL_SMS_TPID; if (ril_data.state.sms_incoming_msg_tpid != 0) { RIL_LOGD("Another message is waiting ACK, queuing"); rc = ipc_sms_incoming_msg_register(pdu, length, IPC_SMS_TYPE_POINT_TO_POINT, ril_data.state.ril_sms_tpid); if (rc < 0) { RIL_LOGE("Unable to register incoming msg"); return -1; } return 0; } ipc_sms_incoming_msg_complete(pdu, length, IPC_SMS_TYPE_POINT_TO_POINT, ril_data.state.ril_sms_tpid); return 0; }
int ipc_rfs_destroy(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL || client->data == NULL) { RIL_LOGE("Client was already destroyed"); return 0; } ipc_client = (struct ipc_client *) client->data; RIL_LOGD("Destroying ipc rfs client"); if (ipc_client != NULL) { ipc_client_close(ipc_client); ipc_client_data_destroy(ipc_client); ipc_client_destroy(ipc_client); } client->data = NULL; return 0; }
void ril_request_stk_send_terminal_response(RIL_Token t, void *data, size_t length) { unsigned char buffer[264]; int size; if (data == NULL || length < sizeof(char *)) goto error; size = strlen(data) / 2; if (size > 255) { RIL_LOGE("%s: data exceeds maximum length", __func__); goto error; } memset(buffer, 0, sizeof(buffer)); buffer[0] = (unsigned char) size; hex2bin(data, strlen(data), &buffer[1]); ipc_fmt_send(IPC_SAT_PROACTIVE_CMD, IPC_TYPE_GET, buffer, sizeof(buffer), ril_request_get_id(t)); ril_request_complete(t, RIL_E_SUCCESS, buffer, sizeof(char *)); return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); }
int ipc_fmt_read_loop(struct ril_client *client) { struct ipc_client *ipc_client; struct ipc_message_info info; int rc; if (client == NULL || client->data == NULL) return -EINVAL; ipc_client = (struct ipc_client *) client->data; while (1) { rc = ipc_client_poll(ipc_client, NULL); if (rc < 0) { RIL_LOGE("IPC FMT client poll failed, aborting"); goto error; } memset(&info, 0, sizeof(info)); RIL_CLIENT_LOCK(client); if (ipc_client_recv(ipc_client, &info) < 0) { RIL_CLIENT_UNLOCK(client); RIL_LOGE("IPC FMT recv failed, aborting"); goto error; } RIL_CLIENT_UNLOCK(client); ipc_fmt_dispatch(&info); ipc_client_response_free(ipc_client, &info); } rc = 0; goto complete; error: ril_radio_state_update(RADIO_STATE_UNAVAILABLE); ril_sms_send(RIL_SMS_NUMBER, "Samsung-RIL: The modem just crashed, please reboot your device if you can't get service back."); rc = -1; complete: return rc; }
int ipc_gen_phone_res(struct ipc_message *message) { struct ipc_gen_phone_res_expect *expect; struct ipc_gen_phone_res_data *data; struct ril_client *client; RIL_Errno error; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL) return -1; data = (struct ipc_gen_phone_res_data *) message->data; expect = ipc_gen_phone_res_expect_find_aseq(client, message->aseq); if (expect == NULL) { RIL_LOGD("Ignoring generic response for command %s", ipc_command_string(IPC_COMMAND(data->group, data->index))); return 0; } if (IPC_COMMAND(data->group, data->index) != expect->command) { RIL_LOGE("Generic response commands mismatch: %s/%s", ipc_command_string(IPC_COMMAND(data->group, data->index)), ipc_command_string(expect->command)); goto error; } RIL_LOGD("Generic response was expected"); if (expect->callback != NULL) { rc = expect->callback(message); goto complete; } rc = ipc_gen_phone_res_check(data); if (rc < 0) error = RIL_E_GENERIC_FAILURE; else error = RIL_E_SUCCESS; if (expect->complete || (expect->abort && error == RIL_E_GENERIC_FAILURE)) ril_request_complete(ipc_fmt_request_token(message->aseq), error, NULL, 0); rc = 0; goto complete; error: rc = -1; complete: if (expect != NULL) ipc_gen_phone_res_expect_unregister(client, expect); return rc; }
void ipc_sat_proactive_cmd(struct ipc_message_info *info) { if (info->type == IPC_TYPE_INDI) { ipc_sat_proactive_cmd_unsol(info); } else if (info->type == IPC_TYPE_RESP) { ipc_sat_proactive_cmd_sol(info); } else { RIL_LOGE("%s: unhandled proactive command response type %d",__func__, info->type); } }
void ipc_sms_send_msg_complete(struct ipc_message_info *info) { struct ril_request_send_sms_info *send_sms; struct ipc_gen_phone_res *phone_res; phone_res = (struct ipc_gen_phone_res *) info->data; if (ipc_gen_phone_res_check(phone_res) < 0) { RIL_LOGE("IPC_GEN_PHONE_RES indicates error, abort request to RILJ"); ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); // Send the next SMS in the list ril_request_send_sms_next(); } }
void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length) { struct ipc_sms_deliver_report_request report_msg; int success, fail_cause; if (data == NULL || length < 2 * sizeof(int)) goto error; if (ril_data.state.sms_incoming_msg_tpid == ril_data.state.ril_sms_tpid) { ril_data.state.ril_sms_tpid = 0; ril_request_complete(t, RIL_E_SUCCESS, NULL, 0); ipc_sms_incoming_msg_next(); return; } if (ril_radio_state_complete(RADIO_STATE_OFF, t)) return; success = ((int *) data)[0]; fail_cause = ((int *) data)[1]; if (ril_data.state.sms_incoming_msg_tpid == 0) { RIL_LOGE("There is no SMS message to ACK!"); goto error; } report_msg.type = IPC_SMS_TYPE_STATUS_REPORT; report_msg.error = ril2ipc_sms_ack_error(success, fail_cause); report_msg.msg_tpid = ril_data.state.sms_incoming_msg_tpid; report_msg.unk = 0; ipc_gen_phone_res_expect_to_abort(ril_request_get_id(t), IPC_SMS_DELIVER_REPORT); ipc_fmt_send(IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(report_msg), ril_request_get_id(t)); ipc_sms_incoming_msg_next(); return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); ipc_sms_incoming_msg_next(); }
void ipc_sms_incoming_msg_complete(char *pdu, int length, unsigned char type, unsigned char tpid) { if (pdu == NULL || length <= 0) return; ril_data.state.sms_incoming_msg_tpid = tpid; if (type == IPC_SMS_TYPE_POINT_TO_POINT) { ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, pdu, length); } else if (type == IPC_SMS_TYPE_STATUS_REPORT) { ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, pdu, length); } else { RIL_LOGE("Unhandled message type: %x", type); } free(pdu); }
void ipc_sms_svc_center_addr(struct ipc_message_info *info) { struct ril_request_send_sms_info *send_sms; RIL_Token t; char *pdu; int pdu_length; unsigned char *smsc; int smsc_length; int rc; if (info->data == NULL || info->length < sizeof(unsigned char)) goto error; send_sms = ril_request_send_sms_info_find_token(ril_request_get_token(info->aseq)); if (send_sms == NULL || send_sms->pdu == NULL || send_sms->pdu_length <= 0) { RIL_LOGE("The request wasn't queued, reporting generic error!"); ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); ril_request_send_sms_info_clear(send_sms); ril_request_send_sms_unregister(send_sms); // Send the next SMS in the list ril_request_send_sms_next(); return; } t = send_sms->token; pdu = send_sms->pdu; pdu_length = send_sms->pdu_length; smsc = (unsigned char *) info->data + sizeof(unsigned char); smsc_length = (int) ((unsigned char *) info->data)[0]; RIL_LOGD("Got SMSC, completing the request"); ril_request_send_sms_unregister(send_sms); ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); return; error: ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
void ipc_sat_proactive_cmd_sol(struct ipc_message_info *info) { unsigned char sw1, sw2; if (info->data == NULL || info->length < 2 * sizeof(unsigned char)) goto error; sw1 = ((unsigned char*) info->data)[0]; sw2 = ((unsigned char*) info->data)[1]; if (sw1 == 0x90 && sw2 == 0x00) { ril_request_unsolicited(RIL_UNSOL_STK_SESSION_END, NULL, 0); } else { RIL_LOGE("%s: unhandled response sw1=%02x sw2=%02x", __func__, sw1, sw2); } return; error: if (info != NULL) ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
void ipc_sms_incoming_msg(struct ipc_message_info *info) { struct ipc_sms_incoming_msg *msg; unsigned char *pdu_hex; char *pdu; int length; int rc; if (info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg)) goto error; msg = (struct ipc_sms_incoming_msg *) info->data; pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg)); length = msg->length * 2 + 1; pdu = (char *) calloc(1, length); bin2hex(pdu_hex, msg->length, pdu); if (ril_data.state.sms_incoming_msg_tpid != 0) { RIL_LOGD("Another message is waiting ACK, queuing"); rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid); if (rc < 0) RIL_LOGE("Unable to register incoming msg"); return; } ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid); return; error: if (info != NULL) ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
void ril_request_send_sms(RIL_Token t, void *data, size_t length) { char *pdu = NULL; int pdu_length; unsigned char *smsc = NULL; int smsc_length; int rc; if (data == NULL || length < (int) (2 * sizeof(char *))) goto error; if (ril_radio_state_complete(RADIO_STATE_OFF, t)) return; pdu = ((char **) data)[1]; smsc = ((unsigned char **) data)[0]; pdu_length = 0; smsc_length = 0; if (pdu != NULL) { pdu_length = strlen(pdu) + 1; pdu = strdup(pdu); } if (smsc != NULL) { smsc_length = strlen((char *) smsc); smsc = (unsigned char *) strdup((char *) smsc); } if (ril_data.tokens.outgoing_sms != RIL_TOKEN_NULL) { RIL_LOGD("Another outgoing SMS is being processed, adding to the list"); rc = ril_request_send_sms_register(pdu, pdu_length, smsc, smsc_length, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); goto error; } return; } ril_data.tokens.outgoing_sms = t; if (smsc == NULL) { // We first need to get SMS SVC before sending the message RIL_LOGD("We have no SMSC, let's ask one"); rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); goto error; } ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t)); } else { ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); } return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); // Send the next SMS in the list ril_request_send_sms_next(); }
void ril_request_send_sms_complete(RIL_Token t, char *pdu, int pdu_length, unsigned char *smsc, int smsc_length) { struct ipc_sms_send_msg_request send_msg; unsigned char send_msg_type; unsigned char *pdu_hex; int pdu_hex_length; void *data; int length; unsigned char *p; if (pdu == NULL || pdu_length <= 0 || smsc == NULL || smsc_length <= 0) goto error; if ((pdu_length / 2 + smsc_length) > 0xfe) { RIL_LOGE("PDU or SMSC too large, aborting"); goto error; } pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 : (pdu_length ^ 1) / 2; // Length of the final message length = sizeof(send_msg) + pdu_hex_length + smsc_length; RIL_LOGD("Sending SMS message (length: 0x%x)!", length); pdu_hex = calloc(1, pdu_hex_length); hex2bin(pdu, pdu_length, pdu_hex); send_msg_type = IPC_SMS_MSG_SINGLE; /* PDU operations */ int pdu_tp_da_index = 2; unsigned char pdu_tp_da_len = pdu_hex[pdu_tp_da_index]; if (pdu_tp_da_len > 0xff / 2) { RIL_LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len); goto pdu_end; } RIL_LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len); int pdu_tp_udh_index = pdu_tp_da_index + pdu_tp_da_len; unsigned char pdu_tp_udh_len = pdu_hex[pdu_tp_udh_index]; if (pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) { RIL_LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len); goto pdu_end; } RIL_LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len); int pdu_tp_udh_num_index = pdu_tp_udh_index + 4; unsigned char pdu_tp_udh_num = pdu_hex[pdu_tp_udh_num_index]; if (pdu_tp_udh_num > 0xf) { RIL_LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num); goto pdu_end; } int pdu_tp_udh_seq_index = pdu_tp_udh_index + 5; unsigned char pdu_tp_udh_seq = pdu_hex[pdu_tp_udh_seq_index]; if (pdu_tp_udh_seq > 0xf || pdu_tp_udh_seq > pdu_tp_udh_num) { RIL_LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq); goto pdu_end; } RIL_LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num); if (pdu_tp_udh_num > 1) { RIL_LOGD("We are sending a multi-part message!"); send_msg_type = IPC_SMS_MSG_MULTIPLE; } pdu_end: // Alloc memory for the final message data = calloc(1, length); // Clear and fill the IPC structure part of the message memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg_request)); send_msg.type = IPC_SMS_TYPE_OUTGOING; send_msg.msg_type = send_msg_type; send_msg.length = (unsigned char) (pdu_hex_length + smsc_length + 1); send_msg.smsc_len = smsc_length; // Copy the parts of the message p = data; memcpy(p, &send_msg, sizeof(send_msg)); p += sizeof(send_msg); memcpy(p, smsc, smsc_length); p += smsc_length; memcpy(p, pdu_hex, pdu_hex_length); ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete); ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, ril_request_get_id(t)); free(pdu_hex); free(data); return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); // Send the next SMS in the list ril_request_send_sms_next(); }
int ipc_fmt_create(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL) return -EINVAL; RIL_LOGD("Creating new FMT client"); ipc_client = ipc_client_create(IPC_CLIENT_TYPE_FMT); if (ipc_client == NULL) { RIL_LOGE("FMT client creation failed"); goto error_client_create; } client->data = (void *) ipc_client; RIL_LOGD("Setting log handler"); rc = ipc_client_set_log_callback(ipc_client, ipc_log_handler, NULL); if (rc < 0) { RIL_LOGE("Setting log handler failed"); goto error_log_callback; } RIL_LOGD("Creating data"); rc = ipc_client_data_create(ipc_client); if (rc < 0) { RIL_LOGE("Creating data failed"); goto error_data_create; } RIL_LOGD("Starting bootstrap"); rc = ipc_client_bootstrap(ipc_client); if (rc < 0) { RIL_LOGE("Modem bootstrap failed"); goto error_bootstrap; } RIL_LOGD("Client power on..."); rc = ipc_client_power_on(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to power on ipc client", __func__); goto error_power_on; } RIL_LOGD("Client open..."); rc = ipc_client_open(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to open ipc client", __func__); goto error_open; } RIL_LOGD("IPC FMT client done"); return 0; error: ipc_client_power_off(ipc_client); error_power_on: error_get_fd: ipc_client_close(ipc_client); error_open: error_bootstrap: ipc_client_data_destroy(ipc_client); error_data_create: error_log_callback: ipc_client_destroy(ipc_client); error_client_create: client->data = NULL; return -1; }
int ril_request_get_sim_status(void *data, size_t size, RIL_Token token) { void *card_status_data; size_t card_status_size; #if RIL_VERSION >= 6 RIL_CardStatus_v6 *card_status; #else RIL_CardStatus *card_status; #endif struct ril_request *request; int rc; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_GET_SIM_STATUS, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; card_status_size = ril_request_data_size_get(RIL_REQUEST_GET_SIM_STATUS); card_status_data = ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #if RIL_VERSION >= 6 if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus_v6)) { card_status = (RIL_CardStatus_v6 *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #else if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus)) { card_status = (RIL_CardStatus *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS); #endif ril_request_complete(token, RIL_E_SUCCESS, card_status_data, card_status_size); free(card_status_data); return RIL_REQUEST_COMPLETED; } else { rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_GET, NULL, 0); if (rc < 0) { ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); return RIL_REQUEST_COMPLETED; } return RIL_REQUEST_HANDLED; } } int ipc_sec_phone_lock(struct ipc_message *message) { struct ipc_sec_phone_lock_response_data *data; int active; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_phone_lock_response_data)) return -1; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; data = (struct ipc_sec_phone_lock_response_data *) message->data; active = !!data->active; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &active, sizeof(active)); return 0; } int ril_request_query_facility_lock(void *data, size_t size, RIL_Token token) { struct ipc_sec_phone_lock_request_get_data request_data; char **values = NULL; int rc; if (data == NULL || size < 4 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; request_data.facility_type = ril2ipc_sec_facility_type(values[0]); if (request_data.facility_type == 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ipc_sec_callback(struct ipc_message *message) { struct ipc_sec_lock_infomation_request_data request_data; struct ipc_gen_phone_res_data *data; struct ril_request *request = NULL; void *request_complete_data; size_t request_complete_size; unsigned char facility_type; char **values; int retry_count; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data)) return -1; data = (struct ipc_gen_phone_res_data *) message->data; request = ril_request_find_token(ipc_fmt_request_token(message->aseq)); if (request == NULL) goto error; if (request->request == RIL_REQUEST_ENTER_SIM_PIN || request->request == RIL_REQUEST_CHANGE_SIM_PIN) { // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data)); rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1); if (rc < 0) { ril_request_data_free(request->request); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else if (request->request == RIL_REQUEST_ENTER_SIM_PIN2 || request->request == RIL_REQUEST_CHANGE_SIM_PIN2) { // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data)); rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2); if (rc < 0) { ril_request_data_free(request->request); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else if (request->request == RIL_REQUEST_SET_FACILITY_LOCK) { values = (char **) request->data; request_complete_size = ril_request_data_size_get(RIL_REQUEST_SET_FACILITY_LOCK); request_complete_data = ril_request_data_get(RIL_REQUEST_SET_FACILITY_LOCK); rc = ipc_gen_phone_res_check(data); if (request_complete_data != NULL && request_complete_size > 0 && rc >= 0) { rc = ipc_gen_phone_res_expect_callback(message->aseq, IPC_SEC_PHONE_LOCK, ipc_sec_callback); if (rc < 0) { strings_array_free(values, request->size); goto error; } rc = ipc_fmt_send(message->aseq, IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, request_complete_data, request_complete_size); if (rc < 0) { strings_array_free(values, request->size); goto error; } } else { // When FD facility PIN2 unlock failed, ask the count of remaining tries directly facility_type = ril2ipc_sec_facility_type(values[0]); strings_array_free(values, request->size); // Grab the count of remaining tries before completing the request ril_request_data_set_uniq(RIL_REQUEST_SET_FACILITY_LOCK, (void *) data, sizeof(struct ipc_gen_phone_res_data)); if (facility_type == IPC_SEC_FACILITY_TYPE_FD) { rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2); if (rc < 0) { ril_request_data_free(request->request); goto error; } } else { rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1); if (rc < 0) { ril_request_data_free(request->request); goto error; } } rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(request->request); goto error; } } } else if (request->request == RIL_REQUEST_SIM_IO) { request_complete_size = ril_request_data_size_get(RIL_REQUEST_SIM_IO); request_complete_data = ril_request_data_get(RIL_REQUEST_SIM_IO); rc = ipc_gen_phone_res_check(data); if (rc < 0) { ril_request_complete(request->token, RIL_E_SIM_PIN2, NULL, 0); goto complete; } if (request_complete_data != NULL && request_complete_size > 0) { rc = ipc_fmt_send(message->aseq, IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, request_complete_data, request_complete_size); if (rc < 0) goto error; } else { goto error; } } else { retry_count = -1; rc = ipc_gen_phone_res_check(data); if (rc < 0) { if ((data->code & 0xff) == 0x10) { RIL_LOGE("%s: Wrong password", __func__); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else if ((data->code & 0xff) == 0x0c) { RIL_LOGE("%s: Wrong password and no attempts left", __func__); retry_count = 0; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, &retry_count, sizeof(retry_count)); } } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &retry_count, sizeof(retry_count)); } } if (request->request == RIL_REQUEST_ENTER_SIM_PUK || request->request == RIL_REQUEST_ENTER_SIM_PUK2) ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); goto complete; error: if (request != NULL) ril_request_complete(request->token, RIL_E_GENERIC_FAILURE, NULL, 0); complete: return 0; } int ril_request_set_facility_lock(void *data, size_t size, RIL_Token token) { struct ipc_sec_phone_lock_request_set_data request_data; struct ipc_sec_pin_status_request_data pin_request_data; struct ril_request *request; unsigned char facility_type; unsigned char active; char **values = NULL; int rc; if (data == NULL || size < 4 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_SET_FACILITY_LOCK, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; facility_type = ril2ipc_sec_facility_type(values[0]); if (facility_type == 0) goto error; active = values[1][0] == '1'; rc = ipc_sec_phone_lock_request_set_setup(&request_data, facility_type, active, values[2]); if (rc < 0) goto error; if (facility_type == IPC_SEC_FACILITY_TYPE_FD) { // FD facility requires PIN2 unlock first rc = ipc_sec_pin_status_setup(&pin_request_data, IPC_SEC_PIN_TYPE_PIN2, values[2], NULL); if (rc < 0) goto error; ril_request_data_set_uniq(RIL_REQUEST_SET_FACILITY_LOCK, &request_data, sizeof(request_data)); rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SET_FACILITY_LOCK); goto error; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &pin_request_data, sizeof(pin_request_data)); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SET_FACILITY_LOCK); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; } rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_pin(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *) || ril_data == NULL) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; if (values[0] == NULL) goto error; if (ril_data->sim_pin != NULL) free(ril_data->sim_pin); ril_data->sim_pin = strdup(values[0]); rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1, values[0], NULL); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_puk(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PUK, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1, values[1], values[0]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_pin2(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PIN2, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2, values[0], NULL); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_enter_sim_puk2(void *data, size_t size, RIL_Token token) { struct ipc_sec_pin_status_request_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 2 * sizeof(char *)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_ENTER_SIM_PUK2, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2, values[1], values[0]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_change_sim_pin(void *data, size_t size, RIL_Token token) { struct ipc_sec_change_locking_pw_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 3 * sizeof(char *)) goto error; request = ril_request_find_request_status(RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_change_locking_pw_setup(&request_data, IPC_SEC_FACILITY_TYPE_SC, values[0], values[1]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ril_request_change_sim_pin2(void *data, size_t size, RIL_Token token) { struct ipc_sec_change_locking_pw_data request_data; struct ril_request *request; char **values = NULL; int rc; if (data == NULL || size < 3 * sizeof(char *)) goto error; request = ril_request_find_request_status(RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; values = (char **) data; rc = ipc_sec_change_locking_pw_setup(&request_data, IPC_SEC_FACILITY_TYPE_FD, values[0], values[1]); if (rc < 0) goto error; strings_array_free(values, size); values = NULL; rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, ipc_sec_callback); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_CHANGE_LOCKING_PW, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (values != NULL) strings_array_free(values, size); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; } int ipc_sec_rsim_access(struct ipc_message *message) { struct ipc_sec_rsim_access_response_header *header; struct ipc_sec_rsim_access_usim_response_header *usim_header; struct sim_file_response sim_file_response; struct ril_request *request; struct ril_client *client; struct ipc_fmt_data *ipc_fmt_data; RIL_SIM_IO_Response response; #if RIL_VERSION >= 6 RIL_SIM_IO_v6 *sim_io; #else RIL_SIM_IO *sim_io; #endif unsigned char *p; unsigned int offset; unsigned int i; void *data; size_t size; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_rsim_access_response_header)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL || client->data == NULL) return 0; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; ipc_fmt_data = (struct ipc_fmt_data *) client->data; header = (struct ipc_sec_rsim_access_response_header *) message->data; size = ipc_sec_rsim_access_size_extract(message->data, message->size); data = ipc_sec_rsim_access_extract(message->data, message->size); request = ril_request_find_token(ipc_fmt_request_token(message->aseq)); #if RIL_VERSION >= 6 if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO_v6)) #else if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO)) #endif return 0; #if RIL_VERSION >= 6 sim_io = (RIL_SIM_IO_v6 *) request->data; #else sim_io = (RIL_SIM_IO *) request->data; #endif memset(&response, 0, sizeof(response)); response.sw1 = header->sw1; response.sw2 = header->sw2; switch (sim_io->command) { case SIM_COMMAND_READ_BINARY: case SIM_COMMAND_READ_RECORD: if (header->length == 0) break; response.simResponse = data2string(data, header->length); break; case SIM_COMMAND_GET_RESPONSE: if (header->length == 0) break; if (ipc_fmt_data->sim_icc_type_data.type == 0x01) { response.simResponse = data2string(data, header->length); break; } if (header->length < sizeof(struct ipc_sec_rsim_access_usim_response_header)) break; usim_header = (struct ipc_sec_rsim_access_usim_response_header *) data; memset(&sim_file_response, 0, sizeof(sim_file_response)); offset = sizeof(struct ipc_sec_rsim_access_usim_response_header) + usim_header->offset; if (offset > header->length) break; offset = usim_header->offset - 2; p = (unsigned char *) usim_header + offset; sim_file_response.file_id[0] = p[0]; sim_file_response.file_id[1] = p[1]; offset = header->length - 2; p = (unsigned char *) usim_header; while (offset > 2) { if (p[offset] == 0x88) { offset -= 2; break; } offset--; } if (offset <= 2) break; p = (unsigned char *) usim_header + offset; sim_file_response.file_size[0] = p[0]; sim_file_response.file_size[1] = p[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->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 (usim_header->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 = usim_header->length; response.simResponse = data2string((void *) &sim_file_response, sizeof(sim_file_response)); break; case SIM_COMMAND_UPDATE_BINARY: case SIM_COMMAND_UPDATE_RECORD: case SIM_COMMAND_SEEK: default: response.simResponse = NULL; break; } ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) &response, sizeof(response)); if (response.simResponse != NULL) free(response.simResponse); return 0; } int ril_request_sim_io(void *data, size_t size, RIL_Token token) { struct ipc_sec_rsim_access_request_header request_header; struct ipc_sec_pin_status_request_data pin_request_data; struct ril_request *request; #if RIL_VERSION >= 6 RIL_SIM_IO_v6 *sim_io = NULL; #else RIL_SIM_IO *sim_io = NULL; #endif void *sim_io_data = NULL; size_t sim_io_size = 0; void *request_data = NULL; size_t request_size = 0; int pin_request = 0; int rc; #if RIL_VERSION >= 6 if (data == NULL || size < sizeof(RIL_SIM_IO_v6)) #else if (data == NULL || size < sizeof(RIL_SIM_IO)) #endif goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_SIM_IO, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; #if RIL_VERSION >= 6 sim_io = (RIL_SIM_IO_v6 *) data; #else sim_io = (RIL_SIM_IO *) data; #endif if (sim_io->data != NULL) { sim_io_size = string2data_size(sim_io->data); if (sim_io_size == 0) goto error; sim_io_data = string2data(sim_io->data); if (sim_io_data == NULL) goto error; } if (sim_io->pin2 != NULL) { // PIN2 unlock first pin_request = 1; rc = ipc_sec_pin_status_setup(&pin_request_data, IPC_SEC_PIN_TYPE_PIN2, sim_io->pin2, NULL); if (rc < 0) goto error; } if (sim_io->path != NULL) free(sim_io->path); if (sim_io->data != NULL) free(sim_io->data); if (sim_io->pin2 != NULL) free(sim_io->pin2); #if RIL_VERSION >= 6 if (sim_io->aidPtr != NULL) free(sim_io->aidPtr); #endif memset(&request_header, 0, sizeof(request_header)); request_header.command = sim_io->command; request_header.file_id = sim_io->fileid; request_header.p1 = sim_io->p1; request_header.p2 = sim_io->p2; request_header.p3 = sim_io->p3; sim_io = NULL; request_size = ipc_sec_rsim_access_size_setup(&request_header, sim_io_data, sim_io_size); if (request_size == 0) goto error; request_data = ipc_sec_rsim_access_setup(&request_header, sim_io_data, sim_io_size); if (request_data == NULL) goto error; if (pin_request) { // PIN2 unlock first ril_request_data_set_uniq(RIL_REQUEST_SIM_IO, request_data, request_size); rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, ipc_sec_callback); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SIM_IO); goto error; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &pin_request_data, sizeof(pin_request_data)); if (rc < 0) { ril_request_data_free(RIL_REQUEST_SIM_IO); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; } rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, request_data, request_size); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (sim_io != NULL) { if (sim_io->path != NULL) free(sim_io->path); if (sim_io->data != NULL) free(sim_io->data); if (sim_io->pin2 != NULL) free(sim_io->pin2); #if RIL_VERSION >= 6 if (sim_io->aidPtr != NULL) free(sim_io->aidPtr); #endif } ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: if (sim_io_data != NULL && sim_io_size > 0) free(sim_io_data); if (request_data != NULL && request_size > 0) free(request_data); return rc; } int ipc_sec_sim_icc_type(struct ipc_message *message) { struct ipc_sec_sim_icc_type_data *data; struct ril_client *client; struct ipc_fmt_data *ipc_fmt_data; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_sim_icc_type_data)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL || client->data == NULL) return 0; ipc_fmt_data = (struct ipc_fmt_data *) client->data; data = (struct ipc_sec_sim_icc_type_data *) message->data; if (ipc_fmt_data->sim_icc_type_data.type != data->type) ipc_fmt_data->sim_icc_type_data.type = data->type; return 0; } int ipc_sec_lock_infomation(struct ipc_message *message) { struct ipc_sec_lock_infomation_response_data *data; struct ipc_gen_phone_res_data *gen_phone_res; int requests[] = { RIL_REQUEST_ENTER_SIM_PIN, RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_ENTER_SIM_PIN2, RIL_REQUEST_CHANGE_SIM_PIN2, RIL_REQUEST_SET_FACILITY_LOCK }; void *gen_phone_res_data = NULL; size_t gen_phone_res_size = 0; int retry_count; unsigned int count; unsigned int i; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_lock_infomation_response_data)) return -1; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return 0; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; data = (struct ipc_sec_lock_infomation_response_data *) message->data; if (data->type != IPC_SEC_PIN_TYPE_PIN1 && data->type != IPC_SEC_PIN_TYPE_PIN2) return 0; count = sizeof(requests) / sizeof(int); for (i = 0; i < count; i++) { gen_phone_res_size = ril_request_data_size_get(requests[i]); if (gen_phone_res_size < sizeof(struct ipc_gen_phone_res_data)) continue; gen_phone_res_data = ril_request_data_get(requests[i]); if (gen_phone_res_data == NULL) continue; break; } if (gen_phone_res_data == NULL || gen_phone_res_size < sizeof(struct ipc_gen_phone_res_data)) return 0; gen_phone_res = (struct ipc_gen_phone_res_data *) gen_phone_res_data; retry_count = data->retry_count; rc = ipc_gen_phone_res_check(gen_phone_res); if (rc < 0) { if ((gen_phone_res->code & 0xff) == 0x10) { RIL_LOGE("%s: Wrong password and %d attempts left", __func__, retry_count); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else if ((gen_phone_res->code & 0xff) == 0x0c) { RIL_LOGE("%s: Wrong password and no attempts left", __func__); retry_count = 0; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_PASSWORD_INCORRECT, &retry_count, sizeof(retry_count)); } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, &retry_count, sizeof(retry_count)); } } else { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &retry_count, sizeof(retry_count)); } free(gen_phone_res_data); return 0; }
int ipc_rfs_create(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL) return -EINVAL; RIL_LOGD("Creating new RFS client"); ipc_client = ipc_client_create(IPC_CLIENT_TYPE_RFS); if (ipc_client == NULL) { RIL_LOGE("RFS client creation failed"); goto error_client_create; } client->data = (void *) ipc_client; RIL_LOGD("Setting log handler"); rc = ipc_client_set_log_callback(ipc_client, ipc_log_handler, NULL); if (rc < 0) { RIL_LOGE("Setting log handler failed"); goto error_log_callback; } RIL_LOGD("Creating data"); rc = ipc_client_data_create(ipc_client); if (rc < 0) { RIL_LOGE("Creating data failed"); goto error_data_create; } RIL_LOGD("Client open..."); rc = ipc_client_open(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to open ipc client", __func__); goto error_open; } RIL_LOGD("IPC RFS client done"); return 0; error: error_get_fd: ipc_client_close(ipc_client); error_open: ipc_client_data_destroy(ipc_client); error_data_create: error_log_callback: ipc_client_destroy(ipc_client); error_client_create: client->data = NULL; return -1; }