diff options
-rw-r--r-- | gen.c | 161 | ||||
-rw-r--r-- | samsung-ril.c | 1 | ||||
-rw-r--r-- | samsung-ril.h | 21 |
3 files changed, 104 insertions, 79 deletions
@@ -25,13 +25,6 @@ #include "util.h" /** - * GEN global vars - */ - -struct ipc_gen_phone_res_expect ipc_gen_phone_res_expects[0x20]; -int ipc_gen_phone_res_id = 0; - -/** * IPC_GEN_PHONE_RES has shared aseq (in the header), group, index and type (in the data) * with the original request it responds to. * On this implementation, we just check aseq and command (group and index). @@ -57,70 +50,95 @@ int ipc_gen_phone_res_id = 0; * GEN expects functions */ -void ipc_gen_phone_res_expects_init(void) +int ipc_gen_phone_res_expect_register(unsigned char aseq, unsigned short command, + void (*func)(struct ipc_message_info *info), int complete, int abort) { - memset(ipc_gen_phone_res_expects, 0, sizeof(struct ipc_gen_phone_res_expect) * 0x20); -} + struct ipc_gen_phone_res_expect_info *expect; + struct list_head *list_end; + struct list_head *list; -int ipc_gen_phone_res_id_new(void) -{ - ipc_gen_phone_res_id++; - ipc_gen_phone_res_id %= 0x20; - return ipc_gen_phone_res_id; -} + expect = calloc(1, sizeof(struct ipc_gen_phone_res_expect_info)); + if(expect == NULL) + return -1; -int ipc_gen_phone_res_get_id(unsigned char aseq) -{ - int i; + expect->aseq = aseq; + expect->command = command; + expect->func = func; + expect->complete = complete; + expect->abort = abort; - for(i=0 ; i < 0x20 ; i++) - if(ipc_gen_phone_res_expects[i].aseq == aseq) - return i; + list_end = ril_data.generic_responses; + while(list_end != NULL && list_end->next != NULL) + list_end = list_end->next; - return -1; + list = list_head_alloc((void *) expect, list_end, NULL); + + if(ril_data.generic_responses == NULL) + ril_data.generic_responses = list; + + return 0; } -void ipc_gen_phone_res_clean_id(int id) +void ipc_gen_phone_res_expect_unregister(struct ipc_gen_phone_res_expect_info *expect) { - ipc_gen_phone_res_expects[id].aseq = 0; - ipc_gen_phone_res_expects[id].command = 0; - ipc_gen_phone_res_expects[id].func = NULL; - ipc_gen_phone_res_expects[id].to_complete = 0; - ipc_gen_phone_res_expects[id].to_abort = 0; + struct list_head *list; + + if(expect == NULL) + return; + + list = ril_data.generic_responses; + while(list != NULL) { + if(list->data == (void *) expect) { + memset(expect, 0, sizeof(struct ipc_gen_phone_res_expect_info)); + free(expect); + + if(list == ril_data.generic_responses) + ril_data.generic_responses = list->next; + + list_head_free(list); + + break; + } +list_continue: + list = list->next; + } } -void ipc_gen_phone_res_expect_to_func(unsigned char aseq, unsigned short command, - void (*func)(struct ipc_message_info *info)) +struct ipc_gen_phone_res_expect_info *ipc_gen_phone_res_expect_find_aseq(unsigned char aseq) { - int id = ipc_gen_phone_res_id_new(); + struct ipc_gen_phone_res_expect_info *expect; + struct list_head *list; + + list = ril_data.generic_responses; + while(list != NULL) { + expect = (struct ipc_gen_phone_res_expect_info *) list->data; + if(expect == NULL) + goto list_continue; + + if(expect->aseq == aseq) + return expect; - ipc_gen_phone_res_expects[id].aseq = aseq; - ipc_gen_phone_res_expects[id].command = command; - ipc_gen_phone_res_expects[id].func = func; - ipc_gen_phone_res_expects[id].to_complete = 0; - ipc_gen_phone_res_expects[id].to_abort = 0; +list_continue: + list = list->next; + } + + return NULL; } -void ipc_gen_phone_res_expect_to_complete(unsigned char aseq, unsigned short command) +int ipc_gen_phone_res_expect_to_func(unsigned char aseq, unsigned short command, + void (*func)(struct ipc_message_info *info)) { - int id = ipc_gen_phone_res_id_new(); - - ipc_gen_phone_res_expects[id].aseq = aseq; - ipc_gen_phone_res_expects[id].command = command; - ipc_gen_phone_res_expects[id].func = NULL; - ipc_gen_phone_res_expects[id].to_complete = 1; - ipc_gen_phone_res_expects[id].to_abort = 0; + return ipc_gen_phone_res_expect_register(aseq, command, func, 0, 0); } -void ipc_gen_phone_res_expect_to_abort(unsigned char aseq, unsigned short command) +int ipc_gen_phone_res_expect_to_complete(unsigned char aseq, unsigned short command) { - int id = ipc_gen_phone_res_id_new(); + return ipc_gen_phone_res_expect_register(aseq, command, NULL, 1, 0); +} - ipc_gen_phone_res_expects[id].aseq = aseq; - ipc_gen_phone_res_expects[id].command = command; - ipc_gen_phone_res_expects[id].func = NULL; - ipc_gen_phone_res_expects[id].to_complete = 0; - ipc_gen_phone_res_expects[id].to_abort = 1; +int ipc_gen_phone_res_expect_to_abort(unsigned char aseq, unsigned short command) +{ + return ipc_gen_phone_res_expect_register(aseq, command, NULL, 0, 1); } /** @@ -133,33 +151,38 @@ void ipc_gen_phone_res_expect_to_abort(unsigned char aseq, unsigned short comman */ void ipc_gen_phone_res(struct ipc_message_info *info) { - struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data; - int id = ipc_gen_phone_res_get_id(info->aseq); + struct ipc_gen_phone_res_expect_info *expect; + struct ipc_gen_phone_res *phone_res; RIL_Errno e; int rc; - // In this case, it can be a real error or we just didn't queue - if(id < 0) { + if(info->data == NULL || info->length < sizeof(struct ipc_gen_phone_res)) + return; + + phone_res = (struct ipc_gen_phone_res *) info->data; + expect = ipc_gen_phone_res_expect_find_aseq(info->aseq); + + if(expect == NULL) { LOGD("aseq: 0x%x not found in the IPC_GEN_PHONE_RES queue", info->aseq); return; } LOGD("aseq: 0x%x found in the IPC_GEN_PHONE_RES queue!", info->aseq); - if(ipc_gen_phone_res_expects[id].command != IPC_COMMAND(phone_res)) { + if(expect->command != IPC_COMMAND(phone_res)) { LOGE("IPC_GEN_PHONE_RES aseq (0x%x) doesn't match the queued one with command (0x%x)", - ipc_gen_phone_res_expects[id].aseq, ipc_gen_phone_res_expects[id].command); + expect->aseq, expect->command); - if(ipc_gen_phone_res_expects[id].func != NULL) { + if(expect->func != NULL) { LOGE("Not safe to run the custom function, reporting generic failure"); - ril_request_complete(ril_request_get_token(ipc_gen_phone_res_expects[id].aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + ril_request_complete(ril_request_get_token(expect->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + goto unregister; } } - if(ipc_gen_phone_res_expects[id].func != NULL) { - ipc_gen_phone_res_expects[id].func(info); - ipc_gen_phone_res_clean_id(id); - return; + if(expect->func != NULL) { + expect->func(info); + goto unregister; } rc = ipc_gen_phone_res_check(phone_res); @@ -168,11 +191,9 @@ void ipc_gen_phone_res(struct ipc_message_info *info) else e = RIL_E_SUCCESS; - if(ipc_gen_phone_res_expects[id].to_complete || (ipc_gen_phone_res_expects[id].to_abort && rc < 0)) { - ril_request_complete(ril_request_get_token(ipc_gen_phone_res_expects[id].aseq), e, NULL, 0); - ipc_gen_phone_res_clean_id(id); - return; - } + if(expect->complete || (expect->abort && e == RIL_E_GENERIC_FAILURE)) + ril_request_complete(ril_request_get_token(expect->aseq), e, NULL, 0); - ipc_gen_phone_res_clean_id(id); +unregister: + ipc_gen_phone_res_expect_unregister(expect); } diff --git a/samsung-ril.c b/samsung-ril.c index ab22f19..2eb738e 100644 --- a/samsung-ril.c +++ b/samsung-ril.c @@ -647,7 +647,6 @@ void ril_data_init(void) void ril_globals_init(void) { - ipc_gen_phone_res_expects_init(); ril_gprs_connections_init(); ril_request_sms_init(); ipc_sms_tpid_queue_init(); diff --git a/samsung-ril.h b/samsung-ril.h index 5049987..0c5cf35 100644 --- a/samsung-ril.h +++ b/samsung-ril.h @@ -173,6 +173,7 @@ struct ril_data { struct ril_state state; struct ril_tokens tokens; + struct list_head *generic_responses; struct list_head *requests; int request_id; @@ -195,19 +196,23 @@ void srs_dispatch(int fd, struct srs_message *message); /* GEN */ -struct ipc_gen_phone_res_expect { +struct ipc_gen_phone_res_expect_info { unsigned char aseq; unsigned short command; void (*func)(struct ipc_message_info *info); - int to_complete; - int to_abort; + int complete; + int abort; }; -void ipc_gen_phone_res_expects_init(void); -void ipc_gen_phone_res_expect_to_func(unsigned char aseq, unsigned short command, - void (*func)(struct ipc_message_info *info)); -void ipc_gen_phone_res_expect_to_complete(unsigned char aseq, unsigned short command); -void ipc_gen_phone_res_expect_to_abort(unsigned char aseq, unsigned short command); +int ipc_gen_phone_res_expect_register(unsigned char aseq, unsigned short command, + void (*func)(struct ipc_message_info *info), int complete, int abort); +void ipc_gen_phone_res_expect_unregister(struct ipc_gen_phone_res_expect_info *expect); +struct ipc_gen_phone_res_expect_info *ipc_gen_phone_res_expect_find_aseq(unsigned char aseq); +int ipc_gen_phone_res_expect_to_func(unsigned char aseq, unsigned short command, + void (*func)(struct ipc_message_info *info)); +int ipc_gen_phone_res_expect_to_complete(unsigned char aseq, unsigned short command); +int ipc_gen_phone_res_expect_to_abort(unsigned char aseq, unsigned short command); + void ipc_gen_phone_res(struct ipc_message_info *info); /* PWR */ |