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