daa756a6c40f338e5ebc01a3c6b7db0faaab6965
[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 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 #include <time.h>
23 #include <pthread.h>
24
25 #define LOG_TAG "RIL"
26 #include <utils/Log.h>
27 #include <telephony/ril.h>
28
29 #include "samsung-ril.h"
30 #include "util.h"
31
32 #define RIL_VERSION_STRING "Samsung RIL"
33
34 /**
35  * Samsung-RIL TODO:
36  *
37  * General:
38  * - SIM SMS I/O
39  * - Review code with requests that produce GEN_PHONE_RES messages to use the GEN_PHONE_RES engine
40  *
41  * Data-related:
42  * - find a reliable way to configure data iface
43  * - GPRS: IPC_GPRS_CALL_STATUS, LAST_DATA_CALL_FAIL_CAUSE
44  * - check data with orange non-free ril: no gprs_ip_config
45  * - data: use IPC_GPRS_CALL_STATUS with global token for possible fail or return anyway and store ip config global?
46  * - update global fail cause in global after gprs_call_status, generic error on stored token
47  */
48
49 /**
50  * RIL global vars
51  */
52
53 struct ril_client *ipc_fmt_client;
54 struct ril_client *ipc_rfs_client;
55 struct ril_client *srs_client;
56
57 const struct RIL_Env *ril_env;
58 struct ril_state ril_state;
59
60 /**
61  * RIL request token
62  */
63
64 struct ril_request_token ril_requests_tokens[0x100];
65 int ril_request_id = 0;
66
67 void ril_requests_tokens_init(void)
68 {
69         memset(ril_requests_tokens, 0, sizeof(struct ril_request_token) * 0x100);
70 }
71
72 int ril_request_id_new(void)
73 {
74         ril_request_id++;
75         ril_request_id %= 0x100;
76         return ril_request_id;
77 }
78
79 int ril_request_reg_id(RIL_Token token)
80 {
81         int id = ril_request_id_new();
82
83         ril_requests_tokens[id].token = token;
84         ril_requests_tokens[id].canceled = 0;
85
86         return id;
87 }
88
89 int ril_request_get_id(RIL_Token token)
90 {
91         int i;
92
93         for(i=0 ; i < 0x100 ; i++)
94                 if(ril_requests_tokens[i].token == token)
95                         return i;
96
97         // If the token isn't registered yet, register it
98         return ril_request_reg_id(token);
99 }
100
101 RIL_Token ril_request_get_token(int id)
102 {
103         return ril_requests_tokens[id].token;
104 }
105
106 int ril_request_get_canceled(RIL_Token token)
107 {
108         int id;
109
110         id = ril_request_get_id(token);
111
112         if(ril_requests_tokens[id].canceled > 0)
113                 return 1;
114         else
115                 return 0;
116 }
117
118 void ril_request_set_canceled(RIL_Token token, int canceled)
119 {
120         int id;
121
122         id = ril_request_get_id(token);
123
124         ril_requests_tokens[id].canceled = canceled;
125 }
126
127 void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
128 {
129         if(!ril_request_get_canceled(t))
130                 RIL_onRequestCompleteReal(t, e, response, responselen);
131         else
132                 RIL_onRequestCompleteReal(t, RIL_E_CANCELLED, response, responselen);
133 }
134
135 /**
136  * RIL tokens
137  */
138
139 void ril_tokens_check(void)
140 {
141         RIL_Token t;
142
143         if(ril_state.tokens.baseband_version != 0) {
144                 if(ril_state.radio_state != RADIO_STATE_OFF) {
145                         t = ril_state.tokens.baseband_version;
146                         ril_state.tokens.baseband_version = 0;
147                         ril_request_baseband_version(t);
148                 }
149         }
150
151         if(ril_state.tokens.get_imei != 0 && ril_state.tokens.get_imeisv != 0) {
152                 if(ril_state.radio_state != RADIO_STATE_OFF) {
153                         t = ril_state.tokens.get_imei;
154                         ril_state.tokens.get_imei = 0;
155                         ril_request_get_imei(t);
156                 }
157         }
158 }
159
160 /**
161  * Clients dispatch functions
162  */
163
164 void ipc_fmt_dispatch(struct ipc_message_info *info)
165 {
166         switch(IPC_COMMAND(info)) {
167                 /* GEN */
168                 case IPC_GEN_PHONE_RES:
169                         ipc_gen_phone_res(info);
170                         break;
171                 /* PWR */
172                 case IPC_PWR_PHONE_PWR_UP:
173                         ipc_pwr_phone_pwr_up();
174                         break;
175                 case IPC_PWR_PHONE_STATE:
176                         ipc_pwr_phone_state(info);
177                         break;
178                 /* DISP */
179                 case IPC_DISP_ICON_INFO:
180                         ipc_disp_icon_info(info);
181                         break;
182                 case IPC_DISP_RSSI_INFO:
183                         ipc_disp_rssi_info(info);
184                         break;
185                 /* MISC */
186                 case IPC_MISC_ME_SN:
187                         ipc_misc_me_sn(info);
188                         break;
189                 case IPC_MISC_ME_VERSION:
190                         ipc_misc_me_version(info);
191                         break;
192                 case IPC_MISC_ME_IMSI:
193                         ipc_misc_me_imsi(info);
194                         break;
195                 case IPC_MISC_TIME_INFO:
196                         ipc_misc_time_info(info);
197                         break;
198                 /* SAT */
199                 case IPC_SAT_PROACTIVE_CMD:
200                         respondSatProactiveCmd(info);
201                         break;
202                 case IPC_SAT_ENVELOPE_CMD:
203                         respondSatEnvelopeCmd(info);
204                         break;
205                 /* SS */
206                 case IPC_SS_USSD:
207                         ipc_ss_ussd(info);
208                         break;
209                 /* SEC */
210                 case IPC_SEC_PIN_STATUS:
211                         ipc_sec_pin_status(info);
212                         break;
213                 case IPC_SEC_LOCK_INFO:
214                         ipc_sec_lock_info(info);
215                         break;
216                 case IPC_SEC_RSIM_ACCESS:
217                         ipc_sec_rsim_access(info);
218                         break;
219                 case IPC_SEC_PHONE_LOCK:
220                         ipc_sec_phone_lock(info);
221                         break;
222                 /* NET */
223                 case IPC_NET_CURRENT_PLMN:
224                         ipc_net_current_plmn(info);
225                         break;
226                 case IPC_NET_REGIST:
227                         ipc_net_regist(info);
228                         break;
229                 case IPC_NET_PLMN_LIST:
230                         ipc_net_plmn_list(info);
231                         break;
232                 case IPC_NET_PLMN_SEL:
233                         ipc_net_plmn_sel(info);
234                         break;
235                 case IPC_NET_MODE_SEL:
236                         ipc_net_mode_sel(info);
237                         break;
238                 /* SMS */
239                 case IPC_SMS_INCOMING_MSG:
240                         ipc_sms_incoming_msg(info);
241                         break;
242                 case IPC_SMS_DELIVER_REPORT:
243                         ipc_sms_deliver_report(info);
244                         break;
245                 case IPC_SMS_SVC_CENTER_ADDR:
246                         ipc_sms_svc_center_addr(info);
247                         break;
248                 case IPC_SMS_SEND_MSG:
249                         ipc_sms_send_msg(info);
250                         break;
251                 case IPC_SMS_DEVICE_READY:
252                         ipc_sms_device_ready(info);
253                         break;
254                 /* CALL */
255                 case IPC_CALL_INCOMING:
256                         ipc_call_incoming(info);
257                         break;
258                 case IPC_CALL_LIST:
259                         ipc_call_list(info);
260                         break;
261                 case IPC_CALL_STATUS:
262                         ipc_call_status(info);
263                         break;
264                 case IPC_CALL_BURST_DTMF:
265                         ipc_call_burst_dtmf(info);
266                         break;
267                 /* GPRS */
268                 case IPC_GPRS_IP_CONFIGURATION:
269                         ipc_gprs_ip_configuration(info);
270                         break;
271                 case IPC_GPRS_CALL_STATUS:
272                         ipc_gprs_call_status(info);
273                         break;
274                 case IPC_GPRS_PDP_CONTEXT:
275                         ipc_gprs_pdp_context(info);
276                         break;
277                 default:
278                         LOGD("Unhandled command: %s (%04x)", ipc_command_to_str(IPC_COMMAND(info)), IPC_COMMAND(info));
279                         break;
280         }
281 }
282
283 void ipc_rfs_dispatch(struct ipc_message_info *info)
284 {
285         switch(IPC_COMMAND(info)) {
286                 case IPC_RFS_NV_READ_ITEM:
287                         ipc_rfs_nv_read_item(info);
288                         break;
289                 case IPC_RFS_NV_WRITE_ITEM:
290                         ipc_rfs_nv_write_item(info);
291                         break;
292                 default:
293                         LOGD("Unhandled command: %s (%04x)", ipc_command_to_str(IPC_COMMAND(info)), IPC_COMMAND(info));
294                         break;
295         }
296 }
297
298 void srs_dispatch(struct srs_message *message)
299 {
300         switch(message->command) {
301                 case SRS_CONTROL_PING:
302                         srs_control_ping(message);
303                         break;
304                 case SRS_SND_SET_CALL_CLOCK_SYNC:
305                         srs_snd_set_call_clock_sync(message);
306                         break;
307                 case SRS_SND_SET_CALL_VOLUME:
308                         srs_snd_set_call_volume(message);
309                         break;
310                 case SRS_SND_SET_CALL_AUDIO_PATH:
311                         srs_snd_set_call_audio_path(message);
312                         break;
313                 default:
314                         LOGD("Unhandled command: (%04x)", message->command);
315                         break;
316         }
317 }
318
319 /*
320  * RIL main dispatch function
321  */
322
323 int ril_modem_check(void)
324 {
325         if(ipc_fmt_client == NULL)
326                 return -1;
327
328         if(ipc_fmt_client->state != RIL_CLIENT_READY)
329                 return -1;
330
331         return 0;
332 }
333
334 void onRequest(int request, void *data, size_t datalen, RIL_Token t)
335 {
336         if(ril_modem_check() < 0)
337                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
338
339         switch(request) {
340                 /* PWR */
341                 case RIL_REQUEST_RADIO_POWER:
342                         ril_request_radio_power(t, data, datalen);
343                         break;
344                 case RIL_REQUEST_BASEBAND_VERSION:
345                         ril_request_baseband_version(t);
346                         break;
347                 /* DISP */
348                 case RIL_REQUEST_SIGNAL_STRENGTH:
349                         ril_request_signal_strength(t);
350                         break;
351                 /* MISC */
352                 case RIL_REQUEST_GET_IMEI:
353                         ril_request_get_imei(t);
354                         break;
355                 case RIL_REQUEST_GET_IMEISV:
356                         ril_request_get_imeisv(t);
357                         break;
358                 case RIL_REQUEST_GET_IMSI:
359                         ril_request_get_imsi(t);
360                         break;
361                 /* SAT */
362                 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
363                         requestSatSendTerminalResponse(t, data, datalen);
364                         break;
365                 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
366                         requestSatSendEnvelopeCommand(t, data, datalen);
367                         break;
368                 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
369                         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
370                         break;
371                 /* SS */
372                 case RIL_REQUEST_SEND_USSD:
373                         ril_request_send_ussd(t, data, datalen);
374                         break;
375                 case RIL_REQUEST_CANCEL_USSD:
376                         ril_request_cancel_ussd(t, data, datalen);
377                 /* SEC */
378                 case RIL_REQUEST_GET_SIM_STATUS:
379                         ril_request_get_sim_status(t);
380                         break;
381                 case RIL_REQUEST_SIM_IO:
382                         ril_request_sim_io(t, data, datalen);
383                         break;
384                 case RIL_REQUEST_ENTER_SIM_PIN:
385                         ril_request_enter_sim_pin(t, data, datalen);
386                         break;
387                 case RIL_REQUEST_CHANGE_SIM_PIN:
388                         ril_request_change_sim_pin(t, data, datalen);
389                         break;
390                 case RIL_REQUEST_ENTER_SIM_PUK:
391                         ril_request_enter_sim_puk(t, data, datalen);
392                         break;
393                 case RIL_REQUEST_QUERY_FACILITY_LOCK:
394                         ril_request_query_facility_lock(t, data, datalen);
395                         break;
396                 case RIL_REQUEST_SET_FACILITY_LOCK:
397                         ril_request_set_facility_lock(t, data, datalen);
398                         break;
399                 /* NET */
400                 case RIL_REQUEST_OPERATOR:
401                         ril_request_operator(t);
402                         break;
403                 case RIL_REQUEST_REGISTRATION_STATE:
404                         ril_request_registration_state(t);
405                         break;
406                 case RIL_REQUEST_GPRS_REGISTRATION_STATE:
407                         ril_request_gprs_registration_state(t);
408                         break;
409                 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
410                         ril_request_query_available_networks(t);
411                         break;
412                 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
413                         ril_request_get_preferred_network_type(t);
414                         break;
415                 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
416                         ril_request_set_preferred_network_type(t, data, datalen);
417                         break;
418                 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
419                         ril_request_query_network_selection_mode(t);
420                         break;
421                 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
422                         ril_request_set_network_selection_automatic(t);
423                         break;
424                 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
425                         ril_request_set_network_selection_manual(t, data, datalen);
426                         break;
427                 /* SMS */
428                 case RIL_REQUEST_SEND_SMS:
429                         ril_request_send_sms(t, data, datalen);
430                         break;
431                 case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
432                         ril_request_send_sms_expect_more(t, data, datalen);
433                         break;
434                 case RIL_REQUEST_SMS_ACKNOWLEDGE:
435                         ril_request_sms_acknowledge(t, data, datalen);
436                         break;
437                 /* CALL */
438                 case RIL_REQUEST_DIAL:
439                         ril_request_dial(t, data, datalen);
440                         break;
441                 case RIL_REQUEST_GET_CURRENT_CALLS:
442                         ril_request_get_current_calls(t);
443                         break;
444                 case RIL_REQUEST_HANGUP:
445                 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
446                 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
447                         ril_request_hangup(t);
448                         break;
449                 case RIL_REQUEST_ANSWER:
450                         ril_request_answer(t);
451                         break;
452                 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
453                         ril_request_last_call_fail_cause(t);
454                         break;
455                 case RIL_REQUEST_DTMF:
456                         ril_request_dtmf(t, data, datalen);
457                        break;
458                 case RIL_REQUEST_DTMF_START:
459                         ril_request_dtmf_start(t, data, datalen);
460                        break;
461                 case RIL_REQUEST_DTMF_STOP:
462                         ril_request_dtmf_stop(t);
463                        break;
464                 /* GPRS */
465                 case RIL_REQUEST_SETUP_DATA_CALL:
466                         ril_request_setup_data_call(t, data, datalen);
467                         break;
468                 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
469                         ril_request_deactivate_data_call(t, data, datalen);
470                         break;
471                 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
472                         ril_request_last_data_call_fail_cause(t);
473                         break;
474                 case RIL_REQUEST_DATA_CALL_LIST:
475                         ril_request_data_call_list(t);
476                         break;
477                 /* SND */
478                 case RIL_REQUEST_SET_MUTE:
479                         ril_request_set_mute(t, data, datalen);
480                 /* OTHER */
481                 case RIL_REQUEST_SCREEN_STATE:
482                         /* This doesn't affect anything */
483                         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
484                         break;
485                 default:
486                         LOGE("Request not implemented: %d\n", request);
487                         RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
488                         break;
489         }
490 }
491
492 /**
493  * RILJ related functions
494  */
495
496 RIL_RadioState currentState()
497 {
498         LOGD("currentState()");
499         return ril_state.radio_state;
500 }
501
502 int onSupports(int requestCode)
503 {
504         switch(requestCode) {
505                 default:
506                         return 1;
507         }
508 }
509
510 void onCancel(RIL_Token t)
511 {
512         ril_request_set_canceled(t, 1);
513 }
514
515 const char *getVersion(void)
516 {
517         return RIL_VERSION_STRING;
518 }
519
520 /**
521  * RIL init function
522  */
523
524 void ril_globals_init(void)
525 {
526         memset(&ril_state, 0, sizeof(ril_state));
527         memset(&(ril_state.tokens), 0, sizeof(struct ril_tokens));
528
529         ril_requests_tokens_init();
530         ipc_gen_phone_res_expects_init();
531         ril_gprs_connections_init();
532         ril_request_sms_init();
533         ipc_sms_tpid_queue_init();
534 }
535
536 void ril_state_lpm(void)
537 {
538         ril_state.radio_state = RADIO_STATE_OFF;
539         ril_state.power_mode = POWER_MODE_LPM;
540 }
541
542
543 static const RIL_RadioFunctions ril_ops = {
544         SAMSUNG_RIL_VERSION,
545         onRequest,
546         currentState,
547         onSupports,
548         onCancel,
549         getVersion
550 };
551
552 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
553 {
554         int rc;
555
556         ril_env = env;
557
558 ipc_fmt:
559         LOGD("Creating IPC FMT client");
560
561         ipc_fmt_client = ril_client_new(&ipc_fmt_client_funcs);
562         rc = ril_client_create(ipc_fmt_client);
563
564         if(rc < 0) {
565                 LOGE("IPC FMT client creation failed.");
566                 goto ipc_rfs;
567         }
568
569         rc = ril_client_thread_start(ipc_fmt_client);
570
571         if(rc < 0) {
572                 LOGE("IPC FMT thread creation failed.");
573                 goto ipc_rfs;
574         }
575
576         LOGD("IPC FMT client ready");
577
578 ipc_rfs:
579         LOGD("Creating IPC RFS client");
580
581         ipc_rfs_client = ril_client_new(&ipc_rfs_client_funcs);
582         rc = ril_client_create(ipc_rfs_client);
583
584         if(rc < 0) {
585                 LOGE("IPC RFS client creation failed.");
586                 goto srs;
587         }
588
589         rc = ril_client_thread_start(ipc_rfs_client);
590
591         if(rc < 0) {
592                 LOGE("IPC RFS thread creation failed.");
593                 goto srs;
594         }
595
596         LOGD("IPC RFS client ready");
597
598 srs:
599         LOGD("Creating SRS client");
600
601         srs_client = ril_client_new(&srs_client_funcs);
602         rc = ril_client_create(srs_client);
603
604         if(rc < 0) {
605                 LOGE("SRS client creation failed.");
606                 goto end;
607         }
608
609         rc = ril_client_thread_start(srs_client);
610
611         if(rc < 0) {
612                 LOGE("SRS thread creation failed.");
613                 goto end;
614         }
615
616         LOGD("SRS client ready");
617
618 end:
619         ril_globals_init();
620         ril_state_lpm();
621
622         return &ril_ops;
623 }
624
625 int main(int argc, char *argv[])
626 {
627         return 0;
628 }
629