diff options
author | PaulK <contact@paulk.fr> | 2011-12-04 12:45:31 +0100 |
---|---|---|
committer | PaulK <contact@paulk.fr> | 2011-12-04 12:45:31 +0100 |
commit | 76e7653e6de5fd290a54a40f1e2592b216fd78da (patch) | |
tree | f836994734f8278150e3144df797a7d464ad3843 | |
parent | f0e385a21e8e02235cbeadbf596b03bfb5a74cec (diff) | |
download | hardware_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.mk | 5 | ||||
-rw-r--r-- | include/samsung-ril-socket.h | 37 | ||||
-rw-r--r-- | samsung-ril.c | 109 | ||||
-rw-r--r-- | socket.c | 148 | ||||
-rw-r--r-- | socket.h | 24 |
5 files changed, 319 insertions, 4 deletions
@@ -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 |