Fix some compilation warnings
[samsung-ril.git] / srs.c
1 /**
2  * This file is part of samsung-ril.
3  *
4  * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr>
5  *
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.
10  *
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.
15  *
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/>.
18  *
19  */
20
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <sys/select.h>
26
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 #include <cutils/sockets.h>
30
31 #define LOG_TAG "RIL-SRS"
32 #include <utils/Log.h>
33
34 #include "samsung-ril.h"
35 #include "util.h"
36
37 struct srs_server *srs_server_new(void)
38 {
39         struct srs_server *srs_server;
40
41         srs_server = malloc(sizeof(struct srs_server));
42         memset(srs_server, 0, sizeof(struct srs_server));
43         srs_server->server_fd = -1;
44         srs_server->client_fd = -1;
45
46         return srs_server;
47 }
48
49 void srs_server_free(struct srs_server *srs_server)
50 {
51         if(srs_server == NULL)
52                 return;
53
54         free(srs_server);
55 }
56
57 int srs_server_send_message(struct srs_server *srs_server, struct srs_message *message)
58 {
59         fd_set fds;
60
61         struct srs_header header;
62         void *data;
63
64         header.length = message->data_len + sizeof(header);
65         header.group = SRS_GROUP(message->command);
66         header.index = SRS_INDEX(message->command);
67
68         data = malloc(header.length);
69         memset(data, 0, header.length);
70
71         memcpy(data, &header, sizeof(header));
72         memcpy((void *) ((char*)data + sizeof(header)),
73                 message->data, message->data_len);
74
75         FD_ZERO(&fds);
76         FD_SET(srs_server->client_fd, &fds);
77
78         select(FD_SETSIZE, NULL, &fds, NULL, NULL);
79
80         write(srs_server->client_fd, data, header.length);
81
82         free(data);
83
84         return 0;
85 }
86
87 int srs_server_send(unsigned short command, void *data, int data_len)
88 {
89         struct srs_server *srs_server;
90         struct srs_message message;
91         int rc;
92
93         srs_server = (struct srs_server *) (srs_client->object);
94
95         message.command = command;
96         message.data = data;
97         message.data_len = data_len;
98
99         rc = srs_server_send_message(srs_server, &message);
100
101         return rc;
102 }
103
104 int srs_server_recv(struct srs_server *srs_server, struct srs_message *message)
105 {
106         void *raw_data = malloc(SRS_DATA_MAX_SIZE);
107         struct srs_header *header;
108         int rc;
109
110         rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE);
111         if(rc < (int)sizeof(struct srs_header)) {
112                 return -1;
113         }
114
115         header = raw_data;
116
117         message->command = SRS_COMMAND(header);
118         message->data_len = header->length - sizeof(struct srs_header);
119         message->data = malloc(message->data_len);
120
121         memcpy(message->data, (char*)raw_data + sizeof(struct srs_header),
122                 message->data_len);
123
124         free(raw_data);
125
126         return 0;
127 }
128
129 int srs_server_accept(struct srs_server *srs_server)
130 {
131         int client_fd = -1;
132         struct sockaddr_un client_addr;
133         int client_addr_len;
134
135         if(srs_server->client_fd > 0) {
136                 return 0;
137         }
138
139         client_fd = accept(srs_server->server_fd,
140                 (struct sockaddr*) &client_addr, &client_addr_len);
141
142         if(client_fd > 0) {
143                 srs_server->client_fd = client_fd;
144                 srs_server->client_addr = client_addr;
145                 srs_server->client_addr_len = client_addr_len;
146
147                 return 0;
148         }
149
150         return -1;
151 }
152
153 void srs_control_ping(struct srs_message *message)
154 {
155         int caffe;
156
157         if(message->data == NULL)
158                 return;
159
160         caffe=*((int *) message->data);
161
162         if(caffe == SRS_CONTROL_CAFFE) {
163                 srs_server_send(SRS_CONTROL_PING, &caffe, sizeof(caffe));
164         }
165 }
166
167 int srs_server_open(struct srs_server *srs_server)
168 {
169         int server_fd = -1;
170
171         int t = 0;
172
173         while(t < 5) {
174                 unlink(SRS_SOCKET_NAME);
175                 server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
176
177                 if(server_fd > 0)
178                         break;
179
180                 t++;
181         }
182         
183         if(server_fd < 0)
184                 return -1;
185
186         srs_server->server_fd = server_fd;
187
188         return 0;
189 }
190
191 int srs_read_loop(struct ril_client *client)
192 {
193         struct srs_server *srs_server;
194         struct srs_message srs_message;
195         fd_set fds;
196         int rc;
197
198         if(client == NULL) {
199                 LOGE("client is NULL, aborting!");
200                 return -1;
201         }
202
203         if(client->object == NULL) {
204                 LOGE("client object is NULL, aborting!");
205                 return -1;
206         }
207
208         srs_server = (struct srs_server *) client->object;
209
210         while(1) {
211                 if(srs_server->server_fd < 0) {
212                         LOGE("SRS client server_fd is negative, aborting!");
213                         return -1;
214                 }
215
216                 rc = srs_server_accept(srs_server);
217
218                 LOGE("SRS server accept!");
219
220                 FD_ZERO(&fds);
221                 FD_SET(srs_server->client_fd, &fds);
222
223                 while(1) {
224                         if(srs_server->client_fd < 0)
225                                 break;
226
227                         select(FD_SETSIZE, &fds, NULL, NULL, NULL);
228
229                         if(FD_ISSET(srs_server->client_fd, &fds)) {
230                                 if(srs_server_recv(srs_server, &srs_message) < 0) {
231                                         LOGE("SRS recv failed, aborting!");
232                                         break;
233                                 }
234
235                                 LOGD("SRS recv: command=%d data_len=%d", srs_message.command, srs_message.data_len);
236                                 hex_dump(srs_message.data, srs_message.data_len);
237
238                                 srs_dispatch(&srs_message);
239
240                                 if(srs_message.data != NULL)
241                                         free(srs_message.data);
242                         }
243                 }
244
245                 if(srs_server->client_fd > 0) {
246                         close(srs_server->client_fd);
247                         srs_server->client_fd = -1;
248                 }
249
250                 LOGE("SRS server client ended!");
251         }
252
253         return 0;
254 }
255
256 int srs_create(struct ril_client *client)
257 {
258         struct srs_server *srs_server;
259
260         LOGD("Creating new SRS client");
261
262         srs_server = srs_server_new();
263         client->object = (void *) srs_server;
264
265         if(srs_server_open(srs_server) < 0) {
266                 LOGE("%s: samsung-ril-socket server open failed", __FUNCTION__);
267                 return -1;
268         }
269
270         return 0;
271 }
272
273 int srs_destroy(struct ril_client *client)
274 {
275         struct srs_server *srs_server = (struct srs_server *) client->object;
276         
277         if(srs_server == NULL)
278                 return 0;
279
280         if(srs_server->client_fd)
281                 close(srs_server->client_fd);
282         
283         close(srs_server->server_fd);
284
285         srs_server_free(srs_server);
286
287         return 0;
288 }
289
290 struct ril_client_funcs srs_client_funcs = {
291         .create = srs_create,
292         .destroy = srs_destroy,
293         .read_loop = srs_read_loop,
294 };