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