2 * This file is part of samsung-ril.
4 * Copyright (C) 2013 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/>.
27 #include <sys/types.h>
28 #include <sys/socket.h>
30 #include <sys/select.h>
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <cutils/sockets.h>
37 #include <telephony/ril.h>
39 #include <samsung-ril-socket.h>
40 #include <srs-client.h>
46 int srs_client_recv_message(struct srs_client *client, struct srs_message *message)
48 struct srs_header *header_p;
49 struct srs_header header;
53 struct timeval timeout;
57 if (client == NULL || message == NULL || client->fd < 0)
60 memset(message, 0, sizeof(struct srs_message));
61 memset(&header, 0, sizeof(header));
63 timeout.tv_sec = (SRS_CLIENT_TIMEOUT - SRS_CLIENT_TIMEOUT % 1000000) / 1000000;
64 timeout.tv_usec = SRS_CLIENT_TIMEOUT % 1000000;
67 FD_SET(client->fd, &fds);
69 rc = select(client->fd + 1, &fds, NULL, NULL, &timeout);
73 } else if (rc < 0 || !FD_ISSET(client->fd, &fds))
76 SRS_CLIENT_LOCK(client);
77 rc = read(client->fd, &header, sizeof(header));
78 SRS_CLIENT_UNLOCK(client);
80 if (rc != sizeof(header))
84 message->command = SRS_COMMAND(header_p);
86 length = header.length - sizeof(header);
88 data = calloc(1, length);
93 FD_SET(client->fd, &fds);
95 rc = select(client->fd + 1, &fds, NULL, NULL, &timeout);
96 if (rc <= 0 || !FD_ISSET(client->fd, &fds))
99 SRS_CLIENT_LOCK(client);
100 rc = read(client->fd, data, length);
101 SRS_CLIENT_UNLOCK(client);
106 message->data = data;
107 message->length = length;
123 int srs_client_send_message(struct srs_client *client, struct srs_message *message)
125 struct srs_header header;
126 unsigned char *p = NULL;
130 struct timeval timeout;
134 if (client == NULL || message == NULL || client->fd < 0)
137 memset(&header, 0, sizeof(header));
138 header.length = message->length + sizeof(header);
139 header.group = SRS_GROUP(message->command);
140 header.index = SRS_INDEX(message->command);
142 length = header.length;
143 data = calloc(1, length);
147 p = (unsigned char *) data;
148 memcpy(p, &header, sizeof(header));
150 if (message->data != NULL && message->length > 0) {
151 memcpy(p, message->data, message->length);
152 p += message->length;
155 timeout.tv_sec = (SRS_CLIENT_TIMEOUT - SRS_CLIENT_TIMEOUT % 1000000) / 1000000;
156 timeout.tv_usec = SRS_CLIENT_TIMEOUT % 1000000;
159 FD_SET(client->fd, &fds);
161 rc = select(client->fd + 1, NULL, &fds, NULL, &timeout);
162 if (rc <= 0 || !FD_ISSET(client->fd, &fds))
165 SRS_CLIENT_LOCK(client);
166 rc = write(client->fd, data, length);
167 SRS_CLIENT_UNLOCK(client);
185 int srs_client_send(struct srs_client *client, unsigned short command, void *data, int length)
187 struct srs_message message;
189 memset(&message, 0, sizeof(message));
190 message.command = command;
192 message.length = length;
194 return srs_client_send_message(client, &message);
197 int srs_client_open(struct srs_client *client)
204 fd = socket_local_client(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
206 fd = socket_local_client(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
217 int srs_client_close(struct srs_client *client)
219 if (client == NULL || client->fd < 0)
228 int srs_client_create(struct srs_client **client_p)
230 struct srs_client *client;
232 if (client_p == NULL)
235 client = calloc(1, sizeof(struct srs_client));
236 if (client == NULL) {
242 pthread_mutex_init(&(client->mutex), NULL);
249 int srs_client_destroy(struct srs_client *client)
254 pthread_mutex_destroy(&(client->mutex));
265 void *srs_client_thread(void *data)
267 struct srs_message message;
268 struct srs_client *client;
274 client = (struct srs_client *) data;
276 if (client->thread_cb == NULL)
279 while (client->thread_run) {
280 rc = srs_client_recv_message(client, &message);
284 client->thread_cb(&message);
288 client->thread_run = 0;
293 int srs_client_thread_start(struct srs_client *client,
294 srs_client_thread_cb cb)
299 if (client == NULL || cb == NULL)
302 client->thread_cb = cb;
303 client->thread_run = 1;
305 pthread_attr_init(&attr);
306 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
308 rc = pthread_create(&(client->thread), &attr, srs_client_thread, (void *) client);
315 int srs_client_thread_stop(struct srs_client *client)
320 client->thread_run = 0;
329 int srs_client_ping(struct srs_client *client)
331 struct srs_message message;
332 struct srs_control_ping ping;
333 struct srs_control_ping *ping_p;
339 memset(&message, 0, sizeof(message));
341 ping.caffe = SRS_CONTROL_CAFFE;
342 rc = srs_client_send(client, SRS_CONTROL_PING, &ping, sizeof(ping));
346 rc = srs_client_recv_message(client, &message);
347 if (rc < 0 || message.length <= 0 || message.data == NULL)
350 ping_p = (struct srs_control_ping *) message.data;
351 if (ping_p->caffe != SRS_CONTROL_CAFFE)
361 if (message.data != NULL)