GPRS: Use lists stored in ril_data instead of global table
authorPaul Kocialkowski <contact@paulk.fr>
Thu, 1 Nov 2012 14:38:36 +0000 (15:38 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Thu, 1 Nov 2012 14:38:36 +0000 (15:38 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
gprs.c
samsung-ril.c
samsung-ril.h

diff --git a/gprs.c b/gprs.c
index bac43a0..0e053c7 100644 (file)
--- a/gprs.c
+++ b/gprs.c
@@ -33,9 +33,6 @@
 #include "samsung-ril.h"
 #include "util.h"
 
-struct ril_gprs_connection **ril_gprs_connections;
-int ril_gprs_connections_count;
-
 #if RIL_VERSION >= 6
 RIL_DataCallFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
 #else
@@ -82,111 +79,155 @@ int ipc2ril_gprs_connection_active(unsigned char state)
        }
 }
 
-void ril_gprs_connections_init(void)
+int ril_gprs_connection_register(int cid)
 {
-       struct ipc_client_gprs_capabilities gprs_capabilities;
-       struct ipc_client *ipc_client;
-       int ril_gprs_connections_size = 0;
+       struct ril_gprs_connection *gprs_connection;
+       struct list_head *list_end;
+       struct list_head *list;
 
-       ipc_client = ((struct ipc_client_data *) ril_data.ipc_fmt_client->data)->ipc_client;
-       ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
+       gprs_connection = calloc(1, sizeof(struct ril_gprs_connection));
+       if(gprs_connection == NULL)
+               return -1;
 
-       ril_gprs_connections_size =
-               gprs_capabilities.cid_max * sizeof(struct ril_gprs_connection *);
+       gprs_connection->cid = cid;
 
-       ril_gprs_connections = (struct ril_gprs_connection **)
-               malloc(ril_gprs_connections_size);
-       memset((void *) ril_gprs_connections, 0, ril_gprs_connections_size);
+       list_end = ril_data.gprs_connections;
+       while(list_end != NULL && list_end->next != NULL)
+               list_end = list_end->next;
 
-       ril_gprs_connections_count = gprs_capabilities.cid_max;
+       list = list_head_alloc((void *) gprs_connection, list_end, NULL);
+
+       if(ril_data.gprs_connections == NULL)
+               ril_data.gprs_connections = list;
+
+       return 0;
 }
 
