3b4e26ba52ae2faffa85ef45b5291d636d74a070
[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 *) (data + sizeof(header)), message->data, message->data_len);
73
74         FD_ZERO(&fds);
75         FD_SET(srs_server->client_fd, &fds);
76
77         select(FD_SETSIZE, NULL, &fds, NULL, NULL);
78
79         write(srs_server->client_fd, data, header.length);
80
81         free(data);
82
83         return 0;
84 }
85
86 int srs_server_send(unsigned short command, void *data, int data_len)
87 {
88         struct srs_server *srs_server;
89         struct srs_message message;
90         int rc;
91
92         srs_server = (struct srs_server *) (srs_client->object);
93
94         message.command = command;
95         message.data = data;
96         message.data_len = data_len;
97
98         rc = srs_server_send_message(srs_server, &message);
99
100         return rc;
101 }
102
103 int srs_server_recv(struct srs_server *srs_server, struct srs_message *message)
104 {
105         void *raw_data = malloc(SRS_DATA_MAX_SIZE);
106         struct srs_header *header;
107         int rc;
108
109         rc = read(srs_server->client_fd, raw_data, SRS_DATA_MAX_SIZE);
110         if(rc < sizeof(struct srs_header)) {
111                 return -1;
112         }
113
114         header = raw_data;
115
116         message->command = SRS_COMMAND(header);
117         message->data_len = header->length - sizeof(struct srs_header);
118         message->data = malloc(message->data_len);
119
120         memcpy(message->data, raw_data + sizeof(struct srs_header), message->data_len);
121
122         free(raw_data);
123
124         return 0;
125 }
126
127 int srs_server_accept(struct srs_server *srs_server)
128 {
129         int client_fd = -1;
130         struct sockaddr_un client_addr;
131         int client_addr_len;
132
133         if(srs_server->client_fd > 0) {
134                 return 0;
135         }
136
137         client_fd = accept(srs_server->server_fd, (struct sockaddr_un *) &client_addr, &client_addr_len);
138
139         if(client_fd > 0) {
140                 srs_server->client_fd = client_fd;
141                 srs_server->client_addr = client_addr;
142                 srs_server->client_addr_len = client_addr_len;
143
144                 return 0;
145         }
146
147         return -1;
148 }
149
150 void srs_control_ping(struct srs_message *message)
151 {
152         int caffe;
153
154         if(message->data == NULL)
155                 return;
156
157         caffe=*((int *) message->data);
158
159         if(caffe == SRS_CONTROL_CAFFE) {
160                 srs_server_send(SRS_CONTROL_PING, &caffe, sizeof(caffe));
161         }
162 }
163
164 int srs_server_open(struct srs_server *srs_server)
165 {
166         int server_fd = -1;
167
168         int t = 0;
169
170         while(t < 5) {
171                 unlink(SRS_SOCKET_NAME);
172                 server_fd = socket_local_server(SRS_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
173
174                 if(server_fd > 0)
175                         break;
176
177                 t++;
178         }
179         
180         if(server_fd < 0)
181                 return -1;
182
183         srs_server->server_fd = server_fd;
184
185         return 0;
186 }
187
188 int srs_read_loop(struct ril_client *client)
189 {
190         struct srs_server *srs_server;
191         struct srs_message srs_message;
192         fd_set fds;
193         int rc;
194
195         if(client == NULL) {
196                 LOGE("client is NULL, aborting!");
197                 return -1;
198         }
199
200         if(client->object == NULL) {
201                 LOGE("client object is NULL, aborting!");
202                 return -1;
203         }
204
205         srs_server = (struct srs_server *) client->object;
206
207         while(1) {
208                 if(srs_server->server_fd < 0) {
209                         LOGE("SRS client server_fd is negative, aborting!");
210                         return -1;
211                 }
212
213                 rc = srs_server_accept(srs_server);
214
215                 LOGE("SRS server accept!");
216
217                 FD_ZERO(&fds);
218                 FD_SET(srs_server->client_fd, &fds);
219
220                 while(1) {
221                         if(srs_server->client_fd < 0)
222                                 break;
223
224                         select(FD_SETSIZE, &fds, NULL, NULL, NULL);
225
226                         if(FD_ISSET(srs_server->client_fd, &fds)) {
227                                 if(srs_server_recv(srs_server, &srs_message) < 0) {
228                                         LOGE("SRS recv failed, aborting!");
229                                         break;
230                                 }
231
232                                 LOGD("SRS recv: command=%d data_len=%d", srs_message.command, srs_message.data_len);
233                                 hex_dump(srs_message.data, srs_message.data_len);
234
235                                 srs_dispatch(&srs_message);
236
237                                 if(srs_message.data != NULL)
238                                         free(srs_message.data);
239                         }
240                 }
241
242                 if(srs_server->client_fd > 0) {
243                         close(srs_server->client_fd);
244                         srs_server->client_fd = -1;
245                 }
246
247                 LOGE("SRS server client ended!");
248         }
249
250         return 0;
251 }
252
253 int srs_create(struct ril_client *client)
254 {
255         struct srs_server *srs_server;
256
257         LOGD("Creating new SRS client");
258
259         srs_server = srs_server_new();
260         client->object = (void *) srs_server;
261
262         if(srs_server_open(srs_server) < 0) {
263                 LOGE("%s: samsung-ril-socket server open failed", __FUNCTION__);
264                 return -1;
265         }
266
267         return 0;
268 }
269
270 int srs_destroy(struct ril_client *client)
271 {
272         struct srs_server *srs_server = (struct srs_server *) client->object;
273         
274         if(srs_server == NULL)
275                 return 0;
276
277         if(srs_server->client_fd)
278                 close(srs_server->client_fd);
279         
280         close(srs_server->server_fd);
281
282         srs_server_free(srs_server);
283
284         return 0;
285 }
286
287 struct ril_client_funcs srs_client_funcs = {
288         .create = srs_create,
289         .destroy = srs_destroy,
290         .read_loop = srs_read_loop,
291 };