summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulK <contact@paulk.fr>2011-12-04 12:45:31 +0100
committerPaulK <contact@paulk.fr>2011-12-04 12:45:31 +0100
commit76e7653e6de5fd290a54a40f1e2592b216fd78da (patch)
treef836994734f8278150e3144df797a7d464ad3843
parentf0e385a21e8e02235cbeadbf596b03bfb5a74cec (diff)
downloadhardware_ril_samsung-ril-76e7653e6de5fd290a54a40f1e2592b216fd78da.zip
hardware_ril_samsung-ril-76e7653e6de5fd290a54a40f1e2592b216fd78da.tar.gz
hardware_ril_samsung-ril-76e7653e6de5fd290a54a40f1e2592b216fd78da.tar.bz2
Added Samsung Ril Socket (SRS) support: this permits working audio calls on nexus s
-rw-r--r--Android.mk5
-rw-r--r--include/samsung-ril-socket.h37
-rw-r--r--samsung-ril.c109
-rw-r--r--socket.c148
-rw-r--r--socket.h24
5 files changed, 319 insertions, 4 deletions
diff --git a/Android.mk b/Android.mk
index 4e3c9a0..026b714 100644
--- a/Android.mk
+++ b/Android.mk
@@ -13,7 +13,9 @@ LOCAL_SRC_FILES := \
sms.c \
util.c \
pwr.c \
- disp.c
+ disp.c \
+ socket.c
+
LOCAL_SHARED_LIBRARIES := \
libcutils libutils libril
@@ -31,6 +33,7 @@ endif
LOCAL_C_INCLUDES := external/libsamsung-ipc/include
LOCAL_C_INCLUDES += hardware/ril/libsamsung-ipc/include
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_MODULE_TAGS := optional
diff --git a/include/samsung-ril-socket.h b/include/samsung-ril-socket.h
new file mode 100644
index 0000000..6686932
--- /dev/null
+++ b/include/samsung-ril-socket.h
@@ -0,0 +1,37 @@
+/* Samsung RIL Socket protocol defines */
+
+#define SRS_COMMAND(f) ((f->group << 8) | f->index)
+#define SRS_GROUP(m) (m >> 8)
+#define SRS_INDEX(m) (m & 0xff)
+
+#define SRS_CONTROL 0x01
+#define SRS_CONTROL_GET_HELO 0x0102
+#define SRS_CONTROL_LINK_CLOSE 0x0103
+
+#define SRS_SND 0x02
+#define SRS_SND_SET_CALL_VOLUME 0x0201
+#define SRS_SND_SET_CALL_AUDIO_PATH 0x0202
+#define SRS_SND_SET_CALL_CLOCK_SYNC 0x0203
+
+#define SRS_CONTROL_HELO 0xCAFFE
+
+#define SRS_CONTROL_LINK_STATUS_OPEN 0x01
+#define SRS_CONTROL_LINK_STATUS_CLOSE 0x02
+
+#define SRS_SOCKET_NAME "samsung-ril-socket"
+#define SRS_DATA_MAX_SIZE 0x1000
+
+struct srs_header {
+ unsigned int length;
+ unsigned char group;
+ unsigned char index;
+ unsigned char msg_id;
+} __attribute__((__packed__));
+
+struct srs_message {
+ unsigned short command;
+ unsigned char msg_id;
+ int data_len;
+ void *data;
+} __attribute__((__packed__));
+
diff --git a/samsung-ril.c b/samsung-ril.c
index ca9e31c..ee3af2d 100644
--- a/samsung-ril.c
+++ b/samsung-ril.c
@@ -2,12 +2,14 @@
#include <telephony/ril.h>
+#include <samsung-ril-socket.h>
#include <radio.h>
#include <util.h>
#define LOG_TAG "RIL"
#include <utils/Log.h>
+#include "socket.h"
#include "samsung-ril.h"
#include "util.h"
@@ -17,6 +19,7 @@ const struct RIL_Env *rilenv;
struct radio_state radio;
struct ipc_client *ipc_client;
+struct srs_server *srs_server;
int client_fmt_fd = -1;
/*
@@ -315,9 +318,93 @@ void ipc_log_handler(const char *message, void *user_data)
LOGD("ipc: %s", message);
}
+void socketRespondGetHelo(struct srs_message *message)
+{
+ int helo = SRS_CONTROL_HELO;
+ srs_server_send(srs_server, SRS_CONTROL_GET_HELO, &helo, sizeof(helo), message->msg_id);
+}
+
+void socketRespondLinkClose(struct srs_message *message)
+{
+ close(srs_server->client_fd);
+ srs_server->client_fd = -1;
+}
+
+void socketRespondSetCallClockSync(struct srs_message *message)
+{
+ unsigned char data = *((unsigned char *) message->data);
+ LOGE("SetCallClockSync data is 0x%x\n", data);
+
+ ipc_client_send(ipc_client, IPC_SND_CLOCK_CTRL, IPC_TYPE_EXEC, &data, sizeof(data), 0xff);
+}
+
+void onSocketReceive(struct srs_message *message)
+{
+ switch(message->command) {
+ case SRS_CONTROL_GET_HELO:
+ socketRespondGetHelo(message);
+ break;
+ case SRS_CONTROL_LINK_CLOSE:
+ socketRespondLinkClose(message);
+ break;
+ case SRS_SND_SET_CALL_CLOCK_SYNC:
+ socketRespondSetCallClockSync(message);
+ break;
+ }
+}
+
+void *socket_loop()
+{
+ struct srs_message srs_message;
+ fd_set fds;
+ int rc;
+
+ while(1) {
+ rc = srs_server_accept(srs_server);
+
+ LOGE("SRS server accept!");
+
+ FD_ZERO(&fds);
+ FD_SET(srs_server->client_fd, &fds);
+
+ while(1) {
+ usleep(300);
+
+ if(srs_server->client_fd < 0)
+ break;
+
+ select(FD_SETSIZE, &fds, NULL, NULL, NULL);
+
+ if(FD_ISSET(srs_server->client_fd, &fds)) {
+ if(srs_server_recv(srs_server, &srs_message) < 0) {
+ LOGE("SRS server RECV failure!!!");
+ break;
+ }
+
+ LOGE("SRS OBTAINED DATA DUMP == %d == %d ======", srs_message.command, srs_message.data_len);
+ ipc_hex_dump(ipc_client, srs_message.data, srs_message.data_len);
+
+ onSocketReceive(&srs_message);
+
+ if(srs_message.data != NULL) //check on datalen
+ free(srs_message.data);
+ }
+ }
+
+ if(srs_server->client_fd > 0) {
+ close(srs_server->client_fd);
+ srs_server->client_fd = -1;
+ }
+
+ LOGE("SRS server client ended!");
+ }
+
+ return 0;
+}
+
/**
* read_loop():
- * This function is the main IPC read loop
+ * This function is the main RIL read loop
*/
void *read_loop()
{
@@ -328,9 +415,9 @@ void *read_loop()
FD_SET(client_fmt_fd, &fds);
while(1) {
- usleep(3000);
+ usleep(300);
- select(client_fmt_fd + 1, &fds, NULL, NULL, NULL);
+ select(FD_SETSIZE, &fds, NULL, NULL, NULL);
if(FD_ISSET(client_fmt_fd, &fds)) {
if(ipc_client_recv(ipc_client, &resp)) {
@@ -365,6 +452,15 @@ void radio_init_lpm(void)
radio.power_mode = POWER_MODE_LPM;
}
+void socket_loop_thread()
+{
+ pthread_t thread;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&thread, &attr, socket_loop, NULL);
+}
+
void read_loop_thread()
{
pthread_t thread;
@@ -421,7 +517,14 @@ const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **a
return 0;
}
+ srs_server = srs_server_new();
+ if(srs_server_open(srs_server) < 0) {
+ LOGE("%s: samsung-ril-socket server open failed", __FUNCTION__);
+ return 0;
+ }
+
read_loop_thread();
+ socket_loop_thread();
return &radio_ops;
}
diff --git a/socket.c b/socket.c
new file mode 100644
index 0000000..7c0f8ed
--- /dev/null
+++ b/socket.c
@@ -0,0 +1,148 @@
+#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 <arpa/inet.h>
+#include <netinet/in.h>
+#include <cutils/sockets.h>
+
+#include <cutils/log.h>
+
+#include <samsung-ril-socket.h>
+#include "socket.h"
+
+struct srs_server *srs_server_new(void)
+{
+ struct srs_server *srs_server;
+
+ srs_server = malloc(sizeof(struct srs_server));
+ memset(srs_server, 0, sizeof(struct srs_server));
+ srs_server->server_fd = -1;
+ srs_server->client_fd = -1;
+
+ return srs_server;
+}
+
+int srs_server_send_message(struct srs_server *srs_server, struct srs_message *message)
+{
+ fd_set fds;
+
+ struct srs_header header;
+ void *data;
+
+ header.length = message->data_len + sizeof(header);
+ header.group = SRS_GROUP(message->command);
+ header.index = SRS_INDEX(message->command);
+ header.msg_id = message->msg_id;
+
+ data = malloc(header.length);
+ memset(data, 0, header.length);
+
+ memcpy(data, &header, sizeof(header));
+ memcpy((void *) (data + sizeof(header)), message->data, message->data_len);
+
+ FD_ZERO(&fds);
+ FD_SET(srs_server->client_fd, &fds);
+
+ select(FD_SETSIZE, NULL, &fds, NULL, NULL);
+
+ write(srs_server->client_fd, data, header.length);
+
+ //FIXME: can we free?
+
+ return 0;
+}
+
+int srs_server_send(struct srs_server *srs_server, unsigned short command, void *data, int data_len, unsigned msg_id)
+{
+ struct srs_message message;
+ int rc;
+
+ message.command = command;
+ message.data = data;
+ message.data_len = data_len;
+ message.msg_id = msg_id;
+
+ rc = srs_server_send_message(srs_server, &message);
+
+ return rc;
+}
+
+int srs_server_recv(struct srs_server *srs_server, struct srs_message *message)
+{
+ void *raw_data = malloc(SRS_DATA_MAX_SIZE);
+ struct srs_header *header;
+ int rc;
+
+ rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE);
+ if(rc < sizeof(struct srs_header)) {
+ return -1;
+ }
+
+ header = raw_data;
+
+ message->command = SRS_COMMAND(header);
+ message->msg_id = header->msg_id;
+ message->data_len = header->length - sizeof(struct srs_header);
+ message->data = malloc(message->data_len);
+
+ memcpy(message->data, raw_data + sizeof(struct srs_header), message->data_len);
+
+ free(raw_data);
+
+ return 0;
+}
+
+int srs_server_accept(struct srs_server *srs_server)
+{
+ int client_fd = -1;
+ struct sockaddr_un client_addr;
+ int client_addr_len;
+
+ if(srs_server->client_fd > 0) {
+ return 0;
+ }
+
+ client_fd = accept(srs_server->server_fd, (struct sockaddr_un *) &client_addr, &client_addr_len);
+
+ if(client_fd > 0) {
+ srs_server->client_fd = client_fd;
+ srs_server->client_addr = client_addr;
+ srs_server->client_addr_len = client_addr_len;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+int srs_server_open(struct srs_server *srs_server)
+{
+ int server_fd = -1;
+
+ int t = 0;
+
+ while(t < 5) {
+ unlink(SRS_SOCKET_NAME);
+ server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+
+ if(server_fd > 0)
+ break;
+
+ t++;
+ }
+
+ if(server_fd < 0)
+ return -1;
+
+ srs_server->server_fd = server_fd;
+
+ return 0;
+}
diff --git a/socket.h b/socket.h
new file mode 100644
index 0000000..0277c00
--- /dev/null
+++ b/socket.h
@@ -0,0 +1,24 @@
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+struct srs_server {
+ int server_fd;
+ int client_fd;
+ struct sockaddr_un client_addr;
+ int client_addr_len;
+};
+
+struct srs_server *srs_server_new(void);
+int srs_server_send(struct srs_server *srs_server, unsigned short command, void *data, int data_len, unsigned msg_id);
+int srs_server_recv(struct srs_server *srs_server, struct srs_message *message);
+int srs_server_accept(struct srs_server *srs_server);
+int srs_server_open(struct srs_server *srs_server);
+
+#endif