-int ril_gprs_connection_reg_id(void)
+void ril_gprs_connection_unregister(struct ril_gprs_connection *gprs_connection)
 {
-       struct ril_gprs_connection *gprs_connection;
-       int i;
+       struct list_head *list;
 
-       for(i=0 ; i < ril_gprs_connections_count ; i++) {
-               if(ril_gprs_connections[i] == NULL)
-                       return i;
-       }
+       if(gprs_connection == NULL)
+               return;
+
+       list = ril_data.gprs_connections;
+       while(list != NULL) {
+               if(list->data == (void *) gprs_connection) {
+                       memset(gprs_connection, 0, sizeof(struct ril_gprs_connection));
+                       free(gprs_connection);
 
-       LOGD("No room left for another GPRS connection, trying to clean one up");
+                       if(list == ril_data.gprs_connections)
+                               ril_data.gprs_connections = list->next;
 
-       // When all the slots are taken, see if some are in a non-working state
-       for(i=0 ; i < ril_gprs_connections_count ; i++) {
-               if(ril_gprs_connections[i]->enabled == 0) {
-                       ril_gprs_connection_del(ril_gprs_connections[i]);
+                       list_head_free(list);
 
-                       return i;
+                       break;
                }
+list_continue:
+               list = list->next;
        }
-
-       return -1;
 }
 
-struct ril_gprs_connection *ril_gprs_connection_add(void)
+struct ril_gprs_connection *ril_gprs_connection_find_cid(int cid)
 {
-       struct ril_gprs_connection *gprs_connection = NULL;
-       int id = ril_gprs_connection_reg_id();
-
-       if(id < 0) {
-               LOGE("Unable to add another GPRS connection!");
-               return NULL;
-       }
+       struct ril_gprs_connection *gprs_connection;
+       struct list_head *list;
 
-       gprs_connection = malloc(sizeof(struct ril_gprs_connection));
-       memset(gprs_connection, 0, sizeof(struct ril_gprs_connection));
+       list = ril_data.gprs_connections;
+       while(list != NULL) {
+               gprs_connection = (struct ril_gprs_connection *) list->data;
+               if(gprs_connection == NULL)
+                       goto list_continue;
 
-       gprs_connection->cid = id + 1;
-       gprs_connection->enabled = 0;
-       gprs_connection->interface = NULL;
-       gprs_connection->token = (RIL_Token) 0x00;
+               if(gprs_connection->cid == cid)
+                       return gprs_connection;
 
-       ril_gprs_connections[id] = gprs_connection;
+list_continue:
+               list = list->next;
+       }
 
-       return gprs_connection;
+       return NULL;
 }
 
-void ril_gprs_connection_del(struct ril_gprs_connection *gprs_connection)
+struct ril_gprs_connection *ril_gprs_connection_find_token(RIL_Token t)
 {
-       int i;
+       struct ril_gprs_connection *gprs_connection;
+       struct list_head *list;
 
-       if(gprs_connection == NULL)
-               return;
+       list = ril_data.gprs_connections;
+       while(list != NULL) {
+               gprs_connection = (struct ril_gprs_connection *) list->data;
+               if(gprs_connection == NULL)
+                       goto list_continue;
 
-       if(gprs_connection->interface != NULL)
-               free(gprs_connection->interface);
+               if(gprs_connection->token == t)
+                       return gprs_connection;
 
-       for(i=0 ; i < ril_gprs_connections_count ; i++)
-               if(ril_gprs_connections[i] == gprs_connection)
-                               ril_gprs_connections[i] = NULL;
+list_continue:
+               list = list->next;
+       }
 
-       free(gprs_connection);
+       return NULL;
 }
 
-struct ril_gprs_connection *ril_gprs_connection_get_token(RIL_Token token)
+struct ril_gprs_connection *ril_gprs_connection_start(void)
 {
+       struct ipc_client_gprs_capabilities gprs_capabilities;
+       struct ril_gprs_connection *gprs_connection;
+       struct ipc_client *ipc_client;
+       struct list_head *list;
+       int cid, cid_max;
+       int rc;
        int i;
 
-       for(i=0 ; i < ril_gprs_connections_count ; i++)
-               if(ril_gprs_connections[i] != NULL)
-                       if(ril_gprs_connections[i]->token == token)
-                               return ril_gprs_connections[i];
+       ipc_client = ((struct ipc_client_data *) ril_data.ipc_fmt_client->data)->ipc_client;
+       ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
+       cid_max = gprs_capabilities.cid_max;
+
+       for(i=0 ; i < cid_max ; i++) {
+               cid = i + 1;
+               list = ril_data.gprs_connections;
+               while(list != NULL) {
+                       if(list->data == NULL)
+                               goto list_continue;
+
+                       gprs_connection = (struct ril_gprs_connection *) list->data;
+                       if(gprs_connection->cid == cid) {
+                               cid = 0;
+                               break;
+                       }
 
-       return NULL;
+list_continue:
+                       list = list->next;
+               }
+
+               if(cid > 0)
+                       break;
+       }
+
+       if(cid <= 0) {
+               LOGE("Unable to find an unused cid, aborting");
+               return NULL;
+       }
+
+       LOGD("Using GPRS connection cid: %d", cid);
+       rc = ril_gprs_connection_register(cid);
+       if(rc < 0)
+               return NULL;
+
+       gprs_connection = ril_gprs_connection_find_cid(cid);
+       return gprs_connection;
 }
 
-struct ril_gprs_connection *ril_gprs_connection_get_cid(int cid)
+void ril_gprs_connection_stop(struct ril_gprs_connection *gprs_connection)
 {
-       int i;
+       if(gprs_connection == NULL)
+               return;
 
-       for(i=0 ; i < ril_gprs_connections_count ; i++)
-               if(ril_gprs_connections[i] != NULL)
-                       if(ril_gprs_connections[i]->cid == cid)
-                               return ril_gprs_connections[i];
+       if(gprs_connection->interface != NULL)
+               free(gprs_connection->interface);
 
-       return NULL;
+       ril_gprs_connection_unregister(gprs_connection);
 }
 
 void ipc_gprs_pdp_context_enable_complete(struct ipc_message_info *info)
@@ -195,7 +236,7 @@ void ipc_gprs_pdp_context_enable_complete(struct ipc_message_info *info)
        struct ril_gprs_connection *gprs_connection;
        int rc;
 
-       gprs_connection = ril_gprs_connection_get_token(ril_request_get_token(info->aseq));
+       gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -229,7 +270,7 @@ void ipc_gprs_define_pdp_context_complete(struct ipc_message_info *info)
        int aseq;
        int rc;
 
-       gprs_connection = ril_gprs_connection_get_token(ril_request_get_token(info->aseq));
+       gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -274,7 +315,7 @@ void ipc_gprs_port_list_complete(struct ipc_message_info *info)
        int rc;
        int aseq;
 
-       gprs_connection = ril_gprs_connection_get_token(ril_request_get_token(info->aseq));
+       gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -330,7 +371,7 @@ void ril_request_setup_data_call(RIL_Token t, void *data, int length)
 
        LOGD("Requesting data connection to APN '%s'\n", apn);
 
-       gprs_connection = ril_gprs_connection_add();
+       gprs_connection = ril_gprs_connection_start();
 
        if(!gprs_connection) {
                LOGE("Unable to create GPRS connection, aborting");
@@ -376,7 +417,7 @@ void ipc_gprs_ip_configuration(struct ipc_message_info *info)
         struct ipc_gprs_ip_configuration *ip_configuration =
                (struct ipc_gprs_ip_configuration *) info->data;
 
-       gprs_connection = ril_gprs_connection_get_cid(ip_configuration->cid);
+       gprs_connection = ril_gprs_connection_find_cid(ip_configuration->cid);
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -401,7 +442,7 @@ void ipc_gprs_pdp_context_disable_complete(struct ipc_message_info *info)
        struct ril_gprs_connection *gprs_connection;
        int rc;
 
-       gprs_connection = ril_gprs_connection_get_token(ril_request_get_token(info->aseq));
+       gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -416,7 +457,7 @@ void ipc_gprs_pdp_context_disable_complete(struct ipc_message_info *info)
                LOGE("There was an error, aborting PDP context complete");
 
                // RILJ is not going to ask for fail reason
-               ril_gprs_connection_del(gprs_connection);
+               ril_gprs_connection_stop(gprs_connection);
 
                ril_request_complete(ril_request_get_token(info->aseq),
                        RIL_E_GENERIC_FAILURE, NULL, 0);
@@ -434,7 +475,7 @@ void ril_request_deactivate_data_call(RIL_Token t, void *data, int length)
        char *cid = ((char **) data)[0];
        int rc;
 
-       gprs_connection = ril_gprs_connection_get_cid(atoi(cid));
+       gprs_connection = ril_gprs_connection_find_cid(atoi(cid));
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -672,7 +713,7 @@ void ipc_gprs_call_status(struct ipc_message_info *info)
 
        int rc;
 
-       gprs_connection = ril_gprs_connection_get_cid(call_status->cid);
+       gprs_connection = ril_gprs_connection_find_cid(call_status->cid);
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection, aborting");
@@ -732,7 +773,7 @@ void ipc_gprs_call_status(struct ipc_message_info *info)
                                        RIL_E_GENERIC_FAILURE, NULL, 0);
 
                                // RILJ is not going to ask for fail reason
-                               ril_gprs_connection_del(gprs_connection);
+                               ril_gprs_connection_stop(gprs_connection);
                        } else {
                                LOGD("GPRS interface disabled");
 
@@ -741,7 +782,7 @@ void ipc_gprs_call_status(struct ipc_message_info *info)
                                ril_request_complete(gprs_connection->token,
                                        RIL_E_SUCCESS, NULL, 0);
 
-                               ril_gprs_connection_del(gprs_connection);
+                               ril_gprs_connection_stop(gprs_connection);
                        }
                } else {
                        LOGE("GPRS connection reported as changed though state is not OK:"
@@ -776,12 +817,12 @@ void ipc_gprs_call_status(struct ipc_message_info *info)
                                LOGE("Failed to disable GPRS interface");
 
                                // RILJ is not going to ask for fail reason
-                               ril_gprs_connection_del(gprs_connection);
+                               ril_gprs_connection_stop(gprs_connection);
                        } else {
                                LOGE("GPRS interface disabled");
 
                                gprs_connection->enabled = 0;
-                               ril_gprs_connection_del(gprs_connection);
+                               ril_gprs_connection_stop(gprs_connection);
                        }
 
                        ril_unsol_data_call_list_changed();
@@ -809,7 +850,7 @@ void ril_request_last_data_call_fail_cause(RIL_Token t)
                goto fail_cause_unspecified;
        }
 
