Device: Various improvements: added missing functions, mutex, threaded recv loop
[hayes-ril.git] / device.c
1 /**
2  * This file is part of hayes-ril.
3  *
4  * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
5  * 
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <pthread.h>
20
21 #define LOG_TAG "RIL-DEV"
22 #include <utils/Log.h>
23
24 #include <hayes-ril.h>
25
26 int ril_device_init(struct ril_device *ril_device_p)
27 {
28         int rc;
29
30         rc = ril_device_data_create(ril_device_p);
31         if(rc < 0) {
32                 LOGE("Failed to create device data!");
33                 return -1;
34         }
35
36         rc = ril_device_power_on(ril_device_p);
37         if(rc < 0) {
38                 LOGE("Failed to power on device!");
39                 return -1;
40         }
41
42         rc = ril_device_boot(ril_device_p);
43         if(rc < 0) {
44                 LOGE("Failed to boot device!");
45                 return -1;
46         }
47
48         rc = ril_device_open(ril_device_p);
49         if(rc < 0) {
50                 LOGE("Failed to open device!");
51                 return -1;
52         }
53
54         return 0;
55 }
56
57 int ril_device_deinit(struct ril_device *ril_device_p)
58 {
59         ril_device_close(ril_device_p);
60
61         ril_device_power_off(ril_device_p);
62
63         ril_device_data_destroy(ril_device_p);
64
65         return 0;
66 }
67
68 int ril_device_data_create(struct ril_device *ril_device_p)
69 {
70         int rc;
71
72         if(ril_device_p->handlers == NULL) {
73                 LOGE("Missing device handlers!");
74                 return -1;
75         }
76
77         if(ril_device_p->handlers->power == NULL) {
78                 LOGE("Missing device power handlers!");
79                 return -1;
80         }
81
82         if(ril_device_p->handlers->power->sdata_create == NULL) {
83                 LOGE("Missing device power data handlers!");
84                 return -1;
85         }
86
87         LOGD("Creating data for power handlers...");
88         rc = ril_device_p->handlers->power->sdata_create(&ril_device_p->handlers->power->sdata);
89         if(rc < 0) {
90                 LOGE("Creating data for power handlers failed!");
91                 return -1;
92         }
93
94         if(ril_device_p->handlers->transport == NULL) {
95                 LOGE("Missing device transport handlers!");
96                 return -1;
97         }
98
99         if(ril_device_p->handlers->transport->sdata_create == NULL) {
100                 LOGE("Missing device transport data handlers!");
101                 return -1;
102         }
103
104         LOGD("Creating data for transport handlers...");
105         ril_device_p->handlers->transport->sdata_create(&ril_device_p->handlers->transport->sdata);
106         if(rc < 0) {
107                 LOGE("Creating data for transport handlers failed!");
108                 return -1;
109         }
110
111         LOGD("Creating mutex for transport handlers...");
112         pthread_mutex_init(&(ril_device_p->handlers->transport->mutex), NULL);
113
114         return 0;
115 }
116
117 int ril_device_data_destroy(struct ril_device *ril_device_p)
118 {
119         int rc;
120
121         if(ril_device_p->handlers == NULL) {
122                 LOGE("Missing device handlers!");
123                 return -1;
124         }
125
126         if(ril_device_p->handlers->power == NULL) {
127                 LOGE("Missing device power handlers!");
128                 return -1;
129         }
130
131         if(ril_device_p->handlers->power->sdata_destroy == NULL) {
132                 LOGE("Missing device power data handlers!");
133                 return -1;
134         }
135
136         LOGD("Destroying data for power handlers...");
137         rc = ril_device_p->handlers->power->sdata_destroy(&ril_device_p->handlers->power->sdata);
138         if(rc < 0) {
139                 LOGE("Destroying data for power handlers failed!");
140                 return -1;
141         }
142
143         if(ril_device_p->handlers->transport == NULL) {
144                 LOGE("Missing device transport handlers!");
145                 return -1;
146         }
147
148         if(ril_device_p->handlers->transport->sdata_destroy == NULL) {
149                 LOGE("Missing device transport data handlers!");
150                 return -1;
151         }
152
153         LOGD("Destroying data for transport handlers...");
154         ril_device_p->handlers->transport->sdata_destroy(&ril_device_p->handlers->transport->sdata);
155         if(rc < 0) {
156                 LOGE("Destroying data for transport handlers failed!");
157                 return -1;
158         }
159
160         LOGD("Destroying mutex for transport handlers...");
161         pthread_mutex_destroy(&(ril_device_p->handlers->transport->mutex));
162
163         return 0;
164 }
165
166 int ril_device_boot(struct ril_device *ril_device_p)
167 {
168         int rc;
169
170         if(ril_device_p->handlers == NULL) {
171                 LOGE("Missing device handlers!");
172                 return -1;
173         }
174
175         if(ril_device_p->handlers->power == NULL) {
176                 LOGE("Missing device power handlers!");
177                 return -1;
178         }
179
180         if(ril_device_p->handlers->power->boot == NULL) {
181                 LOGE("Missing device power boot handler!");
182                 return -1;
183         }
184
185         LOGD("Booting modem...");
186
187         rc = ril_device_p->handlers->power->boot(ril_device_p->handlers->power->sdata);
188         return rc;
189 }
190
191 int ril_device_power_on(struct ril_device *ril_device_p)
192 {
193         int rc;
194
195         if(ril_device_p->handlers == NULL) {
196                 LOGE("Missing device handlers!");
197                 return -1;
198         }
199
200         if(ril_device_p->handlers->power == NULL) {
201                 LOGE("Missing device power handlers!");
202                 return -1;
203         }
204
205         if(ril_device_p->handlers->power->power_on == NULL) {
206                 LOGE("Missing device power on handler!");
207                 return -1;
208         }
209
210         LOGD("Powering modem on...");
211
212         rc = ril_device_p->handlers->power->power_on(ril_device_p->handlers->power->sdata);
213         return rc;
214 }
215
216 int ril_device_power_off(struct ril_device *ril_device_p)
217 {
218         int rc;
219
220         if(ril_device_p->handlers == NULL) {
221                 LOGE("Missing device handlers!");
222                 return -1;
223         }
224
225         if(ril_device_p->handlers->power == NULL) {
226                 LOGE("Missing device power handlers!");
227                 return -1;
228         }
229
230         if(ril_device_p->handlers->power->power_off == NULL) {
231                 LOGE("Missing device power off handler!");
232                 return -1;
233         }
234
235         LOGD("Powering modem off...");
236
237         rc = ril_device_p->handlers->power->power_off(ril_device_p->handlers->power->sdata);
238         return rc;
239 }
240
241 int ril_device_open(struct ril_device *ril_device_p)
242 {
243         int rc;
244
245         if(ril_device_p->handlers == NULL) {
246                 LOGE("Missing device handlers!");
247                 return -1;
248         }
249
250         if(ril_device_p->handlers->transport == NULL) {
251                 LOGE("Missing device transport handlers!");
252                 return -1;
253         }
254
255         if(ril_device_p->handlers->transport->open == NULL) {
256                 LOGE("Missing device transport open handler!");
257                 return -1;
258         }
259
260         LOGD("Opening modem...");
261
262         rc = ril_device_p->handlers->transport->open(ril_device_p->handlers->transport->sdata);
263         return rc;
264 }
265
266 int ril_device_close(struct ril_device *ril_device_p)
267 {
268         int rc;
269
270         if(ril_device_p->handlers == NULL) {
271                 LOGE("Missing device handlers!");
272                 return -1;
273         }
274
275         if(ril_device_p->handlers->transport == NULL) {
276                 LOGE("Missing device transport handlers!");
277                 return -1;
278         }
279
280         if(ril_device_p->handlers->transport->close == NULL) {
281                 LOGE("Missing device transport close handler!");
282                 return -1;
283         }
284
285         LOGD("Closing modem...");
286
287         rc = ril_device_p->handlers->transport->close(ril_device_p->handlers->transport->sdata);
288         return rc;
289 }
290
291 int ril_device_send(struct ril_device *ril_device_p, void *data, int length)
292 {
293         int rc;
294
295         if(ril_device_p->handlers == NULL) {
296                 LOGE("Missing device handlers!");
297                 return -1;
298         }
299
300         if(ril_device_p->handlers->transport == NULL) {
301                 LOGE("Missing device transport handlers!");
302                 return -1;
303         }
304
305         if(ril_device_p->handlers->transport->send == NULL) {
306                 LOGE("Missing device transport send handler!");
307                 return -1;
308         }
309
310         RIL_DEVICE_LOCK(ril_device_p);
311         rc = ril_device_p->handlers->transport->send(ril_device_p->handlers->transport->sdata, data, length);
312         RIL_DEVICE_UNLOCK(ril_device_p);
313
314         return rc;
315 }
316
317 int ril_device_recv(struct ril_device *ril_device_p, void **data, int length)
318 {
319         int rc;
320
321         if(ril_device_p->handlers == NULL) {
322                 LOGE("Missing device handlers!");
323                 return -1;
324         }
325
326         if(ril_device_p->handlers->transport == NULL) {
327                 LOGE("Missing device transport handlers!");
328                 return -1;
329         }
330
331         if(ril_device_p->handlers->transport->recv == NULL) {
332                 LOGE("Missing device transport recv handler!");
333                 return -1;
334         }
335
336         RIL_DEVICE_LOCK(ril_device_p);
337         rc = ril_device_p->handlers->transport->recv(ril_device_p->handlers->transport->sdata, data, length);
338         RIL_DEVICE_UNLOCK(ril_device_p);
339
340         return rc;
341 }
342
343 int ril_device_recv_poll(struct ril_device *ril_device_p)
344 {
345         int rc;
346
347         if(ril_device_p->handlers == NULL) {
348                 LOGE("Missing device handlers!");
349                 return -1;
350         }
351
352         if(ril_device_p->handlers->transport == NULL) {
353                 LOGE("Missing device transport handlers!");
354                 return -1;
355         }
356
357         if(ril_device_p->handlers->transport->recv_poll == NULL) {
358                 LOGE("Missing device transport recv poll handler!");
359                 return -1;
360         }
361
362         rc = ril_device_p->handlers->transport->recv_poll(ril_device_p->handlers->transport->sdata);
363         return rc;
364 }
365
366 int ril_device_recv_loop(struct ril_device *ril_device_p)
367 {
368         // TODO: AT message structure
369         char *data;
370         int count;
371         int rc;
372         int i;
373
374         // Return error after 5 consecutive poll/read failures
375         for(i=5 ; i > 0 ; i--) {
376                 while(1) {
377                         rc = ril_device_recv_poll(ril_device_p);
378                         if(rc < 0) {
379                                 LOGE("Polling from transport recv failed!");
380                                 break;
381                         }
382
383                         count = rc;
384
385                         rc = ril_device_recv(ril_device_p, &data, count);
386                         if(rc < 0) {
387                                 LOGE("Reading from transport recv failed!");
388                                 break;
389                         }
390                         if(rc == 0) LOGE("WERE GOING MAD!!! READING 0 BYTES!!!"); //FIXME
391
392                         // Read works now
393                         if(i != 5)
394                                  i = 5;
395
396                         LOGD("GOT: '%s'", data);
397
398                         //TODO: Convert AT string to AT structures
399                         free(data);
400
401                         //TODO: Dispatch AT structures with multi-message handling (dispatch each)
402                         //TODO: Free AT structures
403                 }
404
405                 // When poll/read failed, close and reopen the device
406                 ril_device_close(ril_device_p);
407                 usleep(500);
408                 ril_device_open(ril_device_p);
409
410                 RIL_DEVICE_UNLOCK(ril_device_p);
411         }
412
413         return -1;
414 }
415
416 void *ril_device_recv_thread(void *data)
417 {
418         struct ril_device *ril_device_p = (struct ril_device *) data;
419         int rc;
420         int i;
421
422         for(i = 5 ; i > 0 ; i--) {
423                 rc = ril_device_recv_loop(ril_device_p);
424                 if(rc < 0) {
425                         LOGE("Recv loop failed too many times, restarting...");
426
427                         rc = ril_device_deinit(ril_device_p);
428                         if(rc < 0)
429                                 break;
430
431                         usleep(500);
432
433                         rc = ril_device_init(ril_device_p);
434                         if(rc < 0)
435                                 break;
436                 }
437         }
438
439         LOGE("Recv thread failed too many times, stopping it all...");
440         ril_device_deinit(ril_device_p);
441
442         return NULL;
443 }
444
445 int ril_device_recv_thread_start(struct ril_device *ril_device_p)
446 {
447         pthread_attr_t attr;
448         int rc;
449
450         if(ril_device_p->handlers == NULL) {
451                 LOGE("Missing device handlers!");
452                 return -1;
453         }
454
455         if(ril_device_p->handlers->transport == NULL) {
456                 LOGE("Missing device transport handlers!");
457                 return -1;
458         }
459
460         pthread_attr_init(&attr);
461         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
462
463         rc = pthread_create(&(ril_device_p->handlers->transport->recv_thread), &attr, ril_device_recv_thread, (void *) ril_device_p);
464         if(rc != 0) {
465                 LOGE("Creating transport recv thread failed!");
466                 return -1;
467         }
468
469         return 0;
470 }