int ipc_call_incoming(struct ipc_message *message) { ril_request_unsolicited(RIL_UNSOL_CALL_RING, NULL, 0); ril_request_unsolicited(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); return 0; }
void ipc_net_regist_unsol(struct ipc_message_info *message) { struct ipc_net_regist *netinfo; netinfo = (struct ipc_net_regist *) message->data; LOGD("Got UNSOL NetRegist message"); switch(netinfo->domain) { case IPC_NET_SERVICE_DOMAIN_GSM: if(ril_state.tokens.registration_state != (RIL_Token) 0 && ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another NetRegist Req is in progress, skipping"); return; } memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist)); /* we already told RILJ to get the new data but it wasn't done yet */ if(ril_tokens_net_get_data_waiting() && ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating NetRegist data in background"); } else { ril_tokens_net_set_data_waiting(); ril_request_unsolicited(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0); } break; case IPC_NET_SERVICE_DOMAIN_GPRS: if(ril_state.tokens.gprs_registration_state != (RIL_Token) 0 && ril_state.tokens.gprs_registration_state != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another GPRS NetRegist Req is in progress, skipping"); return; } memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist)); /* we already told RILJ to get the new data but it wasn't done yet */ if(ril_tokens_net_get_data_waiting() && ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating GPRSNetRegist data in background"); } else { ril_tokens_net_set_data_waiting(); ril_request_unsolicited(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0); } break; default: LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain); break; } ril_tokens_net_state_dump(); }
int ril_request_answer(void *data, size_t size, RIL_Token token) { int rc; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_ANSWER); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_ANSWER, IPC_TYPE_EXEC, NULL, 0); if (rc < 0) goto error; ril_request_unsolicited(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); rc = RIL_REQUEST_HANDLED; goto complete; error: ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
int ipc_call_status(struct ipc_message *message) { struct ipc_call_status_data *data; int fail_cause; void *hangup_data; size_t hangup_size; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_status_data)) return -1; data = (struct ipc_call_status_data *) message->data; // Nobody will ask for a call fail cause when we hangup ourselves hangup_size = ril_request_data_size_get(RIL_REQUEST_HANGUP); hangup_data = ril_request_data_get(RIL_REQUEST_HANGUP); if (data->status == IPC_CALL_STATUS_RELEASED && (hangup_data == NULL || hangup_size == 0)) { fail_cause = ipc2ril_call_fail_cause(data->end_cause); ril_request_data_set_uniq(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, &fail_cause, sizeof(fail_cause)); } else if (hangup_data != NULL && hangup_size > 0) { free(hangup_data); } ril_request_unsolicited(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); return 0; }
int ipc_sec_pin_status(struct ipc_message *message) { struct ipc_sec_pin_status_response_data *data; struct ipc_sec_pin_status_request_data request_data; #if RIL_VERSION >= 6 RIL_CardStatus_v6 card_status; #else RIL_CardStatus card_status; #endif RIL_RadioState radio_state; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_pin_status_response_data)) return -1; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return 0; data = (struct ipc_sec_pin_status_response_data *) message->data; radio_state = ipc2ril_sec_pin_status_response(data, &card_status); if (radio_state == 0) return 0; if (card_status.applications[0].app_type == RIL_APPTYPE_SIM && card_status.applications[0].app_state == RIL_APPSTATE_PIN && ril_data->sim_pin != NULL) { ril_request_data_set_uniq(RIL_REQUEST_GET_SIM_STATUS, (void *) &card_status, sizeof(card_status)); rc = ipc_sec_pin_status_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1, ril_data->sim_pin, NULL); if (rc < 0) { ril_request_data_free(RIL_REQUEST_GET_SIM_STATUS); return 0; } rc = ipc_gen_phone_res_expect_callback(message->aseq, IPC_SEC_PIN_STATUS, ipc_sec_pin_status_callback); if (rc < 0) { ril_request_data_free(RIL_REQUEST_GET_SIM_STATUS); return 0; } rc = ipc_fmt_send(message->aseq, IPC_SEC_PIN_STATUS, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data)); if (rc < 0) { ril_request_data_free(RIL_REQUEST_GET_SIM_STATUS); return 0; } return 0; } ril_radio_state_update(radio_state); if (message->type == IPC_TYPE_RESP && ipc_seq_valid(message->aseq)) { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) &card_status, sizeof(card_status)); } else { ril_request_data_set_uniq(RIL_REQUEST_GET_SIM_STATUS, (void *) &card_status, sizeof(card_status)); ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); } return 0; }
int ril_request_hangup(void *data, size_t size, RIL_Token token) { int hangup; int rc; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; hangup = 1; ril_request_data_set_uniq(RIL_REQUEST_HANGUP, &hangup, sizeof(hangup)); rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_RELEASE); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_RELEASE, IPC_TYPE_EXEC, NULL, 0); if (rc < 0) goto error; ril_request_unsolicited(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); rc = RIL_REQUEST_HANDLED; goto complete; error: ril_request_data_free(RIL_REQUEST_HANGUP); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
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_sim_status(void *data) { ALOGE("%s: test me!", __func__); ril_sim_state sim_state; sim_state =(int) data; /* Update radio state based on SIM state */ ril_state_update(sim_state); ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); }
/** * In: IPC_SAT_PROACTIVE_CMD RESP * STK proactive command * * Out: RIL_UNSOL_STK_SESSION_END */ void respondSatProactiveCmdResp(struct ipc_message_info *info) { unsigned char sw1, sw2; 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 { ALOGE("%s: unhandled response sw1=%02x sw2=%02x", __FUNCTION__, sw1, sw2); } }
/** * In: IPC_SAT_PROACTIVE_CMD * STK proactive command * * Out: RIL_UNSOL_STK_PROACTIVE_COMMAND */ void respondSatProactiveCmdIndi(struct ipc_message_info *info) { int data_len = (info->length-2); char *hexdata; hexdata = (char*)malloc(data_len*2+1); bin2hex((unsigned char*)info->data+2, data_len, hexdata); ril_request_unsolicited(RIL_UNSOL_STK_PROACTIVE_COMMAND, hexdata, sizeof(char*)); free(hexdata); }
void ipc_sat_proactive_cmd_unsol(struct ipc_message_info *info) { char *hexdata; int length; if (info->data == NULL || info->length < 2) return; length = (info->length - 2); hexdata = (char *) calloc(1, length * 2 + 1); bin2hex((unsigned char *) info->data + 2, length, hexdata); ril_request_unsolicited(RIL_UNSOL_STK_PROACTIVE_COMMAND, hexdata, sizeof(char *)); free(hexdata); }
int ipc_sec_pin_status_callback(struct ipc_message *message) { struct ipc_gen_phone_res_data *data; 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; rc = ipc_gen_phone_res_check(data); if (rc < 0) { // Return the original SIM status ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); } else { // Destroy the original SIM status ril_request_data_free(RIL_REQUEST_GET_SIM_STATUS); } return 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 ril_state_update(ril_sim_state sim_state) { RIL_RadioState radio_state; /* If power mode isn't at least normal, don't update RIL state */ if (ril_data.state.power_state != POWER_STATE_NORMAL) return; ril_data.state.sim_state = sim_state; switch(sim_state) { case SIM_STATE_READY: radio_state = RADIO_STATE_SIM_READY; //request SMSC number sim_data_request_to_modem(4, 0x6f42); 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_data.state.radio_state = radio_state; ril_tokens_check(); ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0); }
void ipc_incoming_sms(void* data) { tapiNettextInfo* nettextInfo = (tapiNettextInfo*)(data); char *number_smsc, *da_len, *sca, *a, *b; char *number_oa, *tp_oa; char *pdu_type, *tp_pid, *tp_dcs, *tp_udl, *tp_ud, *message; char tp_scts[15]; char pdu[400]; char c[3]; char *number, *number2, *len_char; char *message_tmp, *number_tmp, *message_bin; uint8_t *mess, dcs; unsigned int i , len_sca, len_oa, message_length, len_mess; char buf[50]; time_t l_time; number_tmp = NULL; message_tmp = NULL; memset(tp_scts, 0, sizeof(tp_scts)); memset(pdu, 0, sizeof(pdu)); memset(c, 0, sizeof(c)); /* Convert sms packet to SMS-DELIVER PDU type format SMS = SCA + TPDU */ //SCA //Convert nettextInfo->serviceCenter to SCA number_smsc = nettextInfo->SMSC; if ((strlen(number_smsc) % 2) > 0) strcat(number_smsc, "F"); number = malloc(strlen(number_smsc) + 1); memset(number, 0, strlen(number_smsc) + 1); i = 0; while (i < strlen(number_smsc)) { a = &(number_smsc[i+1]); strncat(number, a, 1); b = &(number_smsc[i]); strncat(number, b, 1); i = i + 2; } sca = malloc(strlen(number) + 5); memset(sca, 0, strlen(number) + 5); len_sca = (strlen(number) / 2 ) + 1; asprintf(&len_char, "%02X", len_sca); strcat(sca, len_char); strcat(sca, "91"); strcat(sca, number); DEBUG_I("%s : sca = %s", __func__, sca); strcat (pdu, sca); if (number != NULL) free (number); if (sca != NULL) free (sca); len_char = NULL; //TPDU /* Protocol Data Unit Type (PDU Type) SMS-DELIVER TP-MTI: 00 TP-MMS: 04 TP-SRI: 20 TP-RP: 00 TP-UDHI: 00 */ if (nettextInfo->dischargeTime == 0x00) { if (nettextInfo->nUDH == 1) { pdu_type = "44"; } else { pdu_type = "04"; } DEBUG_I("%s : pdu_type = %s", __func__, pdu_type); strcat (pdu, pdu_type); } else { pdu_type = "06"; DEBUG_I("%s : pdu_type = %s", __func__, pdu_type); strcat (pdu, pdu_type); strcat (pdu, "00"); } // TP-OA: TP- Originating-Address //Convert nettextInfo->phoneNumber to TP-OA number_oa = nettextInfo->szFromNumber; if (nettextInfo->TON_FromNumber == 5 ) { ascii2gsm7(number_oa, (unsigned char **)&number_tmp, strlen(number_oa)); number2 = malloc((strlen(number_tmp)* 2) + 1); memset(number2, 0, (strlen(number_tmp)* 2) + 1); bin2hex((unsigned char *)number_tmp, strlen(number_tmp), number2); tp_oa = malloc(strlen(number2) + 5); memset(tp_oa, 0, strlen(number2) + 5); asprintf(&len_char, "%02X", strlen(number2)); strcat(tp_oa, len_char); strcat(tp_oa, "D0"); strcat(tp_oa, number2); DEBUG_I("%s : tp_oa = %s", __func__, tp_oa); } else { len_oa = strlen(number_oa); if ((strlen(number_oa) % 2) > 0) strcat(number_oa, "F"); number2 = malloc(strlen(number_oa) + 1); memset(number2, 0, strlen(number_oa) + 1); i = 0; while (i < strlen(number_oa)) { a = &(number_oa[i+1]); strncat(number2, a, 1); b = &(number_oa[i]); strncat(number2, b, 1); i = i + 2; } tp_oa = malloc(strlen(number2) + 5); memset(tp_oa, 0, strlen(number2) + 5); asprintf(&len_char, "%02X", len_oa); strcat(tp_oa, len_char); if (nettextInfo->TON_FromNumber == 1 ) strcat(tp_oa, "91"); else strcat(tp_oa, "81"); strcat(tp_oa, number2); DEBUG_I("%s : tp_oa = %s", __func__, tp_oa); } strcat (pdu, tp_oa); if (number2 != NULL) free (number2); if (tp_oa != NULL) free (tp_oa); len_char = NULL; //TP-PID : TP-Protocol-Identifier if (nettextInfo->dischargeTime == 0x00) { tp_pid = "00"; strcat (pdu, tp_pid); } //TP-SCTS: TP-Service-Centre-Time-Stamp //Convert nettextInfo->timestamp and nettextInfo->time_zone to TP-SCTS l_time = nettextInfo->scTime; strftime(buf, sizeof(buf), "%y%m%d%H%M%S", gmtime(&l_time)); asprintf(&a, "%02d", nettextInfo->time_zone); strcat(buf, a); i = 0; while (i < 14) { a = &(buf[i+1]); strncat(tp_scts, a, 1); b = &(buf[i]); strncat(tp_scts, b, 1); i = i + 2; } DEBUG_I("%s : scTime = %s", __func__, tp_scts); if (nettextInfo->dischargeTime != 0x00) { strcat (pdu, tp_scts); memset(tp_scts, 0, 15); l_time = nettextInfo->dischargeTime; strftime(buf, sizeof(buf), "%y%m%d%H%M%S", gmtime(&l_time)); asprintf(&a, "%02d", nettextInfo->time_zone); strcat(buf, a); i = 0; while (i < 14) { a = &(buf[i+1]); strncat(tp_scts, a, 1); b = &(buf[i]); strncat(tp_scts, b, 1); i = i + 2; } DEBUG_I("%s : dischargeTime = %s", __func__, tp_scts); strcat (pdu, tp_scts); if (nettextInfo->statusReport == 0) strcat (pdu, "00"); else strcat (pdu, "01"); DEBUG_I("%s : pdu = %s", __func__, pdu); ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, pdu, strlen(pdu)); return; } //TP-UD: TP-User Data //Convert messageBody to TP-UD mess = nettextInfo->messageBody; message_length = nettextInfo->messageLength; message = malloc((message_length * 2) + 3); memset(message, 0, (message_length * 2) + 3); i = 0; if (nettextInfo->nUDH == 1) { strcat(message, "05"); message_length += 1; } while (i < nettextInfo->messageLength) { sprintf(c, "%02X",mess[i]); strcat(message, c); i++; } if (nettextInfo->alphabetType == 3) { /*TP-DCS: TP-Data-Coding-Scheme */ dcs = 0x08; //Unicode DEBUG_I("%s : TP-DCS = Unicode", __func__); tp_ud = malloc(strlen(message) + 2); memset(tp_ud, 0, strlen(message) + 2); strcat(tp_ud,message); } else { /*TP-DCS: TP-Data-Coding-Scheme */ dcs = 0x00; //gsm7 DEBUG_I("%s : TP-DCS = GSM7", __func__); if (nettextInfo->nUDH == 1) { message_bin = malloc(strlen(message) + 3); memset(message_bin, 0, strlen(message) + 3); strcat(message_bin, "0000000"); strcat(message_bin, (char *)(mess + 5)); len_mess = ascii2gsm7(message_bin, (unsigned char **)&message_tmp, strlen(message) + 2); tp_ud = malloc(len_mess + 1); memset(tp_ud, 0, len_mess + 1); bin2hex((unsigned char *)(message_tmp), len_mess / 2, tp_ud); i = 0; while (i < 12) { tp_ud[i] = message[i]; i++; } message_length += 1; if (message_bin != NULL) free(message_bin); } else { len_mess = ascii2gsm7((char *)mess, (unsigned char **)&message_tmp, strlen(message)); tp_ud = malloc(len_mess + 1); memset(tp_ud, 0, len_mess + 1); bin2hex((unsigned char *)message_tmp, len_mess / 2, tp_ud); } } DEBUG_I("%s : tp_ud = %s", __func__, tp_ud); if (nettextInfo->bFlash == 1) dcs += 0x10; asprintf(&tp_dcs, "%02X", dcs); //TP-UDL:TP-User-Data-Length asprintf(&tp_udl, "%02X", message_length); DEBUG_I("%s : tp_udl = %s", __func__, tp_udl); strcat (pdu, tp_dcs); strcat (pdu, tp_scts); strcat (pdu, tp_udl); strcat (pdu, tp_ud); DEBUG_I("%s : pdu = %s", __func__, pdu); ril_request_unsolicited(RIL_UNSOL_RESPONSE_NEW_SMS, pdu, strlen(pdu)); if (message != NULL) free (message); if (tp_ud != NULL) free (tp_ud); }
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; }
/** * In: IPC_NET_CURRENT_PLMN * This can be SOL (RESP) or UNSOL (NOTI) message from modem * * Out: RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED * enqueue modem data if UNSOL modem message and then call * RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED * if SOL message, send back data to RILJ */ void ipc_net_current_plmn(struct ipc_message_info *message) { RIL_Token t = reqGetToken(message->aseq); struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data; char *response[3]; int i; switch(message->type) { case IPC_TYPE_NOTI: LOGD("Got UNSOL Operator message"); // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN || ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) { /* Better keeping it up to date */ memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); return; } else { if(ril_state.tokens.operator != (RIL_Token) 0x00 && ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) { LOGE("Another Operator Req is in progress, skipping"); return; } memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); /* we already told RILJ to get the new data but it wasn't done yet */ if(ril_tokens_net_get_data_waiting() && ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) { LOGD("Updating Operator data in background"); } else { ril_tokens_net_set_data_waiting(); ril_request_unsolicited(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0); } } break; case IPC_TYPE_RESP: // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE || ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING || ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN || ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) { /* Better keeping it up to date */ memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); ril_request_complete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0); if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) ril_state.tokens.operator = (RIL_Token) 0x00; return; } else { if(ril_state.tokens.operator != t) LOGE("Operator tokens mismatch"); /* Better keeping it up to date */ memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn)); ril_plmn_string(plmndata, response); ril_request_complete(t, RIL_E_SUCCESS, response, sizeof(response)); for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) { if(response[i] != NULL) free(response[i]); } if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) ril_state.tokens.operator = (RIL_Token) 0x00; } break; default: LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type); break; } ril_tokens_net_state_dump(); }