9872ab8d372ef5a3c0237df9e47df75b39417a81
[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 /*
27  * Global
28  */
29
30 int ril_device_init(struct ril_device *ril_device_p)
31 {
32         int rc;
33
34         rc = ril_device_data_create(ril_device_p);
35         if(rc < 0) {
36                 LOGE("Failed to create device data!");
37                 return -1;
38         }
39
40         rc = ril_device_power_on(ril_device_p);
41         if(rc < 0) {
42                 LOGE("Failed to power on device!");
43                 return -1;
44         }
45
46         rc = ril_device_power_boot(ril_device_p);
47         if(rc < 0) {
48                 LOGE("Failed to boot device!");
49                 return -1;
50         }
51
52         rc = ril_device_transport_open(ril_device_p);
53         if(rc < 0) {
54                 LOGE("Failed to open device!");
55                 return -1;
56         }
57
58         return 0;
59 }
60
61 int ril_device_deinit(struct ril_device *ril_device_p)
62 {
63         ril_device_transport_close(ril_device_p);
64
65         ril_device_power_off(ril_device_p);
66
67         ril_device_data_destroy(ril_device_p);
68
69         return 0;
70 }
71
72 int ril_device_data_create(struct ril_device *ril_device_p)
73 {
74         int rc;
75
76         if(ril_device_p->handlers == NULL) {
77                 LOGE("Missing device handlers!");
78                 return -1;
79         }
80
81         if(ril_device_p->handlers->power == NULL) {
82                 LOGE("Missing device power handlers!");
83                 return -1;
84         }
85
86         if(ril_device_p->handlers->power->sdata_create == NULL) {
87                 LOGE("Missing device power data handlers!");
88                 return -1;
89         }
90
91         LOGD("Creating data for power handlers...");
92         rc = ril_device_p->handlers->power->sdata_create(&ril_device_p->handlers->power->sdata);
93         if(rc < 0) {
94                 LOGE("Creating data for power handlers failed!");
95                 return -1;
96         }
97
98         if(ril_device_p->handlers->transport == NULL) {
99                 LOGE("Missing device transport handlers!");
100                 return -1;
101         }
102
103         if(ril_device_p->handlers->transport->sdata_create == NULL) {
104                 LOGE("Missing device transport data handlers!");
105                 return -1;
106         }
107
108         LOGD("Creating data for transport handlers...");
109         ril_device_p->handlers->transport->sdata_create(&ril_device_p->handlers->transport->sdata);
110         if(rc < 0) {
111                 LOGE("Creating data for transport handlers failed!");
112                 return -1;
113         }
114
115         LOGD("Creating mutex for transport handlers...");
116         pthread_mutex_init(&(ril_device_p->handlers->transport->mutex), NULL);
117
118         return 0;
119 }
120
121 int ril_device_data_destroy(struct ril_device *ril_device_p)
122 {
123         int rc;
124
125         if(ril_device_p->handlers == NULL) {
126                 LOGE("Missing device handlers!");
127                 return -1;
128         }
129
130         if(ril_device_p->handlers->power == NULL) {
131                 LOGE("Missing device power handlers!");
132                 return -1;
133         }
134
135         if(ril_device_p->handlers->power->sdata_destroy == NULL) {
136                 LOGE("Missing device power data handlers!");
137                 return -1;
138         }
139
140         LOGD("Destroying data for power handlers...");
141         rc = ril_device_p->handlers->power->sdata_destroy(ril_device_p->handlers->power->sdata);
142         if(rc < 0) {
143                 LOGE("Destroying data for power handlers failed!");
144                 return -1;
145         }
146
147         if(ril_device_p->handlers->transport == NULL) {
148                 LOGE("Missing device transport handlers!");
149                 return -1;
150         }
151
152         if(ril_device_p->handlers->transport->sdata_destroy == NULL) {
153                 LOGE("Missing device transport data handlers!");
154                 return -1;
155         }
156
157         LOGD("Destroying data for transport handlers...");
158         ril_device_p->handlers->transport->sdata_destroy(ril_device_p->handlers->transport->sdata);
159         if(rc < 0) {
160                 LOGE("Destroying data for transport handlers failed!");
161                 return -1;
162         }
163
164         LOGD("Destroying mutex for transport handlers...");
165         pthread_mutex_destroy(&(ril_device_p->handlers->transport->mutex));
166
167         return 0;
168 }
169
170 /*
171  * Power
172  */
173
174 int ril_device_power_on(struct ril_device *ril_device_p)
175 {
176         int rc;
177
178         if(ril_device_p->handlers == NULL) {
179                 LOGE("Missing device handlers!");
180                 return -1;
181         }
182
183         if(ril_device_p->handlers->power == NULL) {
184                 LOGE("Missing device power handlers!");
185                 return -1;
186         }
187
188         if(ril_device_p->handlers->power->power_on == NULL) {
189                 LOGE("Missing device power on handler!");
190                 return -1;
191         }
192
193         LOGD("Powering modem on...");
194
195         rc = ril_device_p->handlers->power->power_on(ril_device_p->handlers->power->sdata);
196         return rc;
197 }
198
199 int ril_device_power_off(struct ril_device *ril_device_p)
200 {
201         int rc;
202
203         if(ril_device_p->handlers == NULL) {
204                 LOGE("Missing device handlers!");
205                 return -1;
206         }
207
208         if(ril_device_p->handlers->power == NULL) {
209                 LOGE("Missing device power handlers!");
210                 return -1;
211         }
212
213         if(ril_device_p->handlers->power->power_off == NULL) {
214                 LOGE("Missing device power off handler!");
215                 return -1;
216         }
217
218         LOGD("Powering modem off...");
219
220         rc = ril_device_p->handlers->power->power_off(ril_device_p->handlers->power->sdata);
221         return rc;
222 }
223
224 int ril_device_power_boot(struct ril_device *ril_device_p)
225 {
226         int rc;
227
228         if(ril_device_p->handlers == NULL) {
229                 LOGE("Missing device handlers!");
230                 return -1;
231         }
232
233         if(ril_device_p->handlers->power == NULL) {
234                 LOGE("Missing device power handlers!");
235                 return -1;
236         }
237
238         if(ril_device_p->handlers->power->boot == NULL) {
239                 LOGE("Missing device power boot handler!");
240                 return -1;
241         }
242
243         LOGD("Booting modem...");
244
245         rc = ril_device_p->handlers->power->boot(ril_device_p->handlers->power->sdata);
246         return rc;
247 }
248
249 /*
250  * Transport
251  */
252
253
254 int ril_device_transport_open(struct ril_device *ril_device_p)
255 {
256         int rc;
257
258         if(ril_device_p->handlers == NULL) {
259                 LOGE("Missing device handlers!");
260                 return -1;
261         }
262
263         if(ril_device_p->handlers->transport == NULL) {
264                 LOGE("Missing device transport handlers!");
265                 return -1;
266         }
267
268         if(ril_device_p->handlers->transport->open == NULL) {
269                 LOGE("Missing device transport open handler!");
270                 return -1;
271         }
272
273         LOGD("Opening modem...");
274
275         rc = ril_device_p->handlers->transport->open(ril_device_p->handlers->transport->sdata);
276         return rc;
277 }
278
279 int ril_device_transport_close(struct ril_device *ril_device_p)
280 {
281         int rc;
282
283         if(ril_device_p->handlers == NULL) {
284                 LOGE("Missing device handlers!");
285                 return -1;
286         }
287
288         if(ril_device_p->handlers->transport == NULL) {
289                 LOGE("Missing device transport handlers!");
290                 return -1;
291         }
292
293         if(ril_device_p->handlers->transport->close == NULL) {
294                 LOGE("Missing device transport close handler!");
295                 return -1;
296         }
297
298         LOGD("Closing modem...");
299
300         rc = ril_device_p->handlers->transport->close(ril_device_p->handlers->transport->sdata);
301         return rc;
302 }
303
304 int ril_device_transport_send(struct ril_device *ril_device_p, void *data, int length)
305 {
306         int rc;
307
308         if(ril_device_p->handlers == NULL) {
309                 LOGE("Missing device handlers!");
310                 return -1;
311         }
312
313         if(ril_device_p->handlers->transport == NULL) {
314                 LOGE("Missing device transport handlers!");
315                 return -1;
316         }
317
318         if(ril_device_p->handlers->transport->send == NULL) {
319                 LOGE("Missing device transport send handler!");
320                 return -1;
321         }
322
323         RIL_DEVICE_LOCK(ril_device_p);
324         rc = ril_device_p->handlers->transport->send(ril_device_p->handlers->transport->sdata, data, length);
325         RIL_DEVICE_UNLOCK(ril_device_p);
326
327         return rc;
328 }
329
330 int ril_device_transport_recv(struct ril_device *ril_device_p, void **data, int length)
331 {
332         int rc;
333
334         if(ril_device_p->handlers == NULL) {
335                 LOGE("Missing device handlers!");
336                 return -1;
337         }
338
339         if(ril_device_p->handlers->transport == NULL) {
340                 LOGE("Missing device transport handlers!");
341                 return -1;
342         }
343
344         if(ril_device_p->handlers->transport->recv == NULL) {
345                 LOGE("Missing device transport recv handler!");
346                 return -1;
347         }
348
349         RIL_DEVICE_LOCK(ril_device_p);
350         rc = ril_device_p->handlers->transport->recv(ril_device_p->handlers->transport->sdata, data, length);
351         RIL_DEVICE_UNLOCK(ril_device_p);
352
353         return rc;
354 }
355
356 int ril_device_transport_recv_poll(struct ril_device *ril_device_p)
357 {
358         int rc;
359
360         if(ril_device_p->handlers == NULL) {
361                 LOGE("Missing device handlers!");
362                 return -1;
363         }
364
365         if(ril_device_p->handlers->transport == NULL) {
366                 LOGE("Missing device transport handlers!");
367                 return -1;
368         }
369
370         if(ril_device_p->handlers->transport->recv_poll == NULL) {
371                 LOGE("Missing device transport recv poll handler!");
372                 return -1;
373         }
374
375         rc = ril_device_p->handlers->transport->recv_poll(ril_device_p->handlers->transport->sdata);
376         return rc;
377 }
378
379 int ril_device_transport_recv_loop(struct ril_device *ril_device_p)
380 {
381         struct at_response **responses = NULL;
382         int responses_count = 0;
383         int responses_queued = 0;
384
385         char *data = NULL;
386         int length = 0;
387         int rc;
388         int i, j;
389
390         // Return error after 5 consecutive poll/read failures
391         for(i=5 ; i > 0 ; i--) {
392                 while(1) {
393                         rc = ril_device_transport_recv_poll(ril_device_p);
394                         if(rc < 0) {
395                                 LOGE("Polling from transport recv failed!");
396                                 break;
397                         }
398
399                         length = rc;
400
401                         rc = ril_device_transport_recv(ril_device_p, &data, length);
402                         if(rc <= 0 || data == NULL) {
403                                 LOGE("Reading from transport recv failed!");
404                                 break;
405                         }
406
407                         length = rc;
408
409                         // Read works now
410                         if(i != 5)
411                                  i = 5;
412
413                         responses_count = at_responses_process(&responses, data, length);
414                         responses_queued = 0;
415
416                         // Log response
417                         RIL_LOG_LOCK();
418                         ril_data_log(data, length);
419                         RIL_LOG_UNLOCK();
420
421                         // Good way to give the recv loop some sleep: call at_send_expect_status
422                         for(j=0 ; j < responses_count ; j++) {
423                                 // Log response
424                                 RIL_LOG_LOCK();
425                                 ril_recv_log(responses[j]);
426                                 RIL_LOG_UNLOCK();
427
428                                 // Handle sync
429                                 rc = at_sync_response_dequeue(responses[j]);
430                                 if(rc < 0) {
431                                         rc = at_response_queue(responses[j]);
432                                         if(rc < 0) {
433                                                 LOGE("Failed to queue response, clearing!");
434                                                 at_response_free(responses[j]);
435                                         } else {
436                                                 responses_queued = 1;
437                                         }
438                                 }
439                         }
440
441                         // Unlock the queue after adding all the requests to the queue (if any)
442                         if(responses_queued)
443                                 at_responses_queue_unlock();
444
445                         free(data);
446                 }
447
448                 // When poll/read failed, close and reopen the device
449                 ril_device_transport_close(ril_device_p);
450                 usleep(500);
451                 ril_device_transport_open(ril_device_p);
452
453                 RIL_DEVICE_UNLOCK(ril_device_p);
454         }
455
456         return -1;
457 }
458
459 void *ril_device_transport_recv_thread(void *data)
460 {
461         struct ril_device *ril_device_p = (struct ril_device *) data;
462         int rc;
463         int i;
464
465         for(i = 5 ; i > 0 ; i--) {
466                 rc = ril_device_transport_recv_loop(ril_device_p);
467                 if(rc < 0) {
468                         LOGE("Recv loop failed too many times, restarting...");
469
470                         rc = ril_device_deinit(ril_device_p);
471                         if(rc < 0)
472                                 break;
473
474                         usleep(500);
475
476                         rc = ril_device_init(ril_device_p);
477                         if(rc < 0)
478                                 break;
479                 }
480         }
481
482         LOGE("Recv thread failed too many times, stopping it all...");
483         ril_device_deinit(ril_device_p);
484
485         return NULL;
486 }
487
488 int ril_device_transport_recv_thread_start(struct ril_device *ril_device_p)
489 {
490         pthread_attr_t attr;
491         int rc;
492
493         if(ril_device_p->handlers == NULL) {
494                 LOGE("Missing device handlers!");
495                 return -1;
496         }
497
498         if(ril_device_p->handlers->transport == NULL) {
499                 LOGE("Missing device transport handlers!");
500                 return -1;
501         }
502
503         pthread_attr_init(&attr);
504         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
505
506         rc = pthread_create(&(ril_device_p->handlers->transport->recv_thread), &attr, ril_device_transport_recv_thread, (void *) ril_device_p);
507         if(rc != 0) {
508                 LOGE("Creating transport recv thread failed!");
509                 return -1;
510         }
511
512         return 0;
513 }