void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t datalen) { char *pin = ((char **) data)[0]; /* 1. Send PIN */ if (strlen(data) > 16) { ALOGE("%s: pin exceeds maximum length", __FUNCTION__); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); } sim_verify_chv(0x4, 0x0, pin); ril_data.tokens.pin_status = t; }
void ipc_sms_deliver_report(struct ipc_message_info *info) { struct ipc_sms_deliver_report_response *report_msg; RIL_Errno e; int error_code; if (info->data == NULL || info->length < sizeof(struct ipc_sms_deliver_report_response)) goto error; report_msg = (struct ipc_sms_deliver_report_response *) info->data; e = ipc2ril_sms_ack_error(report_msg->error, &error_code); ril_request_complete(ril_request_get_token(info->aseq), e, NULL, 0); return; error: if (info != NULL) ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
void ril_request_deactivate_data_call(RIL_Token t, void *data, int length) { struct ipc_gprs_pdp_context deactivate_message; memset(&deactivate_message, 0, sizeof(deactivate_message)); deactivate_message.unk0[1]=1; /* send the struct to the modem */ ipc_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET, (void *) &deactivate_message, sizeof(struct ipc_gprs_pdp_context), reqGetId(t)); ril_request_complete(t, RIL_E_SUCCESS, NULL, 0); }
int ipc_call_burst_dtmf(struct ipc_message *message) { if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_burst_dtmf_response_data)) return -1; if (!ipc_seq_valid(message->aseq)) return 0; ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0); return 0; }
int ril_request_dial(void *data, size_t size, RIL_Token token) { struct ipc_call_outgoing_data request_data; RIL_Dial *dial = NULL; unsigned char identity; unsigned char prefix; int rc; if (data == NULL || size < sizeof(RIL_Dial)) goto error; rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY); if (rc < 0) return RIL_REQUEST_UNHANDLED; dial = (RIL_Dial *) data; if (dial->address == NULL) goto error; identity = ril2ipc_call_identity(dial->clir); prefix = dial->address[0] == '+' ? IPC_CALL_PREFIX_INTL : IPC_CALL_PREFIX_NONE; rc = ipc_call_outgoing_setup(&request_data, IPC_CALL_TYPE_VOICE, identity, prefix, dial->address); if (rc < 0) goto error; free(dial->address); dial = NULL; rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_OUTGOING); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_OUTGOING, IPC_TYPE_EXEC, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: if (dial != NULL && dial->address != NULL) free(dial->address); ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
void ipc_sat_envelope_cmd(struct ipc_message_info *info) { char *hexdata; int size; if (info->data == NULL || info->length < 2) goto error; size = (info->length - 2); hexdata = (char *) calloc(1, size * 2 + 1); bin2hex((unsigned char *) info->data + 2, size, hexdata); ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, hexdata, sizeof(char *)); free(hexdata); return; error: ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
/** * In: IPC_SAT_ENVELOPE_CMD EXEC * * Out: RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 */ void respondSatEnvelopeCmd(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_complete(reqGetToken(info->aseq), RIL_E_SUCCESS, hexdata, sizeof(char*)); free(hexdata); }
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 ipc_pin_status(void* data) { ALOGE("%s: test me!", __func__); pinStatus* pinSt = (pinStatus*)(data); int attempts = -1; switch(pinSt->status){ case 0: DEBUG_I("%s : Correct password ", __func__); ril_request_complete(ril_data.tokens.pin_status, RIL_E_SUCCESS, &attempts, sizeof(attempts)); return; case 1: DEBUG_I("%s : Wrong password ", __func__); attempts = pinSt->attempts; ril_request_complete(ril_data.tokens.pin_status, RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts)); return; case 2: DEBUG_I("%s : Wrong password and no attempts left!", __func__); attempts = 0; ril_request_complete(ril_data.tokens.pin_status, RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts)); sim_status(4); return; } }
/** * In: RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 * * Out: IPC_SAT_ENVELOPE_CMD EXEC */ void requestSatSendEnvelopeCommand(RIL_Token t, void *data, size_t datalen) { unsigned char buf[264]; int len = (strlen(data) / 2); if(len > 255) { ALOGE("%s: data exceeds maximum length", __FUNCTION__); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); } memset(buf, 0, sizeof(buf)); buf[0] = len; hex2bin(data, strlen(data), &buf[1]); ipc_send(IPC_SAT_ENVELOPE_CMD, IPC_TYPE_EXEC, buf, sizeof(buf), reqGetId(t)); }
int ril_request_radio_power(void *data, size_t size, RIL_Token token) { struct ipc_pwr_phone_state_request_data request_data; struct ril_request *request; int power_state; int rc; if (data == NULL || size < sizeof(power_state)) goto error; request = ril_request_find_request_status(RIL_REQUEST_RADIO_POWER, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; power_state = *((int *)data); memset(&request_data, 0, sizeof(request_data)); if (power_state > 0) { RIL_LOGD("Requesting normal power state"); request_data.state = IPC_PWR_PHONE_STATE_REQUEST_NORMAL; } else { RIL_LOGD("Requesting low power mode power state"); request_data.state = IPC_PWR_PHONE_STATE_REQUEST_LPM; } rc = ipc_gen_phone_res_expect_abort(ipc_fmt_request_seq(token), IPC_PWR_PHONE_STATE); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
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_gprs_pdp_context_complete(struct ipc_message_info *info) { struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data; int rc; int aseq; rc = ipc_gen_phone_res_check(phone_res); if(rc < 0) { ril_request_complete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); LOGE("There was an error, aborting PDP context complete"); return; } /* We need to get a clean new aseq here */ aseq = ril_request_reg_id(reqGetToken(info->aseq)); /* activate the connection */ ipc_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET, (void *) &(ril_state.gprs_context), sizeof(struct ipc_gprs_pdp_context), aseq); ipc_gen_phone_res_expect_to_abort(aseq, IPC_GPRS_PDP_CONTEXT); // TODO: if this aborts, last fail cause will be: PDP_FAIL_ERROR_UNSPECIFIED }
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); }
int ril_request_dtmf_start(void *data, size_t size, RIL_Token token) { struct ril_request *request; void *dtmf_data; size_t dtmf_size; char tone; int rc; if (data == NULL || size < 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_DTMF, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_DTMF_START, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; tone = *((char *) data); // A previous DTMF tone was started dtmf_size = ril_request_data_size_get(RIL_REQUEST_DTMF_START); dtmf_data = ril_request_data_get(RIL_REQUEST_DTMF_START); if (dtmf_data != NULL && dtmf_size >= sizeof(tone)) { free(dtmf_data); // Let the callback know what to do after completing the previous DTMF tone ril_request_data_set(RIL_REQUEST_DTMF_START, data, size); rc = ril_request_dtmf_stop_complete(ipc_fmt_request_seq(token), 1); if (rc < 0) { ril_request_data_free(RIL_REQUEST_DTMF_START); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; } // Register a new DTMF tone ril_request_data_set(RIL_REQUEST_DTMF_START, data, size); rc = ril_request_dtmf_start_complete(ipc_fmt_request_seq(token), tone); if (rc < 0) { ril_request_data_free(RIL_REQUEST_DTMF_START); goto error; } rc = RIL_REQUEST_HANDLED; goto complete; error: ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
void ril_on_request(int request, void *data, size_t datalen, RIL_Token t) { int check; RIL_LOCK(); LOGV("Request from RILD ID - %d", request); check = ril_modem_check(); if(check < 0) { LOGE("ril_modem_check() returned %d => replying RIL_E_RADIO_NOT_AVAILABLE", check); ril_request_complete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); } switch(request) { /* MISC */ case RIL_REQUEST_GET_IMEI: ril_request_get_imei(t); break; case RIL_REQUEST_GET_IMSI: ril_request_get_imsi(t); break; /* PWR */ case RIL_REQUEST_RADIO_POWER: ril_request_radio_power(t, data, datalen); break; case RIL_REQUEST_BASEBAND_VERSION: ril_request_baseband_version(t); break; #if 0 /* SAT */ case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: requestSatSendTerminalResponse(t, data, datalen); break; case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: requestSatSendEnvelopeCommand(t, data, datalen); break; case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ril_request_complete(t, RIL_E_SUCCESS, NULL, 0); break; #endif /* SIM */ case RIL_REQUEST_GET_SIM_STATUS: ril_request_get_sim_status(t); break; #if 0 case RIL_REQUEST_SIM_IO: ril_request_sim_io(t, data, datalen); break; #endif case RIL_REQUEST_ENTER_SIM_PIN: ril_request_enter_sim_pin(t, data, datalen); break; #if 0 case RIL_REQUEST_QUERY_FACILITY_LOCK: ril_request_query_facility_lock(t, data, datalen); break; case RIL_REQUEST_SET_FACILITY_LOCK: ril_request_set_facility_lock(t, data, datalen); break; #endif /* NET */ case RIL_REQUEST_OPERATOR: ril_request_operator(t); break; case RIL_REQUEST_VOICE_REGISTRATION_STATE: ril_request_voice_registration_state(t); break; #if 0 case RIL_REQUEST_GPRS_REGISTRATION_STATE: ril_request_gprs_registration_state(t); break; case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: ril_request_query_available_networks(t); break; case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ril_request_query_network_selection_mode(t); break; #endif case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ril_request_get_preferred_network_type(t); break; case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ril_request_set_preferred_network_type(t, data, datalen); break; /* SMS */ case RIL_REQUEST_SEND_SMS: ril_request_send_sms(t, data, datalen); break; #if 0 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ril_request_send_sms_expect_more(t, data, datalen); break; case RIL_REQUEST_SMS_ACKNOWLEDGE: ril_request_sms_acknowledge(t, data, datalen); break; #endif /* CALL */ case RIL_REQUEST_DIAL: ril_request_dial(t, data, datalen); break; case RIL_REQUEST_GET_CURRENT_CALLS: ril_request_get_current_calls(t); break; case RIL_REQUEST_HANGUP: case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ril_request_hangup(t); break; case RIL_REQUEST_ANSWER: ril_request_answer(t); break; case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ril_request_last_call_fail_cause(t); break; case RIL_REQUEST_DTMF: ril_request_dtmf(t, data, datalen); break; case RIL_REQUEST_DTMF_START: ril_request_dtmf_start(t, data, datalen); break; case RIL_REQUEST_DTMF_STOP: ril_request_dtmf_stop(t); break; #if 0 /* GPRS */ case RIL_REQUEST_SETUP_DATA_CALL: ril_request_setup_data_call(t, data, datalen); break; case RIL_REQUEST_DEACTIVATE_DATA_CALL: ril_request_deactivate_data_call(t, data, datalen); break; #endif /* SND */ case RIL_REQUEST_SET_MUTE: ril_request_set_mute(t, data, datalen); /* SS */ case RIL_REQUEST_SEND_USSD: ril_request_send_ussd(t, data, datalen); break; case RIL_REQUEST_CANCEL_USSD: ril_request_cancel_ussd(t, data, datalen); break; /* OTHER */ case RIL_REQUEST_SCREEN_STATE: ril_request_screen_state(t, data, datalen); break; default: LOGE("Request not implemented: %d", request); ril_request_complete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); break; } RIL_UNLOCK(); }
int ipc_call_list(struct ipc_message *message) { struct ipc_call_list_entry *entry; RIL_Call **calls = NULL; size_t calls_size; unsigned int calls_count = 0; unsigned char count; unsigned char index; char *number; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_list_header)) return -1; if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq)) return 0; count = ipc_call_list_count_extract(message->data, message->size); if (count == 0) { ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0); return 0; } calls_size = count * sizeof(RIL_Call *); calls = (RIL_Call **) calloc(1, calls_size); for (index = 0; index < count; index++) { entry = ipc_call_list_entry_extract(message->data, message->size, index); if (entry == NULL) goto error; number = ipc_call_list_entry_number_extract(entry); if (number == NULL) goto error; calls[index] = (RIL_Call *) calloc(1, sizeof(RIL_Call)); calls[index]->state = ipc2ril_call_list_entry_state(entry->status); calls[index]->index = entry->id; calls[index]->isMpty = entry->mpty; calls[index]->isMT = entry->term == IPC_CALL_TERM_MT; calls[index]->als = 0; calls[index]->isVoice = entry->type == IPC_CALL_TYPE_VOICE; calls[index]->isVoicePrivacy = 0; calls[index]->number = strdup(number); calls[index]->numberPresentation = (entry->number_length > 0) ? 0 : 2; calls[index]->name = NULL; calls[index]->namePresentation = 2; calls[index]->uusInfo = NULL; if (entry->number_length > 0 && number != NULL && number[0] == '+') calls[index]->toa = 145; else calls[index]->toa = 129; calls_count++; } calls_size = calls_count * sizeof(RIL_Call *); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) calls, calls_size); goto complete; error: ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); complete: if (calls != NULL && calls_size > 0) { for (index = 0; index < calls_count; index++) { if (calls[index] == NULL) continue; if (calls[index]->number != NULL) free(calls[index]->number); free(calls[index]); } free(calls); } return 0; }
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(); }
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(); }
// FIXME: add corect implementation void ril_request_query_network_selection_mode(RIL_Token t) { unsigned int mode = 0; ril_request_complete(t, RIL_E_SUCCESS, &mode, sizeof(mode)); }
/** * In: RIL_REQUEST_SEND_SMS * Send an SMS message. * * Out: TAPI_NETTEXT_SEND */ void ril_request_send_sms(RIL_Token t, void *data, size_t length) { tapiNettextInfo* mess; char *pdu, *a, *message; unsigned char *smsc, *pdu_hex, *p, *message_tmp; int smsc_length, pdu_length, pdu_hex_length, i, numberLen, send_msg_type; if (data == NULL || length < 2 * sizeof(char *)) return; pdu = ((char **) data)[1]; pdu_length = 0; if (pdu != NULL) { pdu_length = strlen(pdu) + 1; pdu = strdup(pdu); } /* We first need to get SMS SVC before sending the message */ smsc_length = strlen((char *) ril_data.smsc_number); smsc = (unsigned char *) strdup((char *) ril_data.smsc_number); if (pdu == NULL || pdu_length <= 0 || smsc == NULL || smsc_length <= 0) { LOGE("Provided PDU or SMSC is invalid! Aborting"); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } if ((pdu_length / 2 + smsc_length) > 0xfe) { LOGE("PDU or SMSC too large, aborting"); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 : (pdu_length ^ 1) / 2; pdu_hex = calloc(1, pdu_hex_length); hex2bin(pdu, pdu_length, pdu_hex); send_msg_type = 0; /* 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) { LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len); goto pdu_end; } 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 / 2 + 5; if (pdu_tp_da_len % 2 > 0) pdu_tp_udh_index += 1; unsigned char pdu_tp_udh_len = pdu_hex[pdu_tp_udh_index]; if (pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) { LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len); goto pdu_end; } 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) { 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) { LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq); goto pdu_end; } LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num); if (pdu_tp_udh_num > 1) { LOGD("We are sending a multi-part message!"); send_msg_type = 1; //multi-part } pdu_end: DEBUG_I("%s : pdu : %s", __func__, pdu); numberLen = (uint8_t)pdu_tp_da_len; mess = (tapiNettextInfo *)malloc(sizeof(tapiNettextInfo)); memset(mess, 0, sizeof(tapiNettextInfo)); mess->NPI_ToNumber= 0x01; // 01 if (pdu_hex[pdu_tp_da_index + 1] == 0x91) mess->TON_ToNumber= 0x01; // 01 - international else mess->TON_ToNumber= 0x00; // 00 - national mess->lengthToNumber = numberLen; if (numberLen % 2 > 0) numberLen = numberLen + 1; i = 0; while (i < numberLen) { mess->szToNumber[i] = pdu[i + 9]; if ( pdu[i + 8] != 'f') mess->szToNumber[i+1] =pdu[i + 8]; i = i + 2; } mess->scTime = time(NULL); mess->NPI_SMSC = 0x01; if (smsc[2] == 0x39 && smsc [3] == 0x31) mess->TON_SMSC = 0x01; // 01 - international else mess->TON_SMSC= 0x00; // 00 - national if (smsc[smsc_length - 2] == 'f' || smsc[smsc_length - 2] == 'F') mess->lengthSMSC = smsc_length - 5; else mess->lengthSMSC = smsc_length - 4; i = 4; while (i < smsc_length) { mess->SMSC[i - 4] = smsc[i + 1]; if ( smsc[i] != 'f') mess->SMSC[i - 3] =smsc[i]; i = i + 2; } if (pdu_hex[0] == 0x21 || pdu_hex[0] == 0x61) mess->bSRR = 0x01; mess->validityValue = 0xFF; //FF mess->classType = 0x04; //04 if (send_msg_type == 1) { mess->nUDH = 0x01; //multipart SMS mess->bUDHI = 0x01; mess->messageLength = pdu_hex[(numberLen / 2) + 6] - 1; } else mess->messageLength = pdu_hex[(numberLen / 2) + 6]; if (pdu_hex[(numberLen / 2) + 5] == 8) { DEBUG_I("%s : DCS - Unicode", __func__); mess->alphabetType = 0x03; //Unicode if (send_msg_type == 0) { int k = (numberLen / 2) + 7; for (i = 0; i < pdu_hex[(numberLen / 2) + 6]; i++) mess->messageBody[i] = pdu_hex[i + k]; } else { int k = (numberLen / 2) + 8; for (i = 0; i < pdu_hex[(numberLen / 2) + 6] - 1; i++) mess->messageBody[i] = pdu_hex[i + k]; } } else { DEBUG_I("%s : DCS - GSM7", __func__); mess->alphabetType = 0x00; //GSM7 int k = (numberLen / 2) + 7; message_tmp = malloc(((pdu_hex[(numberLen / 2) + 6]) * 2) + 1); memset(message_tmp, 0, ((pdu_hex[(numberLen / 2) + 6]) * 2) + 1); for (i = 0; i < pdu_hex[(numberLen / 2) + 6]; i++) message_tmp[i] = pdu_hex[i + k]; gsm72ascii(message_tmp, &message, pdu_hex[(numberLen / 2) + 6]); if (send_msg_type == 0) { for (i = 0; i < pdu_hex[(numberLen / 2) + 6]; i++) mess->messageBody[i] = message[i]; } else { mess->messageLength = mess->messageLength - 1; for (i = 0; i < pdu_hex[(numberLen / 2) + 6] - 2; i++) mess->messageBody[i] = message[i + 2]; for (i = 0; i < 5; i++) mess->messageBody[i] = pdu_hex[(numberLen / 2) + 8 + i]; } free(message_tmp); } tapi_nettext_set_net_burst(0); tapi_nettext_send((uint8_t *)mess); ril_data.tokens.outgoing_sms = t; if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); if (mess != NULL) free(mess); if (pdu_hex != NULL) free(pdu_hex); }
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; }
void ril_request_write_sms_to_sim(RIL_Token token, void *data, size_t size) { struct ipc_sms_save_msg_request_data *sms_save_msg_request_data; RIL_SMS_WriteArgs *args; void *buffer = NULL; size_t length; size_t data_length; size_t pdu_length = 0; size_t pdu_hex_length = 0; size_t smsc_length = 0; size_t smsc_hex_length = 0; unsigned char *p; if (data == NULL || size < sizeof(RIL_SMS_WriteArgs)) goto error; if (ril_radio_state_complete(RADIO_STATE_OFF, token)) return; args = (RIL_SMS_WriteArgs *) data; if (args->pdu != NULL) { pdu_length = strlen(args->pdu); pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 : (pdu_length ^ 1) / 2; } if (args->smsc != NULL) { smsc_length = strlen(args->smsc); smsc_hex_length = smsc_length % 2 == 0 ? smsc_length / 2 : (smsc_length ^ 1) / 2; } data_length = pdu_hex_length + smsc_hex_length; if (data_length == 0 || data_length > 0xff) goto error; length = sizeof(struct ipc_sms_save_msg_request_data) + data_length; buffer = malloc(length); sms_save_msg_request_data = (struct ipc_sms_save_msg_request_data *) buffer; memset(sms_save_msg_request_data, 0, sizeof(struct ipc_sms_save_msg_request_data)); sms_save_msg_request_data->unknown = 0x02; sms_save_msg_request_data->index = 12 - 1; sms_save_msg_request_data->status = ril2ipc_sms_save_msg_status(args->status); sms_save_msg_request_data->length = (unsigned char) (data_length & 0xff); p = (unsigned char *) buffer + sizeof(struct ipc_sms_save_msg_request_data); if (args->smsc != NULL && smsc_length > 0) { hex2bin(args->smsc, smsc_length, p); p += smsc_hex_length; } if (args->pdu != NULL && pdu_length > 0) { hex2bin(args->pdu, pdu_length, p); p += pdu_hex_length; } ipc_gen_phone_res_expect_to_abort(ril_request_get_id(token), IPC_SMS_SAVE_MSG); ipc_fmt_send(IPC_SMS_SAVE_MSG, IPC_TYPE_EXEC, buffer, length, ril_request_get_id(token)); goto complete; error: ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); complete: if (buffer != NULL) free(buffer); }
/** * 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(); }
void ril_request_get_sim_status(RIL_Token t) { ALOGE("%s: test me!", __func__); RIL_CardStatus_v6 card_status; ril_sim_state sim_state; int app_status_array_length; int app_index; int i; 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 }, }; sim_state = ril_data.state.sim_state; /* Card is assumed to be present if not explicitly absent */ if(ril_data.state.sim_state == SIM_STATE_ABSENT) { card_status.card_state = RIL_CARDSTATE_ABSENT; } else { card_status.card_state = RIL_CARDSTATE_PRESENT; } // Initialize the apps for (i = 0 ; i < RIL_CARD_MAX_APPS ; i++) { card_status.applications[i] = app_status_array[0]; } // FIXME: How do we know that? card_status.universal_pin_state = RIL_PINSTATE_UNKNOWN; /* Initialize apps */ for (i = 0; i < RIL_CARD_MAX_APPS; i++) { card_status.applications[i] = app_status_array[i]; } // 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 = RIL_CARD_MAX_APPS; ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status)); }