diff options
| author | Paul Kocialkowski <contact@paulk.fr> | 2013-02-09 12:45:41 +0100 | 
|---|---|---|
| committer | Paul Kocialkowski <contact@paulk.fr> | 2013-02-09 12:45:41 +0100 | 
| commit | 7c0d9885a60491272c67f03c3efc263a7810e64e (patch) | |
| tree | 42c32bbcf4c2dcc73f3a2565cf643be5abed1e48 | |
| parent | e1a4eb9c0632d60ad96c685330202593775bb716 (diff) | |
| download | hardware_ril_samsung-ril-7c0d9885a60491272c67f03c3efc263a7810e64e.zip hardware_ril_samsung-ril-7c0d9885a60491272c67f03c3efc263a7810e64e.tar.gz hardware_ril_samsung-ril-7c0d9885a60491272c67f03c3efc263a7810e64e.tar.bz2  | |
sec: Send SIM I/O requests one after another
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
| -rw-r--r-- | samsung-ril.h | 19 | ||||
| -rw-r--r-- | sec.c | 207 | 
2 files changed, 205 insertions, 21 deletions
diff --git a/samsung-ril.h b/samsung-ril.h index 1643658..9071ba5 100644 --- a/samsung-ril.h +++ b/samsung-ril.h @@ -134,6 +134,7 @@ struct ril_tokens {  	RIL_Token operator;  	RIL_Token outgoing_sms; +	RIL_Token sim_io;  };  void ril_tokens_check(void); @@ -177,8 +178,6 @@ struct ril_state {  	unsigned char sms_incoming_msg_tpid;  }; -void ril_state_lpm(void); -  /**   * RIL data   */ @@ -191,6 +190,7 @@ struct ril_data {  	struct list_head *gprs_connections;  	struct list_head *incoming_sms;  	struct list_head *outgoing_sms; +	struct list_head *sim_io;  	struct list_head *generic_responses;  	struct list_head *requests;  	int request_id; @@ -271,9 +271,24 @@ void ipc_ss_ussd(struct ipc_message_info *info);  /* SEC */ +struct ril_request_sim_io_info { +	unsigned char command; +	unsigned short fileid; +	unsigned char p1; +	unsigned char p2; +	unsigned char p3; +	void *data; +	int length; + +	RIL_Token token; +}; +  void ril_state_update(ril_sim_state status);  void ipc_sec_sim_status(struct ipc_message_info *info);  void ril_request_get_sim_status(RIL_Token t); +void ril_request_sim_io_next(void); +void ril_request_sim_io_complete(RIL_Token t, unsigned char command, unsigned short fileid, +	unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length);  void ril_request_sim_io(RIL_Token t, void *data, int length);  void ipc_sec_rsim_access(struct ipc_message_info *info);  void ipc_sec_sim_status_complete(struct ipc_message_info *info); @@ -316,6 +316,162 @@ void ril_request_get_sim_status(RIL_Token t)  	ril_tokens_pin_status_dump();  } +/* + * SIM I/O + */ + +int ril_request_sim_io_register(RIL_Token t, unsigned char command, unsigned short fileid, +	unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length) +{ +	struct ril_request_sim_io_info *sim_io; +	struct list_head *list_end; +	struct list_head *list; + +	sim_io = calloc(1, sizeof(struct ril_request_sim_io_info)); +	if (sim_io == NULL) +		return -1; + +	sim_io->command = command; +	sim_io->fileid = fileid; +	sim_io->p1 = p1; +	sim_io->p2 = p2; +	sim_io->p3 = p3; +	sim_io->data = data; +	sim_io->length = length; +	sim_io->token = t; + +	list_end = ril_data.sim_io; +	while (list_end != NULL && list_end->next != NULL) +		list_end = list_end->next; + +	list = list_head_alloc((void *) sim_io, list_end, NULL); + +	if (ril_data.sim_io == NULL) +		ril_data.sim_io = list; + +	return 0; +} + +void ril_request_sim_io_unregister(struct ril_request_sim_io_info *sim_io) +{ +	struct list_head *list; + +	if (sim_io == NULL) +		return; + +	list = ril_data.sim_io; +	while (list != NULL) { +		if (list->data == (void *) sim_io) { +			memset(sim_io, 0, sizeof(struct ril_request_sim_io_info)); +			free(sim_io); + +			if (list == ril_data.sim_io) +				ril_data.sim_io = list->next; + +			list_head_free(list); + +			break; +		} +list_continue: +		list = list->next; +	} +} + +struct ril_request_sim_io_info *ril_request_sim_io_info_find(void) +{ +	struct ril_request_sim_io_info *sim_io; +	struct list_head *list; + +	list = ril_data.sim_io; +	while (list != NULL) { +		sim_io = (struct ril_request_sim_io_info *) list->data; +		if (sim_io == NULL) +			goto list_continue; + +		return sim_io; + +list_continue: +		list = list->next; +	} + +	return NULL; +} + +void ril_request_sim_io_info_clear(struct ril_request_sim_io_info *sim_io) +{ +	if (sim_io == NULL) +		return; + +	if (sim_io->data != NULL) +		free(sim_io->data); +} + +void ril_request_sim_io_next(void) +{ +	struct ril_request_sim_io_info *sim_io; +	unsigned char command; +	unsigned short fileid; +	unsigned char p1; +	unsigned char p2; +	unsigned char p3; +	void *data; +	int length; +	RIL_Token t; +	int rc; + +	ril_data.tokens.sim_io = (RIL_Token) 0x00; + +	sim_io = ril_request_sim_io_info_find(); +	if (sim_io == NULL) +		return; + +	command = sim_io->command; +	fileid = sim_io->fileid; +	p1 = sim_io->p1; +	p2 = sim_io->p2; +	p3 = sim_io->p3; +	data = sim_io->data; +	length = sim_io->length; +	t = sim_io->token; + +	ril_request_sim_io_unregister(sim_io); + +	ril_data.tokens.sim_io = t; + +	ril_request_sim_io_complete(t, command, fileid, p1, p2, p3, data, length); +	if (data != NULL) +		free(data); +} + +void ril_request_sim_io_complete(RIL_Token t, unsigned char command, unsigned short fileid, +	unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length) +{ +	struct ipc_sec_rsim_access_get *rsim_access = NULL; +	void *rsim_access_data = NULL; +	int rsim_access_length = 0; + +	rsim_access_length += sizeof(struct ipc_sec_rsim_access_get); + +	if (data != NULL && length > 0) +		rsim_access_length += length; + +	rsim_access_data = calloc(1, rsim_access_length); +	rsim_access = (struct ipc_sec_rsim_access_get *) rsim_access_data; + +	rsim_access->command = command; +	rsim_access->fileid = fileid; +	rsim_access->p1 = p1; +	rsim_access->p2 = p2; +	rsim_access->p3 = p3; + +	if (data != NULL && length > 0) +		memcpy((void *) ((int) rsim_access_data + sizeof(struct ipc_sec_rsim_access_get)), data, length); + +	ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, rsim_access_data, rsim_access_length, ril_request_get_id(t)); + +	free(rsim_access_data); +} +  /**   * In: RIL_REQUEST_SIM_IO   *   Request SIM I/O operation. @@ -333,12 +489,11 @@ void ril_request_sim_io(RIL_Token t, void *data, int length)  #else  	RIL_SIM_IO *sim_io = NULL;  #endif +	void *sim_io_data = NULL;  	int sim_io_data_length = 0; -	struct ipc_sec_rsim_access_get *rsim_access = NULL; -	void *rsim_access_data = NULL; -	int rsim_access_length = 0; +	int rc; -	if (data == NULL || length < sizeof(*sim_io)) +	if (data == NULL || length < (int) sizeof(*sim_io))  		return;  #if RIL_VERSION >= 6 @@ -347,28 +502,39 @@ void ril_request_sim_io(RIL_Token t, void *data, int length)  	sim_io = (RIL_SIM_IO *) data;  #endif -	rsim_access_length += sizeof(struct ipc_sec_rsim_access_get); - +	// SIM IO data should be a string if present  	if (sim_io->data != NULL) { -		sim_io_data_length = (2 * strlen(sim_io->data)); -		rsim_access_length += sim_io_data_length; +		sim_io_data_length = strlen(sim_io->data) / 2; +		if (sim_io_data_length > 0) { +			sim_io_data = calloc(1, sim_io_data_length); +			hex2bin(sim_io->data, sim_io_data_length * 2, sim_io_data); +		}  	} -	rsim_access_data = calloc(1, rsim_access_length); -	rsim_access = (struct ipc_sec_rsim_access_get *) rsim_access_data; +	if (ril_data.tokens.sim_io != (RIL_Token) 0x00) { +		LOGD("Another SIM I/O is being processed, adding to the list"); -	rsim_access->command = sim_io->command; -	rsim_access->fileid = sim_io->fileid; -	rsim_access->p1 = sim_io->p1; -	rsim_access->p2 = sim_io->p2; -	rsim_access->p3 = sim_io->p3; +		rc = ril_request_sim_io_register(t, sim_io->command, sim_io->fileid, +			sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length); +		if (rc < 0) { +			LOGE("Unable to add the request to the list"); -	if (sim_io->data != NULL && sim_io_data_length > 0) -		hex2bin(sim_io->data, sim_io_data_length, (void *) ((int) rsim_access_data + sizeof(struct ipc_sec_rsim_access_get))); +			ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); +			if (sim_io_data != NULL) +				free(sim_io_data); +			// Send the next SIM I/O in the list +			ril_request_sim_io_next(); +		} -	ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, rsim_access_data, rsim_access_length, ril_request_get_id(t)); +		return; +	} -	free(rsim_access_data); +	ril_data.tokens.sim_io = t; + +	ril_request_sim_io_complete(t, sim_io->command, sim_io->fileid, +		sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length); +	if (sim_io_data != NULL) +		free(sim_io_data);  }  /** @@ -410,6 +576,9 @@ void ipc_sec_rsim_access(struct ipc_message_info *info)  	ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &sim_io_response, sizeof(sim_io_response));  	free(sim_io_response.simResponse); + +	// Send the next SIM I/O in the list +	ril_request_sim_io_next();  }  /**  | 
