2 * This file is part of samsung-ril.
4 * Copyright (C) 2011-2012 Paul Kocialkowski <contact@oaulk.fr>
6 * samsung-ril is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * samsung-ril is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with samsung-ril. If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/types.h>
24 #include <sys/socket.h>
26 #include <sys/select.h>
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
30 #include <cutils/sockets.h>
32 #define LOG_TAG "RIL-SRS"
33 #include <utils/Log.h>
35 #include "samsung-ril.h"
38 int srs_client_register(struct srs_client_data *client_data, int fd)
40 struct srs_client_info *client;
41 struct list_head *list_end;
42 struct list_head *list;
44 if(client_data == NULL)
47 client = calloc(1, sizeof(struct srs_client_info));
53 list_end = client_data->clients;
54 while(list_end != NULL && list_end->next != NULL)
55 list_end = list_end->next;
57 list = list_head_alloc((void *) client, list_end, NULL);
59 if(client_data->clients == NULL)
60 client_data->clients = list;
65 void srs_client_unregister(struct srs_client_data *client_data, struct srs_client_info *client)
67 struct list_head *list;
69 if(client_data == NULL || client == NULL)
72 list = client_data->clients;
74 if(list->data == (void *) client) {
75 memset(client, 0, sizeof(struct srs_client_info));
78 if(list == client_data->clients)
79 client_data->clients = list->next;
90 struct srs_client_info *srs_client_info_find(struct srs_client_data *client_data)
92 struct srs_client_info *client;
93 struct list_head *list;
95 list = client_data->clients;
97 client = (struct srs_client_info *) list->data;
110 struct srs_client_info *srs_client_info_find_fd(struct srs_client_data *client_data, int fd)
112 struct srs_client_info *client;
113 struct list_head *list;
115 list = client_data->clients;
116 while(list != NULL) {
117 client = (struct srs_client_info *) list->data;
131 int srs_client_info_fill_fd_set(struct srs_client_data *client_data, fd_set *fds)
133 struct srs_client_info *client;
134 struct list_head *list;
137 if(client_data == NULL || fds == NULL)
141 list = client_data->clients;
142 while(list != NULL) {
143 client = (struct srs_client_info *) list->data;
147 FD_SET(client->fd, fds);
148 if(client->fd > fd_max)
158 int srs_client_info_get_fd_set(struct srs_client_data *client_data, fd_set *fds)
160 struct srs_client_info *client;
161 struct list_head *list;
164 if(client_data == NULL || fds == NULL)
167 list = client_data->clients;
168 while(list != NULL) {
169 client = (struct srs_client_info *) list->data;
173 if(FD_ISSET(client->fd, fds)) {
174 FD_CLR(client->fd, fds);
185 int srs_client_send_message(struct srs_client_data *client_data, struct srs_message *message)
187 struct srs_header header;
190 struct timeval timeout;
194 if(client_data == NULL || message == NULL)
197 memset(&header, 0, sizeof(header));
198 header.length = message->data_len + sizeof(header);
199 header.group = SRS_GROUP(message->command);
200 header.index = SRS_INDEX(message->command);
202 data = calloc(1, header.length);
206 memcpy(data, &header, sizeof(header));
207 memcpy((void *) ((char *) data + sizeof(header)), message->data, message->data_len);
209 memset(&timeout, 0, sizeof(timeout));
210 timeout.tv_usec = 300;
212 if(client_data->client_fd < 0)
216 FD_SET(client_data->client_fd, &fds);
218 rc = select(client_data->client_fd + 1, NULL, &fds, NULL, &timeout);
220 if(!FD_ISSET(client_data->client_fd, &fds)) {
221 LOGE("SRS write select failed on fd %d", client_data->client_fd);
225 rc = write(client_data->client_fd, data, header.length);
226 if(rc < (int) sizeof(struct srs_header)) {
227 LOGE("SRS write failed on fd %d with %d bytes", client_data->client_fd, rc);
239 int srs_client_send(struct srs_client_data *client_data, unsigned short command, void *data, int length)
241 struct srs_client_info *client;
242 struct srs_message message;
245 if(client_data == NULL)
248 memset(&message, 0, sizeof(message));
249 message.command = command;
251 message.data_len = length;
253 RIL_CLIENT_LOCK(client_data->client);
254 rc = srs_client_send_message(client_data, &message);
255 RIL_CLIENT_UNLOCK(client_data->client);
258 LOGD("SRS client with fd %d terminated", client_data->client_fd);
260 client = srs_client_info_find_fd(client_data, client_data->client_fd);
262 srs_client_unregister(client_data, client);
263 close(client_data->client_fd);
264 client_data->client_fd = -1;
270 int srs_send(unsigned short command, void *data, int length)
272 struct srs_client_data *client_data;
275 if(ril_data.srs_client == NULL || ril_data.srs_client->data == NULL)
278 client_data = (struct srs_client_data *) ril_data.srs_client->data;
280 LOGD("SEND SRS: fd=%d command=%d data_len=%d", client_data->client_fd, command, length);
281 if(data != NULL && length > 0) {
282 LOGD("==== SRS DATA DUMP ====");
283 hex_dump(data, length);
284 LOGD("=======================");
287 return srs_client_send(client_data, command, data, length);
290 int srs_client_recv(struct srs_client_data *client_data, struct srs_message *message)
292 struct srs_header *header;
295 struct timeval timeout;
299 if(client_data == NULL || message == NULL)
302 data = calloc(1, SRS_DATA_MAX_SIZE);
306 memset(&timeout, 0, sizeof(timeout));
307 timeout.tv_usec = 300;
309 if(client_data->client_fd < 0)
313 FD_SET(client_data->client_fd, &fds);
315 rc = select(client_data->client_fd + 1, &fds, NULL, NULL, &timeout);
317 if(!FD_ISSET(client_data->client_fd, &fds)) {
318 LOGE("SRS read select failed on fd %d", client_data->client_fd);
322 rc = read(client_data->client_fd, data, SRS_DATA_MAX_SIZE);
323 if(rc < (int) sizeof(struct srs_header)) {
324 LOGE("SRS read failed on fd %d with %d bytes", client_data->client_fd, rc);
328 header = (struct srs_header *) data;
330 memset(message, 0, sizeof(struct srs_message));
331 message->command = SRS_COMMAND(header);
332 message->data_len = header->length - sizeof(struct srs_header);
333 if(message->data_len > 0) {
334 message->data = calloc(1, message->data_len);
335 memcpy(message->data, (void *) ((char *) data + sizeof(struct srs_header)), message->data_len);
337 message->data = NULL;
348 void srs_control_ping(struct srs_message *message)
352 if(message == NULL || message->data == NULL || message->data_len < (int) sizeof(int))
355 caffe=*((int *) message->data);
357 if(caffe == SRS_CONTROL_CAFFE) {
358 srs_send(SRS_CONTROL_PING, &caffe, sizeof(caffe));
362 static int srs_server_open(void)
367 for(t=0 ; t < 5 ; t++) {
368 unlink(SRS_SOCKET_NAME);
370 server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
372 server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
381 void *srs_client_read_loop(void *data)
383 struct srs_client_info *client;
384 struct srs_client_data *client_data;
385 struct srs_message message;
386 struct timeval timeout;
395 client_data = (struct srs_client_data *) data;
397 while(client_data->running) {
401 fd_max = srs_client_info_fill_fd_set(client_data, &fds);
410 timeout.tv_usec = 3000;
412 select(fd_max + 1, &fds, NULL, NULL, &timeout);
415 while((fd = srs_client_info_get_fd_set(client_data, &fds)) >= 0) {
416 client_data->client_fd = fd;
418 RIL_CLIENT_LOCK(client_data->client);
419 rc = srs_client_recv(client_data, &message);
421 LOGD("SRS client with fd %d terminated", fd);
423 client = srs_client_info_find_fd(client_data, fd);
425 srs_client_unregister(client_data, client);
428 RIL_CLIENT_UNLOCK(client_data->client);
431 RIL_CLIENT_UNLOCK(client_data->client);
433 LOGD("RECV SRS: fd=%d command=%d data_len=%d", fd, message.command, message.data_len);
434 if(message.data != NULL && message.data_len > 0) {
435 LOGD("==== SRS DATA DUMP ====");
436 hex_dump(message.data, message.data_len);
437 LOGD("=======================");
440 srs_dispatch(&message);
442 if(message.data != NULL)
445 client_data->client_fd = -1;
454 int srs_read_loop(struct ril_client *client)
456 struct srs_client_data *client_data;
457 struct sockaddr_un client_addr;
463 if(client == NULL || client->data == NULL)
466 client_data = (struct srs_client_data *) client->data;
468 pthread_attr_init(&attr);
469 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
471 client_data->running = 1;
473 rc = pthread_create(&client_data->thread, &attr, srs_client_read_loop, (void *) client_data);
475 LOGE("Unable to create SRS client read loop thread");
479 while(client_data->server_fd >= 0) {
480 fd = accept(client_data->server_fd, (struct sockaddr *) &client_addr,
483 LOGE("Unable to accept new SRS client");
487 fcntl(fd, F_SETFL, O_NONBLOCK);
489 LOGD("Accepted new SRS client from fd %d", fd);
492 rc = srs_client_register(client_data, fd);
495 LOGE("Unable to register SRS client");
500 LOGE("SRS server failure");
502 client_data->running = 0;
504 // Wait for the thread to finish
505 pthread_join(client_data->thread, NULL);
510 int srs_create(struct ril_client *client)
512 struct srs_client_data *client_data = NULL;
517 LOGD("Creating new SRS client");
519 signal(SIGPIPE, SIG_IGN);
521 client_data = (struct srs_client_data *) calloc(1, sizeof(struct srs_client_data));
522 if(client_data == NULL) {
523 LOGE("SRS client data creation failed");
527 client_data->server_fd = srs_server_open();
528 if(client_data->server_fd < 0) {
529 LOGE("SRS server creation failed");
533 pthread_mutex_init(&client_data->mutex, NULL);
535 client_data->client = client;
536 client->data = (void *) client_data;
541 if(client_data != NULL)
547 int srs_destroy(struct ril_client *client)
549 struct srs_client_data *client_data = NULL;
550 struct srs_client_info *client_info;
555 if(client->data == NULL)
558 client_data = (struct srs_client_data *) client->data;
560 pthread_mutex_destroy(&client_data->mutex);
562 while((client_info = srs_client_info_find(client_data)) != NULL) {
563 close(client_info->fd);
564 srs_client_unregister(client_data, client_info);
567 if(client_data->server_fd > 0)
568 close(client_data->server_fd);
570 memset(client_data, 0, sizeof(struct srs_client_data));
577 struct ril_client_funcs srs_client_funcs = {
578 .create = srs_create,
579 .destroy = srs_destroy,
580 .read_loop = srs_read_loop,