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