SRS: Rework to handle multiple clients in a better way
[samsung-ril.git] / samsung-ril.c
1 /**
2  * This file is part of samsung-ril.
3  *
4  * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5  * Copyright (C) 2011-2012 Paul Kocialkowski <contact@oaulk.fr>
6  *
7  * samsung-ril is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * samsung-ril is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with samsung-ril.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #define LOG_TAG "RIL"
23 #include "samsung-ril.h"
24 #include "util.h"
25
26 /**
27  * Samsung-RIL TODO:
28  *
29  * General:
30  * - SIM SMS I/O
31  * - Review code with requests that produce GEN_PHONE_RES messages to use the GEN_PHONE_RES engine
32  *
33  * Data-related:
34  * - find a reliable way to configure data iface
35  * - GPRS: IPC_GPRS_CALL_STATUS, LAST_DATA_CALL_FAIL_CAUSE
36  * - check data with orange non-free ril: no gprs_ip_config
37  * - data: use IPC_GPRS_CALL_STATUS with global token for possible fail or return anyway and store ip config global?
38  * - update global fail cause in global after gprs_call_status, generic error on stored token
39  */
40
41 /**
42  * RIL data
43  */
44
45 struct ril_data ril_data;
46
47 /**
48  * RIL requests
49  */
50
51 int ril_request_id_get(void)
52 {
53         ril_data.request_id++;
54         ril_data.request_id %= 0xff;
55
56         return ril_data.request_id;
57 }
58
59 int ril_request_id_set(int id)
60 {
61         id %= 0xff;
62
63         while(ril_data.request_id < id) {
64                 ril_data.request_id++;
65                 ril_data.request_id %= 0xff;
66         }
67
68         return ril_data.request_id;
69 }
70
71 int ril_request_register(RIL_Token t, int id)
72 {
73         struct ril_request_info *request;
74         struct list_head *list_end;
75         struct list_head *list;
76
77         request = calloc(1, sizeof(struct ril_request_info));
78         if(request == NULL)
79                 return -1;
80
81         request->token = t;
82         request->id = id;
83         request->canceled = 0;
84
85         list_end = ril_data.requests;
86         while(list_end != NULL && list_end->next != NULL)
87                 list_end = list_end->next;
88
89         list = list_head_alloc((void *) request, list_end, NULL);
90
91         if(ril_data.requests == NULL)
92                 ril_data.requests = list;
93
94         return 0;
95 }
96
97 void ril_request_unregister(struct ril_request_info *request)
98 {
99         struct list_head *list;
100
101         if(request == NULL)
102                 return;
103
104         list = ril_data.requests;
105         while(list != NULL) {
106                 if(list->data == (void *) request) {
107                         memset(request, 0, sizeof(struct ril_request_info));
108                         free(request);
109
110                         if(list == ril_data.requests)
111                                 ril_data.requests = list->next;
112
113                         list_head_free(list);
114
115                         break;
116                 }
117 list_continue:
118                 list = list->next;
119         }
120 }
121
122 struct ril_request_info *ril_request_info_find_id(int id)
123 {
124         struct ril_request_info *request;
125         struct list_head *list;
126
127         list = ril_data.requests;
128         while(list != NULL) {
129                 request = (struct ril_request_info *) list->data;
130                 if(request == NULL)
131                         goto list_continue;
132
133                 if(request->id == id)
134                         return request;
135
136 list_continue:
137                 list = list->next;
138         }
139
140         return NULL;
141 }
142
143 struct ril_request_info *ril_request_info_find_token(RIL_Token t)
144 {
145         struct ril_request_info *request;
146         struct list_head *list;
147
148         list = ril_data.requests;
149         while(list != NULL) {
150                 request = (struct ril_request_info *) list->data;
151                 if(request == NULL)
152                         goto list_continue;
153
154                 if(request->token == t)
155                         return request;
156
157 list_continue:
158                 list = list->next;
159         }
160
161         return NULL;
162 }
163
164 int ril_request_set_canceled(RIL_Token t, int canceled)
165 {
166         struct ril_request_info *request;
167
168         request = ril_request_info_find_token(t);
169         if(request == NULL)
170                 return -1;
171
172         request->canceled = canceled ? 1 : 0;
173
174         return 0;
175 }
176
177 int ril_request_get_canceled(RIL_Token t)
178 {
179         struct ril_request_info *request;
180
181         request = ril_request_info_find_token(t);
182         if(request == NULL)
183                 return -1;
184
185         return request->canceled;
186 }
187
188 RIL_Token ril_request_get_token(int id)
189 {
190         struct ril_request_info *request;
191
192         request = ril_request_info_find_id(id);
193         if(request == NULL)
194                 return (RIL_Token) 0x00;
195
196         return request->token;
197 }
198
199 int ril_request_get_id(RIL_Token t)
200 {
201         struct ril_request_info *request;
202         int id, rc;
203
204         request = ril_request_info_find_token(t);
205         if(request != NULL)
206                 return request->id;
207
208         id = ril_request_id_get();
209         rc = ril_request_register(t, id);
210         if(rc < 0)
211                 return -1;
212
213         return id;      
214 }
215
216 void ril_request_complete(RIL_Token t, RIL_Errno e, void *data, size_t length)
217 {
218         struct ril_request_info *request;
219         int canceled = 0;
220
221         request = ril_request_info_find_token(t);
222         if(request == NULL)
223                 goto complete;
224
225         canceled = ril_request_get_canceled(t);
226         ril_request_unregister(request);
227
228         if(canceled)
229                 return;
230
231 complete:
232         ril_data.env->OnRequestComplete(t, e, data, length);
233 }
234
235 void ril_request_unsolicited(int request, void *data, size_t length)
236 {
237         ril_data.env->OnUnsolicitedResponse(request, data, length);
238 }
239
240 void ril_request_timed_callback(RIL_TimedCallback callback, void *data, const struct timeval *time)
241 {
242         ril_data.env->RequestTimedCallback(callback, data, time);
243 }
244
245 /**
246  * RIL tokens
247  */
248
249 void ril_tokens_check(void)
250 {
251         RIL_Token t;
252
253         if(ril_data.tokens.baseband_version != 0) {
254                 if(ril_data.state.radio_state != RADIO_STATE_OFF) {
255                         t = ril_data.tokens.baseband_version;
256                         ril_data.tokens.baseband_version = 0;
257                         ril_request_baseband_version(t);
258                 }
259         }
260
261         if(ril_data.tokens.get_imei != 0 && ril_data.tokens.get_imeisv != 0) {
262                 if(ril_data.state.radio_state != RADIO_STATE_OFF) {
263                         t = ril_data.tokens.get_imei;
264                         ril_data.tokens.get_imei = 0;
265                         ril_request_get_imei(t);
266                 }
267         }
268 }
269
270 /**
271  * Clients dispatch functions
272  */
273
274 void ipc_fmt_dispatch(struct ipc_message_info *info)
275 {
276         if(info == NULL)
277                 return;
278
279         RIL_LOCK();
280
281         ril_request_id_set(info->aseq);
282
283         switch(IPC_COMMAND(info)) {
284                 /* GEN */
285                 case IPC_GEN_PHONE_RES:
286                         ipc_gen_phone_res(info);
287                         break;
288                 /* PWR */
289                 case IPC_PWR_PHONE_PWR_UP:
290                         ipc_pwr_phone_pwr_up();
291                         break;
292                 case IPC_PWR_PHONE_STATE:
293                         ipc_pwr_phone_state(info);
294                         break;
295                 /* DISP */
296                 case IPC_DISP_ICON_INFO:
297                         ipc_disp_icon_info(info);
298                         break;
299                 case IPC_DISP_RSSI_INFO:
300                         ipc_disp_rssi_info(info);
301                         break;
302                 /* MISC */
303                 case IPC_MISC_ME_SN:
304                         ipc_misc_me_sn(info);
305                         break;
306                 case IPC_MISC_ME_VERSION:
307                         ipc_misc_me_version(info);
308                         break;
309                 case IPC_MISC_ME_IMSI:
310                         ipc_misc_me_imsi(info);
311                         break;
312                 case IPC_MISC_TIME_INFO:
313                         ipc_misc_time_info(info);
314                         break;
315                 /* SAT */
316                 case IPC_SAT_PROACTIVE_CMD:
317                         respondSatProactiveCmd(info);
318                         break;
319                 case IPC_SAT_ENVELOPE_CMD:
320                         respondSatEnvelopeCmd(info);
321                         break;
322                 /* SS */
323                 case IPC_SS_USSD:
324                         ipc_ss_ussd(info);
325                         break;
326                 /* SEC */
327                 case IPC_SEC_SIM_STATUS:
328                         ipc_sec_sim_status(info);
329                         break;
330                 case IPC_SEC_LOCK_INFO:
331                         ipc_sec_lock_info(info);
332                         break;
333                 case IPC_SEC_RSIM_ACCESS:
334                         ipc_sec_rsim_access(info);
335                         break;
336                 case IPC_SEC_PHONE_LOCK:
337                         ipc_sec_phone_lock(info);
338                         break;
339                 /* NET */
340                 case IPC_NET_CURRENT_PLMN:
341                         ipc_net_current_plmn(info);
342                         break;
343                 case IPC_NET_REGIST:
344                         ipc_net_regist(info);
345                         break;
346                 case IPC_NET_PLMN_LIST:
347                         ipc_net_plmn_list(info);
348                         break;
349                 case IPC_NET_PLMN_SEL:
350                         ipc_net_plmn_sel(info);
351                         break;
352                 case IPC_NET_MODE_SEL:
353                         ipc_net_mode_sel(info);
354                         break;
355                 /* SMS */
356                 case IPC_SMS_INCOMING_MSG:
357                         ipc_sms_incoming_msg(info);
358                         break;
359                 case IPC_SMS_DELIVER_REPORT:
360                         ipc_sms_deliver_report(info);
361                         break;
362                 case IPC_SMS_SVC_CENTER_ADDR:
363                         ipc_sms_svc_center_addr(info);
364                         break;
365                 case IPC_SMS_SEND_MSG:
366                         ipc_sms_send_msg(info);
367                         break;
368                 case IPC_SMS_DEVICE_READY:
369                         ipc_sms_device_ready(info);
370                         break;
371                 /* CALL */
372                 case IPC_CALL_INCOMING:
373                         ipc_call_incoming(info);
374                         break;
375                 case IPC_CALL_LIST:
376                         ipc_call_list(info);
377                         break;
378                 case IPC_CALL_STATUS:
379                         ipc_call_status(info);
380                         break;
381                 case IPC_CALL_BURST_DTMF:
382                         ipc_call_burst_dtmf(info);
383                         break;
384                 /* GPRS */
385                 case IPC_GPRS_IP_CONFIGURATION:
386                         ipc_gprs_ip_configuration(info);
387                         break;
388                 case IPC_GPRS_CALL_STATUS:
389                         ipc_gprs_call_status(info);
390                         break;
391                 case IPC_GPRS_PDP_CONTEXT:
392                         ipc_gprs_pdp_context(info);
393                         break;
394                 default:
395                         LOGE("%s: Unhandled request: %s (%04x)", __func__, ipc_command_to_str(IPC_COMMAND(info)), IPC_COMMAND(info));
396                         break;
397         }
398
399         RIL_UNLOCK();
400 }
401
402 void ipc_rfs_dispatch(struct ipc_message_info *info)
403 {
404         if(info == NULL)
405                 return;
406
407         RIL_LOCK();
408
409         switch(IPC_COMMAND(info)) {
410                 case IPC_RFS_NV_READ_ITEM:
411                         ipc_rfs_nv_read_item(info);
412                         break;
413                 case IPC_RFS_NV_WRITE_ITEM:
414                         ipc_rfs_nv_write_item(info);
415                         break;
416                 default:
417                         LOGE("%s: Unhandled request: %s (%04x)", __func__, ipc_command_to_str(IPC_COMMAND(info)), IPC_COMMAND(info));
418                         break;
419         }
420
421         RIL_UNLOCK();
422 }
423
424 void srs_dispatch(struct srs_message *message)
425 {
426         if(message == NULL)
427                 return;
428
429         RIL_LOCK();
430
431         switch(message->command) {
432                 case SRS_CONTROL_PING:
433                         srs_control_ping(message);
434                         break;
435                 case SRS_SND_SET_CALL_CLOCK_SYNC:
436                         srs_snd_set_call_clock_sync(message);
437                         break;
438                 case SRS_SND_SET_CALL_VOLUME:
439                         srs_snd_set_call_volume(message);
440                         break;
441                 case SRS_SND_SET_CALL_AUDIO_PATH:
442                         srs_snd_set_call_audio_path(message);
443                         break;
444                 default:
445                         LOGE("%s: Unhandled request: (%04x)", __func__, message->command);
446                         break;
447         }
448
449         RIL_UNLOCK();
450 }
451
452 /*
453  * RIL interface
454  */
455
456 void ril_on_request(int request, void *data, size_t length, RIL_Token t)
457 {
458         RIL_LOCK();
459
460         switch(request) {
461                 /* PWR */
462                 case RIL_REQUEST_RADIO_POWER:
463                         ril_request_radio_power(t, data, length);
464                         break;
465                 case RIL_REQUEST_BASEBAND_VERSION:
466                         ril_request_baseband_version(t);
467                         break;
468                 /* DISP */
469                 case RIL_REQUEST_SIGNAL_STRENGTH:
470                         ril_request_signal_strength(t);
471                         break;
472                 /* MISC */
473                 case RIL_REQUEST_GET_IMEI:
474                         ril_request_get_imei(t);
475                         break;
476                 case RIL_REQUEST_GET_IMEISV:
477                         ril_request_get_imeisv(t);
478                         break;
479                 case RIL_REQUEST_GET_IMSI:
480                         ril_request_get_imsi(t);
481                         break;
482                 /* SAT */
483                 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
484                         requestSatSendTerminalResponse(t, data, length);
485                         break;
486                 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
487                         requestSatSendEnvelopeCommand(t, data, length);
488                         break;
489                 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
490                         ril_request_complete(t, RIL_E_SUCCESS, NULL, 0);
491                         break;
492                 /* SS */
493                 case RIL_REQUEST_SEND_USSD:
494                         ril_request_send_ussd(t, data, length);
495                         break;
496                 case RIL_REQUEST_CANCEL_USSD:
497                         ril_request_cancel_ussd(t, data, length);
498                         break;
499                 /* SEC */
500                 case RIL_REQUEST_GET_SIM_STATUS:
501                         ril_request_get_sim_status(t);
502                         break;
503                 case RIL_REQUEST_SIM_IO:
504                         ril_request_sim_io(t, data, length);
505                         break;
506                 case RIL_REQUEST_ENTER_SIM_PIN:
507                         ril_request_enter_sim_pin(t, data, length);
508                         break;
509                 case RIL_REQUEST_CHANGE_SIM_PIN:
510                         ril_request_change_sim_pin(t, data, length);
511                         break;
512                 case RIL_REQUEST_ENTER_SIM_PUK:
513                         ril_request_enter_sim_puk(t, data, length);
514                         break;
515                 case RIL_REQUEST_QUERY_FACILITY_LOCK:
516                         ril_request_query_facility_lock(t, data, length);
517                         break;
518                 case RIL_REQUEST_SET_FACILITY_LOCK:
519                         ril_request_set_facility_lock(t, data, length);
520                         break;
521                 /* NET */
522                 case RIL_REQUEST_OPERATOR:
523                         ril_request_operator(t);
524                         break;
525                 case RIL_REQUEST_REGISTRATION_STATE:
526                         ril_request_registration_state(t);
527                         break;
528                 case RIL_REQUEST_GPRS_REGISTRATION_STATE:
529                         ril_request_gprs_registration_state(t);
530                         break;
531                 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
532                         ril_request_query_available_networks(t);
533                         break;
534                 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
535                         ril_request_get_preferred_network_type(t);
536                         break;
537                 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
538                         ril_request_set_preferred_network_type(t, data, length);
539                         break;
540                 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
541                         ril_request_query_network_selection_mode(t);
542                         break;
543                 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
544                         ril_request_set_network_selection_automatic(t);
545                         break;
546                 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
547                         ril_request_set_network_selection_manual(t, data, length);
548                         break;
549                 /* SMS */
550                 case RIL_REQUEST_SEND_SMS:
551                         ril_request_send_sms(t, data, length);
552                         break;
553                 case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
554                         ril_request_send_sms_expect_more(t, data, length);
555                         break;
556                 case RIL_REQUEST_SMS_ACKNOWLEDGE:
557                         ril_request_sms_acknowledge(t, data, length);
558                         break;
559                 /* CALL */
560                 case RIL_REQUEST_DIAL:
561                         ril_request_dial(t, data, length);
562                         break;
563                 case RIL_REQUEST_GET_CURRENT_CALLS:
564                         ril_request_get_current_calls(t);
565                         break;
566                 case RIL_REQUEST_HANGUP:
567                 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
568                 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
569                         ril_request_hangup(t);
570                         break;
571                 case RIL_REQUEST_ANSWER:
572                         ril_request_answer(t);
573                         break;
574                 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
575                         ril_request_last_call_fail_cause(t);
576                         break;
577                 case RIL_REQUEST_DTMF:
578                         ril_request_dtmf(t, data, length);
579                         break;
580                 case RIL_REQUEST_DTMF_START:
581                         ril_request_dtmf_start(t, data, length);
582                         break;
583                 case RIL_REQUEST_DTMF_STOP:
584                         ril_request_dtmf_stop(t);
585                         break;
586                 /* GPRS */
587                 case RIL_REQUEST_SETUP_DATA_CALL:
588                         ril_request_setup_data_call(t, data, length);
589                         break;
590                 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
591                         ril_request_deactivate_data_call(t, data, length);
592                         break;
593                 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
594                         ril_request_last_data_call_fail_cause(t);
595                         break;
596                 case RIL_REQUEST_DATA_CALL_LIST:
597                         ril_request_data_call_list(t);
598                         break;
599                 /* SND */
600                 case RIL_REQUEST_SET_MUTE:
601                         ril_request_set_mute(t, data, length);
602                         break;
603                 /* OTHER */
604                 case RIL_REQUEST_SCREEN_STATE:
605                         /* This doesn't affect anything */
606                         ril_request_complete(t, RIL_E_SUCCESS, NULL, 0);
607                         break;
608                 default:
609                         LOGE("%s: Unhandled request: %d", __func__, request);
610                         ril_request_complete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
611                         break;
612         }
613
614         RIL_UNLOCK();
615 }
616
617 RIL_RadioState ril_on_state_request(void)
618 {
619         return ril_data.state.radio_state;
620 }
621
622 int ril_on_supports(int request)
623 {
624         return 1;
625 }
626
627 void ril_on_cancel(RIL_Token t)
628 {
629         ril_request_set_canceled(t, 1);
630 }
631
632 const char *ril_get_version(void)
633 {
634         return RIL_VERSION_STRING;
635 }
636
637 /**
638  * RIL init
639  */
640
641 void ril_data_init(void)
642 {
643         memset(&ril_data, 0, sizeof(ril_data));
644
645         pthread_mutex_init(&ril_data.mutex, NULL);
646 }
647
648 /**
649  * RIL interface
650  */
651
652 static const RIL_RadioFunctions ril_ops = {
653         SAMSUNG_RIL_VERSION,
654         ril_on_request,
655         ril_on_state_request,
656         ril_on_supports,
657         ril_on_cancel,
658         ril_get_version
659 };
660
661 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
662 {
663         struct ril_client *ipc_fmt_client;
664         struct ril_client *ipc_rfs_client;
665         struct ril_client *srs_client;
666         int rc;
667
668         if(env == NULL)
669                 return NULL;
670
671         ril_data_init();
672         ril_data.env = (struct RIL_Env *) env;
673
674         RIL_LOCK();
675
676         LOGD("Creating IPC FMT client");
677
678         ipc_fmt_client = ril_client_new(&ipc_fmt_client_funcs);
679         rc = ril_client_create(ipc_fmt_client);
680
681         if(rc < 0) {
682                 LOGE("IPC FMT client creation failed.");
683                 goto ipc_rfs;
684         }
685
686         rc = ril_client_thread_start(ipc_fmt_client);
687
688         if(rc < 0) {
689                 LOGE("IPC FMT thread creation failed.");
690                 goto ipc_rfs;
691         }
692
693         ril_data.ipc_fmt_client = ipc_fmt_client;
694         LOGD("IPC FMT client ready");
695
696 ipc_rfs:
697         LOGD("Creating IPC RFS client");
698
699         ipc_rfs_client = ril_client_new(&ipc_rfs_client_funcs);
700         rc = ril_client_create(ipc_rfs_client);
701
702         if(rc < 0) {
703                 LOGE("IPC RFS client creation failed.");
704                 goto srs;
705         }
706
707         rc = ril_client_thread_start(ipc_rfs_client);
708
709         if(rc < 0) {
710                 LOGE("IPC RFS thread creation failed.");
711                 goto srs;
712         }
713
714         ril_data.ipc_rfs_client = ipc_rfs_client;
715         LOGD("IPC RFS client ready");
716
717 srs:
718         LOGD("Creating SRS client");
719
720         srs_client = ril_client_new(&srs_client_funcs);
721         rc = ril_client_create(srs_client);
722
723         if(rc < 0) {
724                 LOGE("SRS client creation failed.");
725                 goto end;
726         }
727
728         rc = ril_client_thread_start(srs_client);
729
730         if(rc < 0) {
731                 LOGE("SRS thread creation failed.");
732                 goto end;
733         }
734
735         ril_data.srs_client = srs_client;
736         LOGD("SRS client ready");
737
738 end:
739         ril_data.state.radio_state = RADIO_STATE_OFF;
740         ril_data.state.power_state = IPC_PWR_PHONE_STATE_LPM;
741
742         RIL_UNLOCK();
743
744         return &ril_ops;
745 }