summaryrefslogtreecommitdiffstats
path: root/client.c
diff options
context:
space:
mode:
authorPaulK <contact@paulk.fr>2011-12-21 21:54:03 +0100
committerPaulK <contact@paulk.fr>2011-12-21 21:54:03 +0100
commit0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752 (patch)
treedff5b107e7c51dcbb71d636fd6189d3570881a39 /client.c
parentcb295e0a15c8bc5087a542f25bc369aecbecde80 (diff)
downloadhardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.zip
hardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.tar.gz
hardware_ril_samsung-ril-0091ceae5f7cbeeb42e3b43de3dcf8e500fe8752.tar.bz2
RIL rework: multi-client, more stable, added GPLv3 copyright notice
Diffstat (limited to 'client.c')
-rw-r--r--client.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/client.c b/client.c
new file mode 100644
index 0000000..84cbbd5
--- /dev/null
+++ b/client.c
@@ -0,0 +1,187 @@
+/**
+ * This file is part of samsung-ril.
+ *
+ * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr>
+ *
+ * samsung-ril is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * samsung-ril is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <pthread.h>
+
+#define LOG_TAG "RIL"
+#include <utils/Log.h>
+
+#include "samsung-ril.h"
+
+/**
+ * RIL client functions
+ */
+
+struct ril_client *ril_client_new(struct ril_client_funcs *client_funcs)
+{
+ struct ril_client *ril_client;
+ int rc;
+
+ ril_client = malloc(sizeof(struct ril_client));
+ memset(ril_client, 0, sizeof(struct ril_client));
+
+ if(client_funcs->create)
+ ril_client->create = client_funcs->create;
+
+ if(client_funcs->destroy)
+ ril_client->destroy = client_funcs->destroy;
+
+ if(client_funcs->read_loop)
+ ril_client->read_loop = client_funcs->read_loop;
+
+ pthread_mutex_init(&(ril_client->mutex), NULL);
+
+ return ril_client;
+}
+
+int ril_client_free(struct ril_client *client)
+{
+ pthread_mutex_destroy(&(client->mutex));
+
+ free(client);
+ client = NULL;
+
+ return 0;
+}
+
+int ril_client_create(struct ril_client *client)
+{
+ int rc;
+ int c;
+
+ for(c = 5 ; c > 0 ; c--) {
+ LOGD("Creating RIL client inners, try #%d", 6-c);
+
+ rc = client->create(client);
+
+ if(rc < 0)
+ LOGD("RIL client inners creation failed!");
+ else
+ break;
+ }
+
+ if(c == 0) {
+ client->state = RIL_CLIENT_ERROR;
+ return -1;
+ }
+
+ client->state = RIL_CLIENT_CREATED;
+
+ return 0;
+}
+
+int ril_client_destroy(struct ril_client *client)
+{
+ int rc;
+ int c;
+
+ for(c = 5 ; c > 0 ; c--) {
+ LOGD("Destroying RIL client inners, try #%d", 6-c);
+
+ rc = client->destroy(client);
+
+ if(rc < 0)
+ LOGD("RIL client inners destroying failed!");
+ else
+ break;
+ }
+
+ if(c == 0) {
+ client->state = RIL_CLIENT_ERROR;
+ return -1;
+ }
+
+ client->state = RIL_CLIENT_DESTROYED;
+
+ return 0;
+}
+
+void *ril_client_thread(void *data)
+{
+ struct ril_client *client;
+ int rc;
+ int c;
+
+ if(data == NULL) {
+ LOGE("Data passed to thread is NULL!");
+
+ return 0;
+ }
+
+ client = (struct ipc_client *) data;
+
+ for(c = 5 ; c > 0 ; c--) {
+ client->state = RIL_CLIENT_READY;
+
+ rc = client->read_loop(client);
+
+ if(rc < 0) {
+ client->state = RIL_CLIENT_ERROR;
+
+ LOGE("There was an error with the read loop! Trying to destroy and recreate client object");
+
+ ril_client_destroy(client);
+ ril_client_create(client);
+
+ continue;
+ } else {
+ client->state = RIL_CLIENT_CREATED;
+
+ LOGD("read loop ended with no error!");
+ break;
+ }
+ }
+
+ if(c == 0) {
+ LOGE("FATAL: Main loop failed too many times.");
+ }
+
+ // We are destroying everything here
+
+ rc = ril_client_destroy(client);
+ if(rc < 0) {
+ LOGE("RIL client destroy failed!");
+ }
+
+ rc = ril_client_free(client);
+ if(rc < 0) {
+ LOGE("RIL client free failed!");
+ }
+
+ return 0;
+}
+
+int ril_client_thread_start(struct ril_client *client)
+{
+ pthread_attr_t attr;
+ int rc;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ rc = pthread_create(&(client->thread), &attr, ril_client_thread, (void *) client);
+
+ if(rc != 0) {
+ LOGE("pthread creation failed");
+ return -1;
+ }
+
+ return 0;
+}