From 92d89595bfb600327294df50b9b666f4548470dc Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Mon, 17 Sep 2012 20:45:19 +0200 Subject: WIP on SRS Change-Id: I82d74fb54b6f6dce7d891e85d8ad258bee689e06 --- audio/ril_interface.h | 2 +- device.mk | 1 + samsung-ril-client/Android.mk | 18 ++ samsung-ril-client/samsung-ril-client.c | 360 ++++++++++++++++++++++++++++++++ 4 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 samsung-ril-client/Android.mk create mode 100644 samsung-ril-client/samsung-ril-client.c diff --git a/audio/ril_interface.h b/audio/ril_interface.h index 676772c..d4d5792 100755 --- a/audio/ril_interface.h +++ b/audio/ril_interface.h @@ -17,7 +17,7 @@ #ifndef RIL_INTERFACE_H #define RIL_INTERFACE_H -#define RIL_CLIENT_LIBPATH "libsecril-client.so" +#define RIL_CLIENT_LIBPATH "libsamsung-ril-client.so" #define RIL_CLIENT_ERR_SUCCESS 0 #define RIL_CLIENT_ERR_AGAIN 1 diff --git a/device.mk b/device.mk index 4e8b790..ecec647 100644 --- a/device.mk +++ b/device.mk @@ -88,6 +88,7 @@ PRODUCT_PACKAGES += \ # RIL PRODUCT_PACKAGES += \ libsamsung-ril \ + libsamsung-ril-client \ ipc-modemctrl # Live Wallpapers diff --git a/samsung-ril-client/Android.mk b/samsung-ril-client/Android.mk new file mode 100644 index 0000000..4132aeb --- /dev/null +++ b/samsung-ril-client/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libsamsung-ril-client +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := samsung-ril-client.c + +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) +LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_C_INCLUDES += hardware/ril/samsung-ril/include \ + device/samsung/tuna/audio/ + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) diff --git a/samsung-ril-client/samsung-ril-client.c b/samsung-ril-client/samsung-ril-client.c new file mode 100644 index 0000000..102af87 --- /dev/null +++ b/samsung-ril-client/samsung-ril-client.c @@ -0,0 +1,360 @@ +/** + * Samsung RIL Client (Samsung RIL Socket Client-side implementation) + * + * Copyright (C) 2011 Paul Kocialkowski + * + * samsung-ril-client 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-client 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-client. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define LOG_TAG "SRS-Client" +#include + +#include +#include + +/* + * Structures + */ + +struct srs_client { + int fd; +}; + +/* + * SRS transport + */ + +int srs_send_message(struct srs_client *client, struct srs_message *message) +{ + struct srs_header header; + void *data; + int client_fd = client->fd; + fd_set fds; + int rc; + + if(client_fd < 0) + return -1; + + header.length = message->data_len + sizeof(header); + header.group = SRS_GROUP(message->command); + header.index = SRS_INDEX(message->command); + + 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(client_fd, &fds); + + // We can't rely on select RC + select(client_fd + 1, NULL, &fds, NULL, NULL); + + rc = write(client_fd, data, header.length); + + free(data); + + return rc; +} + +int srs_send(struct srs_client *client, unsigned short command, void *data, int data_len) +{ + struct srs_message message; + int rc; + + LOGE("%s", __func__); + + message.command = command; + message.data = data; + message.data_len = data_len; + + rc = srs_send_message(client, &message); + + return rc; +} + +int srs_recv_timed(struct srs_client *client, struct srs_message *message, long sec, long usec) +{ + void *raw_data = malloc(SRS_DATA_MAX_SIZE); + struct srs_header *header; + int rc; + + int client_fd = client->fd; + + if(client_fd < 0) + return -1; + + struct timeval timeout; + fd_set fds; + + FD_ZERO(&fds); + FD_SET(client_fd, &fds); + + timeout.tv_sec = sec; + timeout.tv_usec = usec; + + select(client_fd + 1, &fds, NULL, NULL, &timeout); + + rc = read(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->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_recv(struct srs_client *client, struct srs_message *message) +{ + return srs_recv_timed(client, message, 0, 0); +} + +int srs_ping(struct srs_client *client) +{ + int caffe_w = SRS_CONTROL_CAFFE; + int caffe_r = 0; + int rc = 0; + + struct srs_message message; + + rc = srs_send(client, SRS_CONTROL_PING, &caffe_w, sizeof(caffe_w)); + + if(rc < 0) { + return -1; + } + + rc = srs_recv_timed(client, &message, 0, 300); + + if(rc < 0) { + return -1; + } + + if(message.data == NULL) + return -1; + + caffe_r = *((int *) message.data); + + if(caffe_r == SRS_CONTROL_CAFFE) { + LOGD("Caffe is ready!"); + rc = 0; + } else { + LOGE("Caffe went wrong!"); + rc = -1; + } + + free(message.data); + return rc; +} + +/* + * Interface + */ + +void *OpenClient_RILD(void) +{ + struct srs_client *client = NULL; + + LOGE("%s", __func__); + + signal(SIGPIPE, SIG_IGN); + + client = calloc(1, sizeof(struct srs_client)); + client->fd = -1; + + return (void *) client; +} + +int Connect_RILD(void *data) +{ + struct srs_client *client = (struct srs_client *) data; + int t = 0; + int fd = -1; + int rc; + + LOGE("%s", __func__); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + +socket_connect: + while(t < 5) { + fd = socket_local_client(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); + + if(fd > 0) + break; + + LOGE("Socket creation to RIL failed: trying another time"); + + t++; + usleep(300); + } + + if(fd < 0) { + LOGE("Socket creation to RIL failed too many times"); + return RIL_CLIENT_ERR_CONNECT; + } + + client->fd = fd; + + LOGE("Socket creation done, sending ping"); + + rc = srs_ping(client); + + if(rc < 0) { + LOGE("Ping failed!"); + goto socket_connect; + } else { + LOGD("Ping went alright"); + } + + return RIL_CLIENT_ERR_SUCCESS; +} + +int Disconnect_RILD(void *data) +{ + struct srs_client *client = (struct srs_client *) data; + + LOGE("%s", __func__); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + if(client->fd > 0) + close(client->fd); + + return RIL_CLIENT_ERR_SUCCESS; +} + +int CloseClient_RILD(void *data) +{ + struct srs_client *client = (struct srs_client *) data; + + LOGE("%s", __func__); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + free(client); + + return RIL_CLIENT_ERR_SUCCESS; +} + +int isConnected_RILD(void *data) +{ + struct srs_client *client = (struct srs_client *) data; + int rc; + + LOGE("%s", __func__); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + if(client->fd < 0) + return 0; + + rc = srs_ping(client); + + if(rc < 0) { + LOGE("Ping failed!"); + close(client->fd); + + return 0; + } else { + LOGD("Ping went alright"); + } + + return 1; +} + +int SetCallVolume(void *data, enum ril_sound_type type, int vol_level) +{ + struct srs_client *client = (struct srs_client *) data; + struct srs_snd_call_volume call_volume; + + LOGD("Asking call volume"); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + call_volume.type = (enum srs_snd_type) type; + call_volume.volume = vol_level; + + srs_send(client, SRS_SND_SET_CALL_VOLUME, (void *) &call_volume, sizeof(call_volume)); + + return RIL_CLIENT_ERR_SUCCESS; +} + + +int SetCallAudioPath(void *data, enum ril_audio_path path) +{ + struct srs_client *client = (struct srs_client *) data; + + LOGD("Asking audio path"); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + srs_send(client, SRS_SND_SET_CALL_AUDIO_PATH, (void *) &path, sizeof(enum srs_snd_path)); + + return RIL_CLIENT_ERR_SUCCESS; +} + +int SetCallClockSync(void *data, enum ril_clock_state condition) +{ + struct srs_client *client = (struct srs_client *) data; + unsigned char clock_data = condition; + + LOGD("Asking clock sync"); + + if(client == NULL) + return RIL_CLIENT_ERR_INVAL; + + srs_send(client, SRS_SND_SET_CALL_CLOCK_SYNC, &clock_data, sizeof(data)); + + return RIL_CLIENT_ERR_SUCCESS; +} + +int RegisterUnsolicitedHandler(void *data, int command, void *callback) +{ + LOGD("Unsolicited handler isn't implemented yet!"); + + return RIL_CLIENT_ERR_SUCCESS; +} -- cgit v1.1