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