summaryrefslogtreecommitdiffstats
path: root/ipc.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 /ipc.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 'ipc.c')
-rw-r--r--ipc.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/ipc.c b/ipc.c
new file mode 100644
index 0000000..8bfeafc
--- /dev/null
+++ b/ipc.c
@@ -0,0 +1,216 @@
+/**
+ * This file is part of samsung-ril.
+ *
+ * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
+ * 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/>.
+ *
+ */
+
+#define LOG_TAG "RIL-IPC"
+#include <utils/Log.h>
+
+#include "samsung-ril.h"
+#include <radio.h>
+
+void ipc_log_handler(const char *message, void *user_data)
+{
+ LOGD("ipc: %s", message);
+}
+
+void ipc_fmt_send(const unsigned short command, const char type, unsigned char *data, const int length, unsigned char mseq)
+{
+ struct ipc_client *ipc_client;
+
+ if(ipc_fmt_client == NULL) {
+ LOGE("ipc_fmt_client is null, aborting!");
+ return;
+ }
+
+ if(ipc_fmt_client->object == NULL) {
+ LOGE("ipc_fmt_client object is null, aborting!");
+ return;
+ }
+
+ ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
+
+ pthread_mutex_lock(&(ipc_fmt_client->mutex));
+ ipc_client_send(ipc_client, command, type, data, length, mseq);
+ pthread_mutex_unlock(&(ipc_fmt_client->mutex));
+}
+
+int ipc_fmt_read_loop(struct ril_client *client)
+{
+ struct ipc_message_info info;
+ struct ipc_client *ipc_client;
+ int ipc_client_fd;
+ fd_set fds;
+
+ if(client == NULL) {
+ LOGE("client is NULL, aborting!");
+ return -1;
+ }
+
+ if(client->object == NULL) {
+ LOGE("client object is NULL, aborting!");
+ return -1;
+ }
+
+ ipc_client = ((struct ipc_client_object *) client->object)->ipc_client;
+ ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd;
+
+ FD_ZERO(&fds);
+ FD_SET(ipc_client_fd, &fds);
+
+ while(1) {
+ if(ipc_client_fd < 0) {
+ LOGE("IPC FMT client fd is negative, aborting!");
+ return -1;
+ }
+
+ select(FD_SETSIZE, &fds, NULL, NULL, NULL);
+
+ if(FD_ISSET(ipc_client_fd, &fds)) {
+ if(ipc_client_recv(ipc_client, &info)) {
+ LOGE("IPC FMT recv failed, aborting!");
+ return -1;
+ }
+ LOGD("IPC FMT recv: aseq=0x%x mseq=0x%x data_length=%d\n", info.aseq, info.mseq, info.length);
+
+ ipc_fmt_dispatch(&info);
+
+ if(info.data != NULL)
+ free(info.data);
+ }
+ }
+
+ return 0;
+}
+
+int ipc_fmt_create(struct ril_client *client)
+{
+ struct ipc_client_object *client_object;
+ struct ipc_client *ipc_client;
+ int ipc_client_fd;
+ int rc;
+
+ client_object = malloc(sizeof(struct ipc_client_object));
+ memset(client_object, 0, sizeof(struct ipc_client_object));
+ client_object->ipc_client_fd = -1;
+
+ client->object = client_object;
+
+ ipc_client = (struct ipc_client *) client_object->ipc_client;
+
+ LOGD("Creating new FMT client");
+ ipc_client = ipc_client_new(IPC_CLIENT_TYPE_FMT);
+
+ if(ipc_client == NULL) {
+ LOGE("FMT client creation failed!");
+ return -1;
+ }
+
+ client_object->ipc_client = ipc_client;
+
+ LOGD("Setting log handler");
+ rc = ipc_client_set_log_handler(ipc_client, ipc_log_handler, NULL);
+
+ if(rc < 0) {
+ LOGE("Setting log handler failed!");
+ return -1;
+ }
+
+ //FIXME: ipc_client_set_handler
+
+ LOGD("Passing client->object->ipc_client fd as handlers data");
+ rc = ipc_client_set_all_handlers_data(ipc_client, &((struct ipc_client_object *) client->object)->ipc_client_fd);
+
+ if(rc < 0) {
+ LOGE("ipc_client_fd as handlers data failed!");
+ return -1;
+ }
+
+
+ LOGD("Starting modem bootstrap");
+ rc = ipc_client_bootstrap_modem(ipc_client);
+
+ if(rc < 0) {
+ LOGE("Modem bootstrap failed!");
+ return -1;
+ }
+
+ LOGD("Client open...");
+ if(ipc_client_open(ipc_client)) {
+ LOGE("%s: failed to open ipc client", __FUNCTION__);
+ return -1;
+ }
+
+ ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd;
+
+ if(ipc_client_fd < 0) {
+ LOGE("%s: client_fmt_fd is negative, aborting", __FUNCTION__);
+ return -1;
+ }
+
+ LOGD("Client power on...");
+ if(ipc_client_power_on(ipc_client)) {
+ LOGE("%s: failed to power on ipc client", __FUNCTION__);
+ return -1;
+ }
+
+ return 0;
+}
+
+int ipc_fmt_destroy(struct ril_client *client)
+{
+ struct ipc_client *ipc_client;
+ int ipc_client_fd;
+ int rc;
+
+ LOGD("Destrying ipc fmt client");
+
+ if(client == NULL) {
+ LOGE("client was already destroyed");
+ return 0;
+ }
+
+ if(client->object == NULL) {
+ LOGE("client object was already destroyed");
+ return 0;
+ }
+
+ ipc_client_fd = ((struct ipc_client_object *) client->object)->ipc_client_fd;
+
+ if(ipc_client_fd)
+ close(ipc_client_fd);
+
+ ipc_client = ((struct ipc_client_object *) client->object)->ipc_client;
+
+ if(ipc_client != NULL) {
+ ipc_client_power_off(ipc_client);
+ ipc_client_close(ipc_client);
+ ipc_client_free(ipc_client);
+ }
+
+ free(client->object);
+
+ return 0;
+}
+
+struct ril_client_funcs ipc_fmt_client_funcs = {
+ .create = ipc_fmt_create,
+ .destroy = ipc_fmt_destroy,
+ .read_loop = ipc_fmt_read_loop,
+};