AT: Various code fixes, new async handled code, spare status/error handling
[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         struct at_response **responses = NULL;
369         int responses_count = 0;
370
371         char *data = NULL;
372         int length = 0;
373         int rc;
374         int i, j;
375
376         // Return error after 5 consecutive poll/read failures
377         for(i=5 ; i > 0 ; i--) {
378                 while(1) {
379                         rc = ril_device_recv_poll(ril_device_p);
380                         if(rc < 0) {
381                                 LOGE("Polling from transport recv failed!");
382                                 break;
383                         }
384
385                         length = rc;
386
387                         rc = ril_device_recv(ril_device_p, &data, length);
388                         if(rc <= 0 || data == NULL) {
389                                 LOGE("Reading from transport recv failed!");
390                                 break;
391                         }
392
393                         length = rc;
394
395                         // Read works now
396                         if(i != 5)
397                                  i = 5;
398
399                         responses_count = at_responses_process(&responses, data, length);
400
401                         // Log response
402                         RIL_LOG_LOCK();
403                         ril_data_log(data, length);
404                         RIL_LOG_UNLOCK();
405
406                         // Good way to give the recv loop some sleep: call at_send_expect_status
407                         for(j=0 ; j < responses_count ; j++) {
408                                 // Log response
409                                 RIL_LOG_LOCK();
410                                 ril_recv_log(responses[j]);
411                                 RIL_LOG_UNLOCK();
412
413                                 rc = at_response_expect_status(responses[j]);
414                                 if(rc < 0) {
415                                         rc = at_response_queue(responses[j]);
416                                         if(rc < 0) {
417                                                 LOGE("Failed to queue response, clearing!");
418                                                 at_response_free(responses[j]);
419                                         }
420                                 }
421                         }
422
423                         free(data);
424                 }
425
426                 // When poll/read failed, close and reopen the device
427                 ril_device_close(ril_device_p);
428                 usleep(500);
429                 ril_device_open(ril_device_p);
430
431                 RIL_DEVICE_UNLOCK(ril_device_p);
432         }
433
434         return -1;
435 }
436
437 void *ril_device_recv_thread(void *data)
438 {
439         struct ril_device *ril_device_p = (struct ril_device *) data;
440         int rc;
441         int i;
442
443         for(i = 5 ; i > 0 ; i--) {
444                 rc = ril_device_recv_loop(ril_device_p);
445                 if(rc < 0) {
446                         LOGE("Recv loop failed too many times, restarting...");
447
448                         rc = ril_device_deinit(ril_device_p);
449                         if(rc < 0)
450                                 break;
451
452                         usleep(500);
453
454                         rc = ril_device_init(ril_device_p);
455                         if(rc < 0)
456                                 break;
457                 }
458         }
459
460         LOGE("Recv thread failed too many times, stopping it all...");
461         ril_device_deinit(ril_device_p);
462
463         return NULL;
464 }
465
466 int ril_device_recv_thread_start(struct ril_device *ril_device_p)
467 {
468         pthread_attr_t attr;
469         int rc;
470
471         if(ril_device_p->handlers == NULL) {
472                 LOGE("Missing device handlers!");
473                 return -1;
474         }
475
476         if(ril_device_p->handlers->transport == NULL) {
477                 LOGE("Missing device transport handlers!");
478                 return -1;
479         }
480
481         pthread_attr_init(&attr);
482         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
483
484         rc = pthread_create(&(ril_device_p->handlers->transport->recv_thread), &attr, ril_device_recv_thread, (void *) ril_device_p);
485         if(rc != 0) {
486                 LOGE("Creating transport recv thread failed!");
487                 return -1;
488         }
489
490         return 0;
491 }