Define and use RIL_TOKEN_NULL
[samsung-ril.git] / sec.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-SEC"
23 #include <utils/Log.h>
24
25 #include "samsung-ril.h"
26 #include "util.h"
27
28 #include <sim.h>
29
30 ril_sim_state ipc2ril_sim_state(struct ipc_sec_sim_status_response *pin_status)
31 {
32         if (pin_status == NULL)
33                 return -EINVAL;
34
35         switch(pin_status->status) {
36                 case IPC_SEC_SIM_STATUS_LOCK_SC:
37                         switch(pin_status->facility_lock) {
38                                 case IPC_SEC_FACILITY_LOCK_TYPE_SC_UNLOCKED:
39                                         return SIM_STATE_READY;
40                                 case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ:
41                                         return SIM_STATE_PIN;
42                                 case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ:
43                                         return SIM_STATE_PUK;
44                                 case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED:
45                                         return SIM_STATE_BLOCKED;
46                                 default:
47                                         LOGE("Unknown SIM facility lock: 0x%x", pin_status->facility_lock);
48                                         return SIM_STATE_ABSENT;
49                         }
50                         break;
51                 case IPC_SEC_SIM_STATUS_LOCK_FD:
52                         return SIM_STATE_ABSENT;
53                 case IPC_SEC_SIM_STATUS_LOCK_PN:
54                         return SIM_STATE_NETWORK_PERSO;
55                 case IPC_SEC_SIM_STATUS_LOCK_PU:
56                         return SIM_STATE_NETWORK_SUBSET_PERSO;
57                 case IPC_SEC_SIM_STATUS_LOCK_PP:
58                         return SIM_STATE_SERVICE_PROVIDER_PERSO;
59                 case IPC_SEC_SIM_STATUS_LOCK_PC:
60                         return SIM_STATE_CORPORATE_PERSO;
61                 case IPC_SEC_SIM_STATUS_READY:
62                 case IPC_SEC_SIM_STATUS_INIT_COMPLETE:
63                 case IPC_SEC_SIM_STATUS_PB_INIT_COMPLETE:
64                         return SIM_STATE_READY;
65                 case IPC_SEC_SIM_STATUS_SIM_LOCK_REQUIRED:
66                 case IPC_SEC_SIM_STATUS_INSIDE_PF_ERROR:
67                 case IPC_SEC_SIM_STATUS_CARD_NOT_PRESENT:
68                 case IPC_SEC_SIM_STATUS_CARD_ERROR:
69                         return SIM_STATE_ABSENT;
70                 default:
71                         LOGE("Unknown SIM status: 0x%x", pin_status->status);
72                         return SIM_STATE_ABSENT;
73         }
74 }
75
76 void ril_state_update(ril_sim_state sim_state)
77 {
78         RIL_RadioState radio_state;
79
80         /* If power mode isn't at least normal, don't update RIL state */
81         if (ril_data.state.power_state != IPC_PWR_PHONE_STATE_NORMAL)
82                 return;
83
84         ril_data.state.sim_state = sim_state;
85
86         switch(sim_state) {
87                 case SIM_STATE_READY:
88 #if RIL_VERSION >= 7
89                         radio_state = RADIO_STATE_ON;
90 #else
91                         radio_state = RADIO_STATE_SIM_READY;
92 #endif
93                         break;
94                 case SIM_STATE_NOT_READY:
95                         radio_state = RADIO_STATE_SIM_NOT_READY;
96                         break;
97                 case SIM_STATE_ABSENT:
98                 case SIM_STATE_PIN:
99                 case SIM_STATE_PUK:
100                 case SIM_STATE_BLOCKED:
101                 case SIM_STATE_NETWORK_PERSO:
102                 case SIM_STATE_NETWORK_SUBSET_PERSO:
103                 case SIM_STATE_CORPORATE_PERSO:
104                 case SIM_STATE_SERVICE_PROVIDER_PERSO:
105                         radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT;
106                         break;
107                 default:
108                         radio_state = RADIO_STATE_SIM_NOT_READY;
109                         break;
110         }
111
112         LOGD("Setting radio state to %x", radio_state);
113         ril_data.state.radio_state = radio_state;
114
115         ril_tokens_check();
116
117         ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
118 }
119
120 #if RIL_VERSION >= 6
121 void ipc2ril_card_status(struct ipc_sec_sim_status_response *pin_status, RIL_CardStatus_v6 *card_status)
122 #else
123 void ipc2ril_card_status(struct ipc_sec_sim_status_response *pin_status, RIL_CardStatus *card_status)
124 #endif
125 {
126         ril_sim_state sim_state;
127         int app_status_array_length;
128         int app_index;
129         int i;
130
131         if (pin_status == NULL || card_status == NULL)
132                 return;
133
134         static RIL_AppStatus app_status_array[] = {
135                 /* SIM_ABSENT = 0 */
136                 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
137                 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
138                 /* SIM_NOT_READY = 1 */
139                 { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
140                 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
141                 /* SIM_READY = 2 */
142                 { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
143                 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
144                 /* SIM_PIN = 3 */
145                 { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
146                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
147                 /* SIM_PUK = 4 */
148                 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
149                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
150                 /* SIM_BLOCKED = 4 */
151                 { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
152                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_PERM_BLOCKED, RIL_PINSTATE_UNKNOWN },
153                 /* SIM_NETWORK_PERSO = 6 */
154                 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
155                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
156                 /* SIM_NETWORK_SUBSET_PERSO = 7 */
157                 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET,
158                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
159                 /* SIM_CORPORATE_PERSO = 8 */
160                 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_CORPORATE,
161                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
162                 /* SIM_SERVICE_PROVIDER_PERSO = 9 */
163                 { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
164                 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
165         };
166
167         app_status_array_length = sizeof(app_status_array) / sizeof(RIL_AppStatus);
168
169         if (app_status_array_length > RIL_CARD_MAX_APPS)
170                 app_status_array_length = RIL_CARD_MAX_APPS;
171
172         sim_state = ipc2ril_sim_state(pin_status);
173
174         /* Card is assumed to be present if not explicitly absent */
175         if (sim_state == SIM_STATE_ABSENT) {
176                 card_status->card_state = RIL_CARDSTATE_ABSENT;
177         } else {
178                 card_status->card_state = RIL_CARDSTATE_PRESENT;
179         }
180
181         // FIXME: How do we know that?
182         card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
183
184         // Initialize the apps
185         for (i = 0 ; i < app_status_array_length ; i++) {
186                 memcpy((void *) &(card_status->applications[i]), (void *) &(app_status_array[i]), sizeof(RIL_AppStatus));
187         }
188         for (i = app_status_array_length ; i < RIL_CARD_MAX_APPS ; i++) {
189                 memset((void *) &(card_status->applications[i]), 0, sizeof(RIL_AppStatus));
190         }
191
192         // sim_state corresponds to the app index on the table
193         card_status->gsm_umts_subscription_app_index = (int) sim_state;
194         card_status->cdma_subscription_app_index = (int) sim_state;
195         card_status->num_applications = app_status_array_length;
196
197         LOGD("Selecting application #%d on %d", (int) sim_state, app_status_array_length);
198 }
199
200 void ril_tokens_pin_status_dump(void)
201 {
202         LOGD("ril_tokens_pin_status_dump:\n\
203         \tril_data.tokens.pin_status = %p\n", ril_data.tokens.pin_status);
204 }
205
206 void ipc_sec_sim_status(struct ipc_message_info *info)
207 {
208         struct ipc_sec_sim_status_response *pin_status;
209         RIL_Token t;
210 #if RIL_VERSION >= 6
211         RIL_CardStatus_v6 card_status;
212 #else
213         RIL_CardStatus card_status;
214 #endif
215         ril_sim_state sim_state;
216
217         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sec_sim_status_response))
218                 goto error;
219
220         pin_status = (struct ipc_sec_sim_status_response *) info->data;
221         t = ril_request_get_token(info->aseq);
222
223         switch(info->type) {
224                 case IPC_TYPE_NOTI:
225                         // Don't consider this if modem isn't in normal power mode
226                         if (ril_data.state.power_state != IPC_PWR_PHONE_STATE_NORMAL)
227                                 return;
228
229                         LOGD("Got UNSOL PIN status message");
230
231                         if (ril_data.tokens.pin_status != RIL_TOKEN_NULL && ril_data.tokens.pin_status != RIL_TOKEN_DATA_WAITING) {
232                                 LOGE("Another PIN status Req is in progress, skipping");
233                                 return;
234                         }
235
236                         sim_state = ipc2ril_sim_state(pin_status);
237                         ril_state_update(sim_state);
238
239                         memcpy(&(ril_data.state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
240
241                         ril_data.tokens.pin_status = RIL_TOKEN_DATA_WAITING;
242                         ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
243                         break;
244                 case IPC_TYPE_RESP:
245                         LOGD("Got SOL PIN status message");
246
247                         if (ril_data.tokens.pin_status != t)
248                                 LOGE("PIN status tokens mismatch");
249
250                         sim_state = ipc2ril_sim_state(pin_status);
251                         ril_state_update(sim_state);
252
253                         // Better keeping this up to date
254                         memcpy(&(ril_data.state.sim_pin_status), pin_status, sizeof(struct ipc_sec_sim_status_response));
255
256                         ipc2ril_card_status(pin_status, &card_status);
257                         ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
258
259                         if (ril_data.tokens.pin_status != RIL_TOKEN_DATA_WAITING)
260                                 ril_data.tokens.pin_status = RIL_TOKEN_NULL;
261                         break;
262                 default:
263                         LOGE("%s: unhandled ipc method: %d", __func__, info->type);
264                         break;
265         }
266
267         ril_tokens_pin_status_dump();
268
269         return;
270
271 error:
272         if (info != NULL)
273                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
274 }
275
276 void ril_request_get_sim_status(RIL_Token t)
277 {
278         struct ipc_sec_sim_status_response *pin_status;
279 #if RIL_VERSION >= 6
280         RIL_CardStatus_v6 card_status;
281 #else
282         RIL_CardStatus card_status;
283 #endif
284
285         if (ril_data.tokens.pin_status == RIL_TOKEN_DATA_WAITING) {
286                 LOGD("Got RILJ request for UNSOL data");
287                 hex_dump(&(ril_data.state.sim_pin_status), sizeof(struct ipc_sec_sim_status_response));
288                 pin_status = &(ril_data.state.sim_pin_status);
289
290                 ipc2ril_card_status(pin_status, &card_status);
291
292                 ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
293
294                 ril_data.tokens.pin_status = RIL_TOKEN_NULL;
295         } else if (ril_data.tokens.pin_status == RIL_TOKEN_NULL) {
296                 LOGD("Got RILJ request for SOL data");
297
298                 /* Request data to the modem */
299                 ril_data.tokens.pin_status = t;
300
301                 ipc_fmt_send_get(IPC_SEC_SIM_STATUS, ril_request_get_id(t));
302         } else {
303                 LOGE("Another request is going on, returning UNSOL data");
304
305                 pin_status = &(ril_data.state.sim_pin_status);
306
307                 ipc2ril_card_status(pin_status, &card_status);
308                 ril_request_complete(t, RIL_E_SUCCESS, &card_status, sizeof(card_status));
309         }
310
311         ril_tokens_pin_status_dump();
312 }
313
314 void ipc_sec_sim_icc_type(struct ipc_message_info *info)
315 {
316         struct ipc_sec_sim_icc_type *sim_icc_type;
317
318         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sec_sim_icc_type))
319                 goto error;
320
321         sim_icc_type = (struct ipc_sec_sim_icc_type *) info->data;
322
323         memcpy(&ril_data.state.sim_icc_type, sim_icc_type, sizeof(struct ipc_sec_sim_icc_type));
324
325         return;
326
327 error:
328         if (info != NULL)
329                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
330 }
331
332 /*
333  * SIM I/O
334  */
335
336 int ril_request_sim_io_register(RIL_Token t, unsigned char command, unsigned short fileid,
337         unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length,
338         struct ril_request_sim_io_info **sim_io_p)
339 {
340         struct ril_request_sim_io_info *sim_io;
341         struct list_head *list_end;
342         struct list_head *list;
343
344         sim_io = calloc(1, sizeof(struct ril_request_sim_io_info));
345         if (sim_io == NULL)
346                 return -1;
347
348         sim_io->command = command;
349         sim_io->fileid = fileid;
350         sim_io->p1 = p1;
351         sim_io->p2 = p2;
352         sim_io->p3 = p3;
353         sim_io->data = data;
354         sim_io->length = length;
355         sim_io->waiting = 1;
356         sim_io->token = t;
357
358         list_end = ril_data.sim_io;
359         while (list_end != NULL && list_end->next != NULL)
360                 list_end = list_end->next;
361
362         list = list_head_alloc((void *) sim_io, list_end, NULL);
363
364         if (ril_data.sim_io == NULL)
365                 ril_data.sim_io = list;
366
367         if (sim_io_p != NULL)
368                 *sim_io_p = sim_io;
369
370         return 0;
371 }
372
373 void ril_request_sim_io_unregister(struct ril_request_sim_io_info *sim_io)
374 {
375         struct list_head *list;
376
377         if (sim_io == NULL)
378                 return;
379
380         list = ril_data.sim_io;
381         while (list != NULL) {
382                 if (list->data == (void *) sim_io) {
383                         memset(sim_io, 0, sizeof(struct ril_request_sim_io_info));
384                         free(sim_io);
385
386                         if (list == ril_data.sim_io)
387                                 ril_data.sim_io = list->next;
388
389                         list_head_free(list);
390
391                         break;
392                 }
393 list_continue:
394                 list = list->next;
395         }
396 }
397
398 struct ril_request_sim_io_info *ril_request_sim_io_info_find(void)
399 {
400         struct ril_request_sim_io_info *sim_io;
401         struct list_head *list;
402
403         list = ril_data.sim_io;
404         while (list != NULL) {
405                 sim_io = (struct ril_request_sim_io_info *) list->data;
406                 if (sim_io == NULL)
407                         goto list_continue;
408
409                 return sim_io;
410
411 list_continue:
412                 list = list->next;
413         }
414
415         return NULL;
416 }
417
418 struct ril_request_sim_io_info *ril_request_sim_io_info_find_token(RIL_Token t)
419 {
420         struct ril_request_sim_io_info *sim_io;
421         struct list_head *list;
422
423         list = ril_data.sim_io;
424         while (list != NULL) {
425                 sim_io = (struct ril_request_sim_io_info *) list->data;
426                 if (sim_io == NULL)
427                         goto list_continue;
428
429                 if (sim_io->token == t)
430                         return sim_io;
431
432 list_continue:
433                 list = list->next;
434         }
435
436         return NULL;
437 }
438
439 void ril_request_sim_io_info_clear(struct ril_request_sim_io_info *sim_io)
440 {
441         if (sim_io == NULL)
442                 return;
443
444         if (sim_io->data != NULL)
445                 free(sim_io->data);
446 }
447
448 void ril_request_sim_io_next(void)
449 {
450         struct ril_request_sim_io_info *sim_io;
451         int rc;
452
453         ril_data.tokens.sim_io = RIL_TOKEN_NULL;
454
455         sim_io = ril_request_sim_io_info_find();
456         if (sim_io == NULL)
457                 return;
458
459         sim_io->waiting = 0;
460         ril_data.tokens.sim_io = sim_io->token;
461
462         ril_request_sim_io_complete(sim_io->token, sim_io->command, sim_io->fileid,
463                 sim_io->p1, sim_io->p2, sim_io->p3, sim_io->data, sim_io->length);
464
465         if (sim_io->data != NULL)
466                 free(sim_io->data);
467         sim_io->data = NULL;
468         sim_io->length = 0;
469 }
470
471 void ril_request_sim_io_complete(RIL_Token t, unsigned char command, unsigned short fileid,
472         unsigned char p1, unsigned char p2, unsigned char p3, void *data, int length)
473 {
474         struct ipc_sec_rsim_access_get *rsim_access = NULL;
475         void *rsim_access_data = NULL;
476         int rsim_access_length = 0;
477
478         rsim_access_length += sizeof(struct ipc_sec_rsim_access_get);
479
480         if (data != NULL && length > 0)
481                 rsim_access_length += length;
482
483         rsim_access_data = calloc(1, rsim_access_length);
484         rsim_access = (struct ipc_sec_rsim_access_get *) rsim_access_data;
485
486         rsim_access->command = command;
487         rsim_access->fileid = fileid;
488         rsim_access->p1 = p1;
489         rsim_access->p2 = p2;
490         rsim_access->p3 = p3;
491
492         if (data != NULL && length > 0)
493                 memcpy((void *) ((int) rsim_access_data + sizeof(struct ipc_sec_rsim_access_get)), data, length);
494
495         ipc_fmt_send(IPC_SEC_RSIM_ACCESS, IPC_TYPE_GET, rsim_access_data, rsim_access_length, ril_request_get_id(t));
496
497         free(rsim_access_data);
498 }
499
500 void ril_request_sim_io(RIL_Token t, void *data, int length)
501 {
502         struct ril_request_sim_io_info *sim_io_info = NULL;
503 #if RIL_VERSION >= 6
504         RIL_SIM_IO_v6 *sim_io = NULL;
505 #else
506         RIL_SIM_IO *sim_io = NULL;
507 #endif
508         void *sim_io_data = NULL;
509         int sim_io_data_length = 0;
510         int rc;
511
512         if (data == NULL || length < (int) sizeof(*sim_io))
513                 goto error;
514
515 #if RIL_VERSION >= 6
516         sim_io = (RIL_SIM_IO_v6 *) data;
517 #else
518         sim_io = (RIL_SIM_IO *) data;
519 #endif
520
521         // SIM IO data should be a string if present
522         if (sim_io->data != NULL) {
523                 sim_io_data_length = strlen(sim_io->data) / 2;
524                 if (sim_io_data_length > 0) {
525                         sim_io_data = calloc(1, sim_io_data_length);
526                         hex2bin(sim_io->data, sim_io_data_length * 2, sim_io_data);
527                 }
528         }
529
530         rc = ril_request_sim_io_register(t, sim_io->command, sim_io->fileid,
531                 sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length,
532                 &sim_io_info);
533         if (rc < 0 || sim_io_info == NULL) {
534                 LOGE("Unable to add the request to the list");
535
536                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
537                 if (sim_io_data != NULL)
538                         free(sim_io_data);
539
540                 // Send the next SIM I/O in the list
541                 ril_request_sim_io_next();
542         }
543
544         if (ril_data.tokens.sim_io != RIL_TOKEN_NULL) {
545                 LOGD("Another SIM I/O is being processed, adding to the list");
546                 return;
547         }
548
549         sim_io_info->waiting = 0;
550         ril_data.tokens.sim_io = t;
551
552         ril_request_sim_io_complete(t, sim_io->command, sim_io->fileid,
553                 sim_io->p1, sim_io->p2, sim_io->p3, sim_io_data, sim_io_data_length);
554
555         if (sim_io_data != NULL)
556                 free(sim_io_data);
557         sim_io_info->data = NULL;
558         sim_io_info->length = 0;
559
560         return;
561
562 error:
563         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
564 }
565
566 void ipc_sec_rsim_access(struct ipc_message_info *info)
567 {
568         struct ril_request_sim_io_info *sim_io_info;
569         struct sim_file_response sim_file_response;
570         RIL_SIM_IO_Response sim_io_response;
571         struct ipc_sec_rsim_access_response *rsim_access = NULL;
572         struct ipc_sec_rsim_access_response_data *rsim_data = NULL;
573         void *rsim_access_data = NULL;
574         char *sim_response = NULL;
575         unsigned char *buf = NULL;
576         int offset;
577         int i;
578
579         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sec_rsim_access_response))
580                 goto error;
581
582         sim_io_info = ril_request_sim_io_info_find_token(ril_request_get_token(info->aseq));
583         if (sim_io_info == NULL) {
584                 LOGE("Unable to find SIM I/O in the list!");
585
586                 // Send the next SIM I/O in the list
587                 ril_request_sim_io_next();
588
589                 return;
590         }
591
592         rsim_access = (struct ipc_sec_rsim_access_response *) info->data;
593         rsim_access_data = (void *) ((int) info->data + sizeof(struct ipc_sec_rsim_access_response));
594
595         memset(&sim_io_response, 0, sizeof(sim_io_response));
596         sim_io_response.sw1 = rsim_access->sw1;
597         sim_io_response.sw2 = rsim_access->sw2;
598
599         switch (sim_io_info->command) {
600                 case SIM_COMMAND_READ_BINARY:
601                 case SIM_COMMAND_READ_RECORD:
602                         if (rsim_access->len <= 0)
603                                 break;
604
605                         // Copy the data as-is
606                         sim_response = (char *) malloc(rsim_access->len * 2 + 1);
607                         bin2hex(rsim_access_data, rsim_access->len, sim_response);
608                         sim_io_response.simResponse = sim_response;
609                         break;
610                 case SIM_COMMAND_GET_RESPONSE:
611                         if (rsim_access->len < sizeof(struct ipc_sec_rsim_access_response_data))
612                                 break;
613
614                         // SIM ICC type 1 requires direct copy
615                         if (ril_data.state.sim_icc_type.type == 1) {
616                                 sim_response = (char *) malloc(rsim_access->len * 2 + 1);
617                                 bin2hex(rsim_access_data, rsim_access->len, sim_response);
618                                 sim_io_response.simResponse = sim_response;
619                                 break;
620                         }
621
622                         rsim_data = (struct ipc_sec_rsim_access_response_data *)
623                                 rsim_access_data;
624
625                         memset(&sim_file_response, 0, sizeof(sim_file_response));
626
627                         buf = (unsigned char *) rsim_data;
628                         buf += sizeof(struct ipc_sec_rsim_access_response_data);
629                         buf += rsim_data->offset - 2;
630                         if (((int) buf + 1 - (int) rsim_access_data) > rsim_access->len)
631                                 break;
632
633                         sim_file_response.file_id[0] = buf[0];
634                         sim_file_response.file_id[1] = buf[1];
635
636                         buf = (unsigned char *) rsim_data;
637                         buf += rsim_access->len - 2;
638                         while ((int) buf > (int) rsim_data + 2) {
639                                 if (buf[0] == 0x88) {
640                                         buf -= 2;
641                                         break;
642                                 }
643                                 buf--;
644                         }
645
646                         if ((int) buf <= (int) rsim_data + 2)
647                                 break;
648
649                         sim_file_response.file_size[0] = buf[0];
650                         sim_file_response.file_size[1] = buf[1];
651
652                         // Fallback to EF
653                         sim_file_response.file_type = SIM_FILE_TYPE_EF;
654                         for (i=0 ; i < sim_file_ids_count ; i++) {
655                                 if (sim_io_info->fileid == sim_file_ids[i].file_id) {
656                                         sim_file_response.file_type = sim_file_ids[i].type;
657                                         break;
658                                 }
659                         }
660
661                         sim_file_response.access_condition[0] = 0x00;
662                         sim_file_response.access_condition[1] = 0xff;
663                         sim_file_response.access_condition[2] = 0xff;
664
665                         sim_file_response.file_status = 0x01;
666                         sim_file_response.file_length = 0x02;
667
668                         switch (rsim_data->file_structure) {
669                                 case IPC_SEC_RSIM_FILE_STRUCTURE_TRANSPARENT:
670                                         sim_file_response.file_structure = SIM_FILE_STRUCTURE_TRANSPARENT;
671                                         break;
672                                 case IPC_SEC_RSIM_FILE_STRUCTURE_LINEAR_FIXED:
673                                 default:
674                                         sim_file_response.file_structure = SIM_FILE_STRUCTURE_LINEAR_FIXED;
675                                         break;
676                         }
677
678                         sim_file_response.record_length = rsim_data->record_length;
679
680                         sim_response = (char *) malloc(sizeof(struct sim_file_response) * 2 + 1);
681                         bin2hex((void *) &sim_file_response, sizeof(struct sim_file_response), sim_response);
682                         sim_io_response.simResponse = sim_response;
683                         break;
684                 case SIM_COMMAND_UPDATE_BINARY:
685                 case SIM_COMMAND_UPDATE_RECORD:
686                 case SIM_COMMAND_SEEK:
687                 default:
688                         sim_io_response.simResponse = NULL;
689                         break;
690         }
691
692         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &sim_io_response, sizeof(sim_io_response));
693
694         if (sim_io_response.simResponse != NULL) {
695                 LOGD("SIM response: %s", sim_io_response.simResponse);
696                 free(sim_io_response.simResponse);
697         }
698
699         ril_request_sim_io_unregister(sim_io_info);
700
701         // Send the next SIM I/O in the list
702         ril_request_sim_io_next();
703
704         return;
705
706 error:
707         if (info != NULL)
708                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
709 }
710
711 void ipc_sec_sim_status_complete(struct ipc_message_info *info)
712 {
713         struct ipc_gen_phone_res *phone_res;
714         int attempts = -1;
715         int rc;
716
717         phone_res = (struct ipc_gen_phone_res *) info->data;
718
719         rc = ipc_gen_phone_res_check(phone_res);
720         if (rc < 0) {
721                 if ((phone_res->code & 0x00ff) == 0x10) {
722                         LOGE("Wrong password!");
723                         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
724                 } else if ((phone_res->code & 0x00ff) == 0x0c) {
725                         LOGE("Wrong password and no attempts left!");
726
727                         attempts = 0;
728                         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_PASSWORD_INCORRECT, &attempts, sizeof(attempts));
729
730                         ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
731                 } else {
732                         LOGE("There was an error during pin status complete!");
733                         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
734                 }
735                 return;
736         }
737
738         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &attempts, sizeof(attempts));
739 }
740
741 void ipc_sec_lock_info(struct ipc_message_info *info)
742 {
743         struct ipc_sec_lock_info_response *lock_info;
744         int attempts;
745
746         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sec_lock_info_response))
747                 return;
748
749         lock_info = (struct ipc_sec_lock_info_response *) info->data;
750
751         /*
752          * FIXME: solid way of handling lockinfo and sim unlock response together
753          * so we can return the number of attempts left in respondSecPinStatus
754          */
755
756         if (lock_info->type == IPC_SEC_PIN_TYPE_PIN1) {
757                 attempts = lock_info->attempts;
758                 LOGD("%s: PIN1 %d attempts left", __func__, attempts);
759         } else {
760                 LOGE("%s: unhandled lock type %d", __func__, lock_info->type);
761         }
762 }
763
764 void ril_request_enter_sim_pin(RIL_Token t, void *data, size_t length)
765 {
766         struct ipc_sec_pin_status_set pin_status;
767         char *pin = ((char **) data)[0];
768         unsigned char buf[9];
769
770         if (data == NULL || length < (int) sizeof(char *))
771                 goto error;
772
773         // 1. Send PIN
774         if (strlen(data) > 16) {
775                 LOGE("%s: pin exceeds maximum length", __func__);
776                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
777         }
778
779         ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, NULL);
780
781         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_SIM_STATUS, ipc_sec_sim_status_complete);
782
783         ipc_fmt_send_set(IPC_SEC_SIM_STATUS, ril_request_get_id(t), (unsigned char *) &pin_status, sizeof(pin_status));
784
785         // 2. Get lock status
786         // FIXME: This is not clean at all
787         memset(buf, 0, sizeof(buf));
788         buf[0] = 1;
789         buf[1] = IPC_SEC_PIN_TYPE_PIN1;
790
791         ipc_fmt_send(IPC_SEC_LOCK_INFO, IPC_TYPE_GET, buf, sizeof(buf), ril_request_get_id(t));
792
793         return;
794
795 error:
796         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
797 }
798
799 void ril_request_change_sim_pin(RIL_Token t, void *data, size_t length)
800 {
801         char *password_old;
802         char *password_new;
803         struct ipc_sec_change_locking_pw_set locking_pw;
804
805         if (data == NULL || length < (int) (2 * sizeof(char *)))
806                 goto error;
807
808         password_old = ((char **) data)[0];
809         password_new = ((char **) data)[1];
810
811         memset(&locking_pw, 0, sizeof(locking_pw));
812
813         locking_pw.facility = IPC_SEC_SIM_STATUS_LOCK_SC;
814
815         locking_pw.length_new = strlen(password_new) > sizeof(locking_pw.password_new)
816                                 ? sizeof(locking_pw.password_new)
817                                 : strlen(password_new);
818
819         memcpy(locking_pw.password_new, password_new, locking_pw.length_new);
820
821         locking_pw.length_old = strlen(password_old) > sizeof(locking_pw.password_old)
822                                 ? sizeof(locking_pw.password_old)
823                                 : strlen(password_old);
824
825         memcpy(locking_pw.password_old, password_old, locking_pw.length_old);
826
827         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_CHANGE_LOCKING_PW,
828                 ipc_sec_sim_status_complete);
829
830         ipc_fmt_send_set(IPC_SEC_CHANGE_LOCKING_PW, ril_request_get_id(t), (unsigned char *) &locking_pw, sizeof(locking_pw));
831
832         return;
833
834 error:
835         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
836 }
837
838 void ril_request_enter_sim_puk(RIL_Token t, void *data, size_t length)
839 {
840         struct ipc_sec_pin_status_set pin_status;
841         char *puk;
842         char *pin;
843
844         if (data == NULL || length < (int) (2 * sizeof(char *)))
845                 goto error;
846
847         puk = ((char **) data)[0];
848         pin = ((char **) data)[1];
849
850         ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, puk);
851
852         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_SIM_STATUS,
853                 ipc_sec_sim_status_complete);
854
855         ipc_fmt_send_set(IPC_SEC_SIM_STATUS, ril_request_get_id(t), (unsigned char *) &pin_status, sizeof(pin_status));
856
857         return;
858
859 error:
860         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
861 }
862
863 void ipc_sec_phone_lock(struct ipc_message_info *info)
864 {
865         int status;
866         struct ipc_sec_phone_lock_response *lock;
867
868         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sec_phone_lock_response))
869                 goto error;
870
871         lock = (struct ipc_sec_phone_lock_response *) info->data;
872         status = lock->status;
873
874         ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, &status, sizeof(status));
875
876         return;
877
878 error:
879         if (info != NULL)
880                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
881 }
882
883 void ril_request_query_facility_lock(RIL_Token t, void *data, size_t length)
884 {
885         struct ipc_sec_phone_lock_get lock_request;
886         char *facility;
887
888         if (data == NULL || length < sizeof(char *))
889                 goto error;
890
891         facility = ((char **) data)[0];
892
893         if (!strcmp(facility, "SC")) {
894                 lock_request.facility = IPC_SEC_FACILITY_TYPE_SC;
895         } else if (!strcmp(facility, "FD")) {
896                 lock_request.facility = IPC_SEC_FACILITY_TYPE_FD;
897         } else if (!strcmp(facility, "PN")) {
898                 lock_request.facility = IPC_SEC_FACILITY_TYPE_PN;
899         } else if (!strcmp(facility, "PU")) {
900                 lock_request.facility = IPC_SEC_FACILITY_TYPE_PU;
901         } else if (!strcmp(facility, "PP")) {
902                 lock_request.facility = IPC_SEC_FACILITY_TYPE_PP;
903         } else if (!strcmp(facility, "PC")) {
904                 lock_request.facility = IPC_SEC_FACILITY_TYPE_PC;
905         } else {
906                 LOGE("%s: unsupported facility: %s", __func__, facility);
907                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
908         }
909
910         ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_GET, (void *) &lock_request, sizeof(lock_request), ril_request_get_id(t));
911
912         return;
913
914 error:
915         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
916 }
917
918 // Both functions were the same
919 #define ipc_sec_phone_lock_complete \
920         ipc_sec_sim_status_complete
921
922 void ril_request_set_facility_lock(RIL_Token t, void *data, size_t length)
923 {
924         struct ipc_sec_phone_lock_set lock_request;
925         char *facility;
926         char *lock;
927         char *password;
928         char *class;
929
930         if (data == NULL || length < (int) (4 * sizeof(char *)))
931                 goto error;
932
933         facility = ((char **) data)[0];
934         lock = ((char **) data)[1];
935         password = ((char **) data)[2];
936         class = ((char **) data)[3];
937
938         memset(&lock_request, 0, sizeof(lock_request));
939
940         if (!strcmp(facility, "SC")) {
941                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_SC;
942         } else if (!strcmp(facility, "FD")) {
943                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_FD;
944         } else if (!strcmp(facility, "PN")) {
945                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PN;
946         } else if (!strcmp(facility, "PU")) {
947                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PU;
948         } else if (!strcmp(facility, "PP")) {
949                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PP;
950         } else if (!strcmp(facility, "PC")) {
951                 lock_request.type = IPC_SEC_SIM_STATUS_LOCK_PC;
952         } else {
953                 LOGE("%s: unsupported facility: %s", __func__, facility);
954                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
955         }
956
957         lock_request.lock = lock[0] == '1' ? 1 : 0;
958         lock_request.length = strlen(password) > sizeof(lock_request.password)
959                                 ? sizeof(lock_request.password)
960                                 : strlen(password);
961
962         memcpy(lock_request.password, password, lock_request.length);
963
964         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SEC_PHONE_LOCK,
965                 ipc_sec_phone_lock_complete);
966
967         ipc_fmt_send(IPC_SEC_PHONE_LOCK, IPC_TYPE_SET, (void *) &lock_request, sizeof(lock_request), ril_request_get_id(t));
968
969         return;
970
971 error:
972         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
973 }