summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2013-03-07 14:41:30 +0100
committerPaul Kocialkowski <contact@paulk.fr>2013-03-07 14:41:30 +0100
commit8507877c6dba1cca27268dc4e8079b4a96da51a9 (patch)
treeb64b7336a830478e739fb37d5b9254d5b83cc43d
parent0d0f2ab21d3d26bc8a5d04a4b7a717763382e855 (diff)
downloadhardware_replicant_libsamsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.tar.gz
hardware_replicant_libsamsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.tar.bz2
hardware_replicant_libsamsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.zip
SRS: srs-client library, proper structures for protocol data
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rw-r--r--Android.mk18
-rw-r--r--include/samsung-ril-socket.h29
-rw-r--r--srs-client/include/srs-client.h60
-rw-r--r--srs-client/srs-client.c365
-rw-r--r--srs.c24
5 files changed, 475 insertions, 21 deletions
diff --git a/Android.mk b/Android.mk
index 78e9a5f..6e8539e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,7 +17,7 @@
# along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
#
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -113,3 +113,19 @@ else
LOCAL_MODULE:= samsung-ril
include $(BUILD_EXECUTABLE)
endif
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := srs-client/srs-client.c
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/srs-client/include \
+
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libsrs-client
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/include/samsung-ril-socket.h b/include/samsung-ril-socket.h
index c7b5e0d..59be2f2 100644
--- a/include/samsung-ril-socket.h
+++ b/include/samsung-ril-socket.h
@@ -40,6 +40,19 @@
#define SRS_CONTROL_CAFFE 0xCAFFE
+struct srs_header {
+ unsigned int length;
+ unsigned char group;
+ unsigned char index;
+} __attribute__((__packed__));
+
+struct srs_message {
+ unsigned short command;
+ int length;
+ void *data;
+};
+
+
enum srs_snd_type {
SRS_SND_TYPE_VOICE,
SRS_SND_TYPE_SPEAKER,
@@ -66,16 +79,16 @@ struct srs_snd_call_volume {
int volume;
} __attribute__((__packed__));
-struct srs_header {
- unsigned int length;
- unsigned char group;
- unsigned char index;
+struct srs_snd_call_audio_path {
+ enum srs_snd_path path;
} __attribute__((__packed__));
-struct srs_message {
- unsigned short command;
- int data_len;
- void *data;
+struct srs_snd_call_clock_sync {
+ unsigned char sync;
+} __attribute__((__packed__));
+
+struct srs_control_ping {
+ int caffe;
} __attribute__((__packed__));
#endif
diff --git a/srs-client/include/srs-client.h b/srs-client/include/srs-client.h
new file mode 100644
index 0000000..b98e5e9
--- /dev/null
+++ b/srs-client/include/srs-client.h
@@ -0,0 +1,60 @@
+/**
+ * This file is part of samsung-ril.
+ *
+ * Copyright (C) 2013 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>
+
+#include <samsung-ril-socket.h>
+
+#ifndef _SRS_CLIENT_H_
+#define _SRS_CLIENT_H_
+
+#define SRS_CLIENT_TIMEOUT 500000
+
+#define SRS_CLIENT_LOCK(client) pthread_mutex_lock(&(client->mutex))
+#define SRS_CLIENT_UNLOCK(client) pthread_mutex_unlock(&(client->mutex))
+
+typedef void (*srs_client_thread_cb)(struct srs_message *message);
+
+struct srs_client {
+ int fd;
+
+ pthread_mutex_t mutex;
+ pthread_t thread;
+ int thread_run;
+
+ srs_client_thread_cb thread_cb;
+};
+
+int srs_client_recv_message(struct srs_client *client, struct srs_message *message);
+int srs_client_send_message(struct srs_client *client, struct srs_message *message);
+int srs_client_send(struct srs_client *client, unsigned short command, void *data, int length);
+
+int srs_client_open(struct srs_client *client);
+int srs_client_close(struct srs_client *client);
+int srs_client_create(struct srs_client **client_p);
+int srs_client_destroy(struct srs_client *client);
+
+int srs_client_thread_start(struct srs_client *client,
+ srs_client_thread_cb cb);
+int srs_client_thread_stop(struct srs_client *client);
+
+int srs_client_ping(struct srs_client *client);
+
+#endif
diff --git a/srs-client/srs-client.c b/srs-client/srs-client.c
new file mode 100644
index 0000000..dd408eb
--- /dev/null
+++ b/srs-client/srs-client.c
@@ -0,0 +1,365 @@
+/**
+ * This file is part of samsung-ril.
+ *
+ * Copyright (C) 2013 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/select.h>
+
+#include <signal.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <cutils/sockets.h>
+
+#include <telephony/ril.h>
+
+#include <samsung-ril-socket.h>
+#include <srs-client.h>
+
+/*
+ * SRS Client fops
+ */
+
+int srs_client_recv_message(struct srs_client *client, struct srs_message *message)
+{
+ struct srs_header *header_p;
+ struct srs_header header;
+ void *data = NULL;
+ int length = 0;
+
+ struct timeval timeout;
+ fd_set fds;
+ int rc;
+
+ if (client == NULL || message == NULL || client->fd < 0)
+ return -EINVAL;
+
+ memset(message, 0, sizeof(struct srs_message));
+ memset(&header, 0, sizeof(header));
+
+ timeout.tv_sec = (SRS_CLIENT_TIMEOUT - SRS_CLIENT_TIMEOUT % 1000000) / 1000000;
+ timeout.tv_usec = SRS_CLIENT_TIMEOUT % 1000000;
+
+ FD_ZERO(&fds);
+ FD_SET(client->fd, &fds);
+
+ rc = select(client->fd + 1, &fds, NULL, NULL, &timeout);
+ if (rc == 0) {
+ rc = 0;
+ goto done;
+ } else if (rc < 0 || !FD_ISSET(client->fd, &fds))
+ goto error;
+
+ SRS_CLIENT_LOCK(client);
+ rc = read(client->fd, &header, sizeof(header));
+ SRS_CLIENT_UNLOCK(client);
+
+ if (rc != sizeof(header))
+ goto error;
+
+ header_p = &header;
+ message->command = SRS_COMMAND(header_p);
+
+ length = header.length - sizeof(header);
+ if (length > 0) {
+ data = calloc(1, length);
+ if (data == NULL)
+ goto error;
+
+ FD_ZERO(&fds);
+ FD_SET(client->fd, &fds);
+
+ rc = select(client->fd + 1, &fds, NULL, NULL, &timeout);
+ if (rc <= 0 || !FD_ISSET(client->fd, &fds))
+ goto error;
+
+ SRS_CLIENT_LOCK(client);
+ rc = read(client->fd, data, length);
+ SRS_CLIENT_UNLOCK(client);
+
+ if (rc != length)
+ goto error;
+
+ message->data = data;
+ message->length = length;
+ }
+
+ rc = header.length;
+ goto done;
+
+error:
+ rc = -1;
+
+ if (data != NULL)
+ free(data);
+
+done:
+ return rc;
+}
+
+int srs_client_send_message(struct srs_client *client, struct srs_message *message)
+{
+ struct srs_header header;
+ unsigned char *p = NULL;
+ void *data = NULL;
+ int length = 0;
+
+ struct timeval timeout;
+ fd_set fds;
+ int rc;
+
+ if (client == NULL || message == NULL || client->fd < 0)
+ return -EINVAL;
+
+ memset(&header, 0, sizeof(header));
+ header.length = message->length + sizeof(header);
+ header.group = SRS_GROUP(message->command);
+ header.index = SRS_INDEX(message->command);
+
+ length = header.length;
+ data = calloc(1, length);
+ if (data == NULL)
+ goto error;
+
+ p = (unsigned char *) data;
+ memcpy(p, &header, sizeof(header));
+ p += sizeof(header);
+ if (message->data != NULL && message->length > 0) {
+ memcpy(p, message->data, message->length);
+ p += message->length;
+ }
+
+ timeout.tv_sec = (SRS_CLIENT_TIMEOUT - SRS_CLIENT_TIMEOUT % 1000000) / 1000000;
+ timeout.tv_usec = SRS_CLIENT_TIMEOUT % 1000000;
+
+ FD_ZERO(&fds);
+ FD_SET(client->fd, &fds);
+
+ rc = select(client->fd + 1, NULL, &fds, NULL, &timeout);
+ if (rc <= 0 || !FD_ISSET(client->fd, &fds))
+ goto error;
+
+ SRS_CLIENT_LOCK(client);
+ rc = write(client->fd, data, length);
+ SRS_CLIENT_UNLOCK(client);
+
+ if (rc != length)
+ goto error;
+
+ rc = length;
+ goto done;
+
+error:
+ rc = -1;
+
+done:
+ if (data != NULL)
+ free(data);
+
+ return rc;
+}
+
+int srs_client_send(struct srs_client *client, unsigned short command, void *data, int length)
+{
+ struct srs_message message;
+
+ memset(&message, 0, sizeof(message));
+ message.command = command;
+ message.data = data;
+ message.length = length;
+
+ return srs_client_send_message(client, &message);
+}
+
+int srs_client_open(struct srs_client *client)
+{
+ int fd;
+
+ if (client == NULL)
+ return -EINVAL;
+#if RIL_VERSION >= 6
+ fd = socket_local_client(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+#else
+ fd = socket_local_client(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+#endif
+ if (fd < 0) {
+ client->fd = -1;
+ return -1;
+ }
+
+ client->fd = fd;
+ return 0;
+}
+
+int srs_client_close(struct srs_client *client)
+{
+ if (client == NULL || client->fd < 0)
+ return -EINVAL;
+
+ close(client->fd);
+ client->fd = -1;
+
+ return 0;
+}
+
+int srs_client_create(struct srs_client **client_p)
+{
+ struct srs_client *client;
+
+ if (client_p == NULL)
+ return -EINVAL;
+
+ client = calloc(1, sizeof(struct srs_client));
+ if (client == NULL) {
+ *client_p = NULL;
+ return -1;
+ }
+
+ client->fd = -1;
+ pthread_mutex_init(&(client->mutex), NULL);
+
+ *client_p = client;
+
+ return 0;
+}
+
+int srs_client_destroy(struct srs_client *client)
+{
+ if (client == NULL)
+ return -EINVAL;
+
+ pthread_mutex_destroy(&(client->mutex));
+
+ free(client);
+
+ return 0;
+}
+
+/*
+ * SRS Client thread
+ */
+
+void *srs_client_thread(void *data)
+{
+ struct srs_message message;
+ struct srs_client *client;
+ int rc;
+
+ if (data == NULL)
+ return NULL;
+
+ client = (struct srs_client *) data;
+
+ if (client->thread_cb == NULL)
+ goto done;
+
+ while (client->thread_run) {
+ rc = srs_client_recv_message(client, &message);
+ if (rc < 0)
+ goto done;
+
+ client->thread_cb(&message);
+ }
+
+done:
+ client->thread_run = 0;
+
+ return NULL;
+}
+
+int srs_client_thread_start(struct srs_client *client,
+ srs_client_thread_cb cb)
+{
+ pthread_attr_t attr;
+ int rc;
+
+ if (client == NULL || cb == NULL)
+ return -EINVAL;
+
+ client->thread_cb = cb;
+ client->thread_run = 1;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ rc = pthread_create(&(client->thread), &attr, srs_client_thread, (void *) client);
+ if (rc != 0)
+ return -1;
+
+ return 0;
+}
+
+int srs_client_thread_stop(struct srs_client *client)
+{
+ if (client == NULL)
+ return -EINVAL;
+
+ client->thread_run = 0;
+
+ return 0;
+}
+
+/*
+ * SRS Client inline
+ */
+
+int srs_client_ping(struct srs_client *client)
+{
+ struct srs_message message;
+ struct srs_control_ping ping;
+ struct srs_control_ping *ping_p;
+ int rc;
+
+ if (client == NULL)
+ return -1;
+
+ memset(&message, 0, sizeof(message));
+
+ ping.caffe = SRS_CONTROL_CAFFE;
+ rc = srs_client_send(client, SRS_CONTROL_PING, &ping, sizeof(ping));
+ if (rc < 0)
+ goto error;
+
+ rc = srs_client_recv_message(client, &message);
+ if (rc < 0 || message.length <= 0 || message.data == NULL)
+ goto error;
+
+ ping_p = (struct srs_control_ping *) message.data;
+ if (ping_p->caffe != SRS_CONTROL_CAFFE)
+ goto error;
+
+ rc = 0;
+ goto done;
+
+error:
+ rc = -1;
+
+done:
+ if (message.data != NULL)
+ free(message.data);
+
+ return rc;
+}
diff --git a/srs.c b/srs.c
index 38b74d7..3a32b5a 100644
--- a/srs.c
+++ b/srs.c
@@ -195,7 +195,7 @@ int srs_client_send_message(struct srs_client_data *client_data, struct srs_mess
return -1;
memset(&header, 0, sizeof(header));
- header.length = message->data_len + sizeof(header);
+ header.length = message->length + sizeof(header);
header.group = SRS_GROUP(message->command);
header.index = SRS_INDEX(message->command);
@@ -204,7 +204,7 @@ int srs_client_send_message(struct srs_client_data *client_data, struct srs_mess
return -1;
memcpy(data, &header, sizeof(header));
- memcpy((void *) ((char *) data + sizeof(header)), message->data, message->data_len);
+ memcpy((void *) ((char *) data + sizeof(header)), message->data, message->length);
memset(&timeout, 0, sizeof(timeout));
timeout.tv_usec = 300;
@@ -248,7 +248,7 @@ int srs_client_send(struct srs_client_data *client_data, unsigned short command,
memset(&message, 0, sizeof(message));
message.command = command;
message.data = data;
- message.data_len = length;
+ message.length = length;
RIL_CLIENT_LOCK(client_data->client);
rc = srs_client_send_message(client_data, &message);
@@ -277,7 +277,7 @@ int srs_send(unsigned short command, void *data, int length)
client_data = (struct srs_client_data *) ril_data.srs_client->data;
- LOGD("SEND SRS: fd=%d command=%d data_len=%d", client_data->client_fd, command, length);
+ LOGD("SEND SRS: fd=%d command=%d length=%d", client_data->client_fd, command, length);
if (data != NULL && length > 0) {
LOGD("==== SRS DATA DUMP ====");
hex_dump(data, length);
@@ -329,10 +329,10 @@ int srs_client_recv(struct srs_client_data *client_data, struct srs_message *mes
memset(message, 0, sizeof(struct srs_message));
message->command = SRS_COMMAND(header);
- message->data_len = header->length - sizeof(struct srs_header);
- if (message->data_len > 0) {
- message->data = calloc(1, message->data_len);
- memcpy(message->data, (void *) ((char *) data + sizeof(struct srs_header)), message->data_len);
+ message->length = header->length - sizeof(struct srs_header);
+ if (message->length > 0) {
+ message->data = calloc(1, message->length);
+ memcpy(message->data, (void *) ((char *) data + sizeof(struct srs_header)), message->length);
} else {
message->data = NULL;
}
@@ -349,7 +349,7 @@ void srs_control_ping(struct srs_message *message)
{
int caffe;
- if (message == NULL || message->data == NULL || message->data_len < (int) sizeof(int))
+ if (message == NULL || message->data == NULL || message->length < (int) sizeof(int))
return;
caffe=*((int *) message->data);
@@ -430,10 +430,10 @@ void *srs_client_read_loop(void *data)
}
RIL_CLIENT_UNLOCK(client_data->client);
- LOGD("RECV SRS: fd=%d command=%d data_len=%d", fd, message.command, message.data_len);
- if (message.data != NULL && message.data_len > 0) {
+ LOGD("RECV SRS: fd=%d command=%d length=%d", fd, message.command, message.length);
+ if (message.data != NULL && message.length > 0) {
LOGD("==== SRS DATA DUMP ====");
- hex_dump(message.data, message.data_len);
+ hex_dump(message.data, message.length);
LOGD("=======================");
}