Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
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;
}
Пример #6
0
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);
}
Пример #7
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);
}
Пример #8
0
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();
	}
}
Пример #9
0
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;	
	}
}
Пример #10
0
/**
 * 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;
}
Пример #12
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);
}
Пример #13
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
}
Пример #14
0
void ipc_sms_incoming_msg(struct ipc_message_info *info)
{
	struct ipc_sms_incoming_msg *msg;
	unsigned char *pdu_hex;
	char *pdu;
	int length;
	int rc;

	if (info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg))
		goto error;

	msg = (struct ipc_sms_incoming_msg *) info->data;
	pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg));

	length = msg->length * 2 + 1;
	pdu = (char *) calloc(1, length);

	bin2hex(pdu_hex, msg->length, pdu);

	if (ril_data.state.sms_incoming_msg_tpid != 0) {
		RIL_LOGD("Another message is waiting ACK, queuing");
		rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid);
		if (rc < 0)
			RIL_LOGE("Unable to register incoming msg");

		return;
	}

	ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid);

	return;

error:
	if (info != NULL)
		ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
}
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;
}
Пример #16
0
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;
}
Пример #18
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();
}
Пример #19
0
void ril_request_send_sms(RIL_Token t, void *data, size_t length)
{
	char *pdu = NULL;
	int pdu_length;
	unsigned char *smsc = NULL;
	int smsc_length;
	int rc;

	if (data == NULL || length < (int) (2 * sizeof(char *)))
		goto error;

	if (ril_radio_state_complete(RADIO_STATE_OFF, t))
		return;

	pdu = ((char **) data)[1];
	smsc = ((unsigned char **) data)[0];
	pdu_length = 0;
	smsc_length = 0;

	if (pdu != NULL) {
		pdu_length = strlen(pdu) + 1;
		pdu = strdup(pdu);
	}
	if (smsc != NULL) {
		smsc_length = strlen((char *) smsc);
		smsc = (unsigned char *) strdup((char *) smsc);
	}

	if (ril_data.tokens.outgoing_sms != RIL_TOKEN_NULL) {
		RIL_LOGD("Another outgoing SMS is being processed, adding to the list");

		rc = ril_request_send_sms_register(pdu, pdu_length, smsc, smsc_length, t);
		if (rc < 0) {
			RIL_LOGE("Unable to add the request to the list");
			goto error;
		}

		return;
	}

	ril_data.tokens.outgoing_sms = t;
	if (smsc == NULL) {
		// We first need to get SMS SVC before sending the message
		RIL_LOGD("We have no SMSC, let's ask one");

		rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t);
		if (rc < 0) {
			RIL_LOGE("Unable to add the request to the list");
			goto error;
		}

		ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t));
	} else {
		ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length);
		if (pdu != NULL)
			free(pdu);
		if (smsc != NULL)
			free(smsc);
	}

	return;

error:
	ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);

	if (pdu != NULL)
		free(pdu);
	if (smsc != NULL)
		free(smsc);
	// Send the next SMS in the list
	ril_request_send_sms_next();
}
Пример #20
0
// 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));
}
Пример #21
0
/**
 * 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;
}
Пример #23
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);
}
Пример #24
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();
}
Пример #25
0
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));
	
}