-       gprs_connection = ril_gprs_connection_get_cid(last_failed_cid);
+       gprs_connection = ril_gprs_connection_find_cid(last_failed_cid);
 
        if(!gprs_connection) {
                LOGE("Unable to find GPRS connection");
@@ -820,7 +861,7 @@ void ril_request_last_data_call_fail_cause(RIL_Token t)
        fail_cause = gprs_connection->fail_cause;
 
        LOGD("Destroying GPRS connection with cid: %d", gprs_connection->cid);
-       ril_gprs_connection_del(gprs_connection);
+       ril_gprs_connection_stop(gprs_connection);
 
        goto fail_cause_return;
 
@@ -885,7 +926,7 @@ void ipc_gprs_pdp_context(struct ipc_message_info *info)
                        ipc2ril_gprs_connection_active(context->desc[i].state);
 
                if(context->desc[i].state == IPC_GPRS_STATE_ENABLED) {
-                       gprs_connection = ril_gprs_connection_get_cid(context->desc[i].cid);
+                       gprs_connection = ril_gprs_connection_find_cid(context->desc[i].cid);
 
                        if(gprs_connection == NULL) {
                                LOGE("CID %d reported as enabled but not listed here",
index 2eb738e..cf4f380 100644 (file)
@@ -147,7 +147,7 @@ struct ril_request_info *ril_request_info_find_token(RIL_Token t)
 
        list = ril_data.requests;
        while(list != NULL) {
-               request = list->data;
+               request = (struct ril_request_info *) list->data;
                if(request == NULL)
                        goto list_continue;
 
@@ -647,7 +647,6 @@ void ril_data_init(void)
 
 void ril_globals_init(void)
 {
-       ril_gprs_connections_init();
        ril_request_sms_init();
        ipc_sms_tpid_queue_init();
 }
index 0c5cf35..9219a2b 100644 (file)
@@ -173,6 +173,7 @@ struct ril_data {
 
        struct ril_state state;
        struct ril_tokens tokens;
+       struct list_head *gprs_connections;
        struct list_head *generic_responses;
        struct list_head *requests;
        int request_id;
@@ -368,10 +369,13 @@ struct ril_gprs_connection {
        struct ipc_gprs_ip_configuration ip_configuration;
 };
 
-void ril_gprs_connections_init(void);
-int ril_gprs_connection_reg_id(void);
-struct ril_gprs_connection *ril_gprs_connection_add(void);
-void ril_gprs_connection_del(struct ril_gprs_connection *gprs_connection);
+int ril_gprs_connection_register(int cid);
+void ril_gprs_connection_unregister(struct ril_gprs_connection *gprs_connection);
+struct ril_gprs_connection *ril_gprs_connection_find_cid(int cid);
+struct ril_gprs_connection *ril_gprs_connection_find_token(RIL_Token t);
+struct ril_gprs_connection *ril_gprs_connection_start(void);
+void ril_gprs_connection_stop(struct ril_gprs_connection *gprs_connection);
+
 void ril_request_setup_data_call(RIL_Token t, void *data, int length);
 void ril_request_deactivate_data_call(RIL_Token t, void *data, int length);
 void ipc_gprs_ip_configuration(struct ipc_message_info *info);