diff options
| author | Paul Kocialkowski <contact@paulk.fr> | 2013-03-07 14:41:30 +0100 | 
|---|---|---|
| committer | Paul Kocialkowski <contact@paulk.fr> | 2013-03-07 14:41:30 +0100 | 
| commit | 8507877c6dba1cca27268dc4e8079b4a96da51a9 (patch) | |
| tree | b64b7336a830478e739fb37d5b9254d5b83cc43d | |
| parent | 0d0f2ab21d3d26bc8a5d04a4b7a717763382e855 (diff) | |
| download | hardware_ril_samsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.zip hardware_ril_samsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.tar.gz hardware_ril_samsung-ril-8507877c6dba1cca27268dc4e8079b4a96da51a9.tar.bz2  | |
SRS: srs-client library, proper structures for protocol data
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
| -rw-r--r-- | Android.mk | 18 | ||||
| -rw-r--r-- | include/samsung-ril-socket.h | 29 | ||||
| -rw-r--r-- | srs-client/include/srs-client.h | 60 | ||||
| -rw-r--r-- | srs-client/srs-client.c | 365 | ||||
| -rw-r--r-- | srs.c | 24 | 
5 files changed, 475 insertions, 21 deletions
@@ -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; +} @@ -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("=======================");  			}  | 
