8f154531322afc63fbe3b57551b345ed4560edcf
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sim.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ankit Jogi <ankit.jogi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <tcore.h>
26 #include <hal.h>
27 #include <core_object.h>
28 #include <plugin.h>
29 #include <queue.h>
30 #include <co_sim.h>
31 #include <co_sms.h>
32 #include <storage.h>
33 #include <user_request.h>
34 #include <server.h>
35 #include <at.h>
36 #include <ss_manager.h>
37
38 #include "imc_common.h"
39 #include "imc_sms.h"
40 #include "imc_sim.h"
41
42 #define ID_RESERVED_AT 0x0229
43 #define SIM_PIN_MAX_RETRY_COUNT  3
44 #define SMS_STATE_READY 1
45
46 #define SIM_SSM_GROUP_ID "secure-storage::telephony_sim"
47 #define SIM_SSM_FILE_IMSI1 "imsi1"
48
49 #define SWAPBYTES16(x) \
50         { \
51                 unsigned short int data = *(unsigned short int *)&(x);  \
52                 data = ((data & 0xff00) >> 8) |   \
53                            ((data & 0x00ff) << 8);        \
54                 *(unsigned short int *)&(x) = data;      \
55         }
56
57 enum imc_sim_sec_op_e {
58         SEC_PIN1_VERIFY,
59         SEC_PIN2_VERIFY,
60         SEC_PUK1_VERIFY,
61         SEC_PUK2_VERIFY,
62         SEC_SIM_VERIFY,
63         SEC_ADM_VERIFY,
64         SEC_PIN1_CHANGE,
65         SEC_PIN2_CHANGE,
66         SEC_PIN1_ENABLE,
67         SEC_PIN1_DISABLE,
68         SEC_PIN2_ENABLE,
69         SEC_PIN2_DISABLE, /* 10 */
70         SEC_SIM_ENABLE,
71         SEC_SIM_DISABLE,
72         SEC_NET_ENABLE,
73         SEC_NET_DISABLE,
74         SEC_NS_ENABLE,
75         SEC_NS_DISABLE,
76         SEC_SP_ENABLE,
77         SEC_SP_DISABLE,
78         SEC_CP_ENABLE,
79         SEC_CP_DISABLE, /* 20 */
80         SEC_FDN_ENABLE,
81         SEC_FDN_DISABLE,
82         SEC_PIN1_STATUS,
83         SEC_PIN2_STATUS,
84         SEC_FDN_STATUS,
85         SEC_NET_STATUS,
86         SEC_NS_STATUS,
87         SEC_SP_STATUS,
88         SEC_CP_STATUS,
89         SEC_SIM_STATUS,
90         SEC_SIM_UNKNOWN = 0xff
91 };
92
93 struct imc_sim_property {
94         gboolean b_valid; /**< Valid or not */
95         enum tel_sim_file_id file_id; /**< File identifier */
96         enum tcore_sim_file_type_e file_type; /**< File type and structure */
97         int rec_length; /**< Length of one record in file */
98         int rec_count; /**< Number of records in file */
99         int data_size; /**< File size */
100         int current_index; /**< current index to read */
101         enum imc_sim_sec_op_e current_sec_op; /**< current index to read */
102         int mb_count; /**< Number of MB records in file */
103         struct tel_sim_mbi_list mbi_list;
104         struct tel_sim_mailbox mb_data;
105         struct tresp_sim_read files;
106 };
107
108 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data);
109 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
110 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
111 static gboolean _get_sim_type(CoreObject *o);
112 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
113 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
114 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
115 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
116 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
117
118 static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
119 {
120         TcoreATRequest *req = NULL;
121         TcoreHal *hal = NULL;
122         TcorePending *pending = NULL;
123         TReturn ret;
124
125
126         hal = tcore_object_get_hal(co);
127         dbg("hal: %p", hal);
128
129         pending = tcore_pending_new(co, 0);
130         if (!pending) {
131                 dbg("Pending is NULL");
132                 return;
133         }
134         req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
135         if (req == NULL) {
136                 tcore_pending_free(pending);
137                 return;
138         }
139
140         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
141
142         tcore_pending_set_request_data(pending, 0, req);
143         tcore_pending_set_response_callback(pending, callback, NULL);
144         tcore_pending_link_user_request(pending, NULL); /* set user request to NULL - this is internal request */
145         ret = tcore_hal_send_request(hal, pending);
146         if (ret != TCORE_RETURN_SUCCESS) {
147                 err("error: [0x%x]", ret);
148                 tcore_pending_free(pending);
149                 tcore_at_request_free(req);
150         }
151         return;
152 }
153
154
155 static enum tcore_response_command _find_resp_command(UserRequest *ur)
156 {
157         enum tcore_request_command command;
158
159         command = tcore_user_request_get_command(ur);
160         switch (command) {
161         case TREQ_SIM_VERIFY_PINS:
162                 return TRESP_SIM_VERIFY_PINS;
163                 break;
164
165         case TREQ_SIM_VERIFY_PUKS:
166                 return TRESP_SIM_VERIFY_PUKS;
167                 break;
168
169         case TREQ_SIM_CHANGE_PINS:
170                 return TRESP_SIM_CHANGE_PINS;
171                 break;
172
173         case TREQ_SIM_GET_FACILITY_STATUS:
174                 return TRESP_SIM_GET_FACILITY_STATUS;
175                 break;
176
177         case TREQ_SIM_DISABLE_FACILITY:
178                 return TRESP_SIM_DISABLE_FACILITY;
179                 break;
180
181         case TREQ_SIM_ENABLE_FACILITY:
182                 return TRESP_SIM_ENABLE_FACILITY;
183                 break;
184
185         case TREQ_SIM_GET_LOCK_INFO:
186                 return TRESP_SIM_GET_LOCK_INFO;
187                 break;
188
189         case TREQ_SIM_TRANSMIT_APDU:
190                 return TRESP_SIM_TRANSMIT_APDU;
191                 break;
192
193         case TREQ_SIM_GET_ATR:
194                 return TRESP_SIM_GET_ATR;
195                 break;
196
197         case TREQ_SIM_GET_ECC:
198                 return TRESP_SIM_GET_ECC;
199                 break;
200
201         case TREQ_SIM_GET_LANGUAGE:
202                 return TRESP_SIM_GET_LANGUAGE;
203                 break;
204
205         case TREQ_SIM_SET_LANGUAGE:
206                 return TRESP_SIM_SET_LANGUAGE;
207                 break;
208
209         case TREQ_SIM_GET_ICCID:
210                 return TRESP_SIM_GET_ICCID;
211                 break;
212
213         case TREQ_SIM_GET_MAILBOX:
214                 return TRESP_SIM_GET_MAILBOX;
215                 break;
216
217         case TREQ_SIM_SET_MAILBOX:
218                 return TRESP_SIM_SET_MAILBOX;
219                 break;
220
221         case TREQ_SIM_GET_CALLFORWARDING:
222                 return TRESP_SIM_GET_CALLFORWARDING;
223                 break;
224
225         case TREQ_SIM_SET_CALLFORWARDING:
226                 return TRESP_SIM_SET_CALLFORWARDING;
227                 break;
228
229         case TREQ_SIM_GET_MESSAGEWAITING:
230                 return TRESP_SIM_GET_MESSAGEWAITING;
231                 break;
232
233         case TREQ_SIM_SET_MESSAGEWAITING:
234                 return TRESP_SIM_SET_MESSAGEWAITING;
235                 break;
236
237         case TREQ_SIM_GET_CPHS_INFO:
238                 return TRESP_SIM_GET_CPHS_INFO;
239                 break;
240
241         case TREQ_SIM_GET_MSISDN:
242                 return TRESP_SIM_GET_MSISDN;
243                 break;
244
245         case TREQ_SIM_GET_SPN:
246                 return TRESP_SIM_GET_SPN;
247                 break;
248
249         case TREQ_SIM_GET_SPDI:
250                 return TRESP_SIM_GET_SPDI;
251                 break;
252
253         case TREQ_SIM_GET_OPL:
254                 return TRESP_SIM_GET_OPL;
255                 break;
256
257         case TREQ_SIM_GET_PNN:
258                 return TRESP_SIM_GET_PNN;
259                 break;
260
261         case TREQ_SIM_GET_CPHS_NETNAME:
262                 return TRESP_SIM_GET_CPHS_NETNAME;
263                 break;
264
265         case TREQ_SIM_GET_OPLMNWACT:
266                 return TRESP_SIM_GET_OPLMNWACT;
267                 break;
268
269         case TREQ_SIM_REQ_AUTHENTICATION:
270                 return TRESP_SIM_REQ_AUTHENTICATION;
271                 break;
272
273         case TREQ_SIM_GET_SERVICE_TABLE:
274                 return TRESP_SIM_GET_SERVICE_TABLE;
275                 break;
276
277         default:
278                 break;
279         }
280         return TRESP_UNKNOWN;
281 }
282
283 static int _sim_get_current_pin_facility(enum imc_sim_sec_op_e op)
284 {
285         int ret_type = 0;
286
287         dbg("current sec_op[%d]", op);
288
289         switch (op) {
290         case SEC_PIN1_VERIFY:
291         case SEC_PIN1_CHANGE:
292                 ret_type = SIM_PTYPE_PIN1;
293                 break;
294
295         case SEC_PIN2_VERIFY:
296         case SEC_PIN2_CHANGE:
297                 ret_type = SIM_PTYPE_PIN2;
298                 break;
299
300         case SEC_PUK1_VERIFY:
301                 ret_type = SIM_PTYPE_PUK1;
302                 break;
303
304         case SEC_PUK2_VERIFY:
305                 ret_type = SIM_PTYPE_PUK2;
306                 break;
307
308         case SEC_SIM_VERIFY:
309                 ret_type = SIM_PTYPE_SIM;
310                 break;
311
312         case SEC_ADM_VERIFY:
313                 ret_type = SIM_PTYPE_ADM;
314                 break;
315
316         case SEC_PIN1_ENABLE:
317         case SEC_PIN1_DISABLE:
318         case SEC_PIN1_STATUS:
319                 ret_type = SIM_FACILITY_SC;
320                 break;
321
322         case SEC_SIM_ENABLE:
323         case SEC_SIM_DISABLE:
324         case SEC_SIM_STATUS:
325                 ret_type = SIM_FACILITY_PS;
326                 break;
327
328         case SEC_NET_ENABLE:
329         case SEC_NET_DISABLE:
330         case SEC_NET_STATUS:
331                 ret_type = SIM_FACILITY_PN;
332                 break;
333
334         case SEC_NS_ENABLE:
335         case SEC_NS_DISABLE:
336         case SEC_NS_STATUS:
337                 ret_type = SIM_FACILITY_PU;
338                 break;
339
340         case SEC_SP_ENABLE:
341         case SEC_SP_DISABLE:
342         case SEC_SP_STATUS:
343                 ret_type = SIM_FACILITY_PP;
344                 break;
345
346         case SEC_CP_ENABLE:
347         case SEC_CP_DISABLE:
348         case SEC_CP_STATUS:
349                 ret_type = SIM_FACILITY_PC;
350                 break;
351
352         case SEC_FDN_ENABLE:
353         case SEC_FDN_DISABLE:
354         case SEC_FDN_STATUS:
355                 ret_type = SIM_FACILITY_FD;
356                 break;
357
358         default:
359                 dbg("not handled current sec op[%d]", op);
360                 break;
361         }
362         return ret_type;
363 }
364
365 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
366 {
367         enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
368
369         if (status_word1 == 0x93 && status_word2 == 0x00) {
370                 rst = SIM_ACCESS_FAILED;
371                 /*Failed SIM request command*/
372                 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
373         } else if (status_word1 == 0x94 && status_word2 == 0x00) {
374                 rst = SIM_ACCESS_FAILED;
375                 /*Failed SIM request command*/
376                 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
377         } else if (status_word1 == 0x94 && status_word2 == 0x02) {
378                 rst = SIM_ACCESS_FAILED;
379                 /*Failed SIM request command*/
380                 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
381                         status_word1, status_word2);
382         } else if (status_word1 == 0x94 && status_word2 == 0x04) {
383                 rst = SIM_ACCESS_FILE_NOT_FOUND;
384                 /*Failed SIM request command*/
385                 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
386         } else if (status_word1 == 0x94 && status_word2 == 0x08) {
387                 rst = SIM_ACCESS_FAILED; /* MOdem not support */
388                 /*Failed SIM request command*/
389                 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
390                         status_word1, status_word2);
391         } else if (status_word1 == 0x98 && status_word2 == 0x02) {
392                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
393                 /*Failed SIM request command*/
394                 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
395         } else if (status_word1 == 0x98 && status_word2 == 0x04) {
396                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
397                 /*Failed SIM request command*/
398                 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
399                 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
400                         status_word1, status_word2);
401                 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
402                         status_word1, status_word2);
403                 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
404         } else if (status_word1 == 0x98 && status_word2 == 0x08) {
405                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
406                 /*Failed SIM request command*/
407                 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
408         } else if (status_word1 == 0x98 && status_word2 == 0x10) {
409                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
410                 /*Failed SIM request command*/
411                 dbg("error - Contradiction with invalidation status [%x][%x]",
412                         status_word1, status_word2);
413         } else if (status_word1 == 0x98 && status_word2 == 0x40) {
414                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
415                 /*Failed SIM request command*/
416                 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
417                         status_word1, status_word2);
418                 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
419                         status_word1, status_word2);
420                 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
421         } else if (status_word1 == 0x67 && status_word2 == 0x00) {
422                 rst = SIM_ACCESS_FAILED;
423                 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
424         } else if (status_word1 == 0x6B && status_word2 == 0x00) {
425                 rst = SIM_ACCESS_FAILED;
426                 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
427         } else if (status_word1 == 0x6D && status_word2 == 0x00) {
428                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
429                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
430         } else if (status_word1 == 0x6E && status_word2 == 0x00) {
431                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
432                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
433         } else if (status_word1 == 0x69 && status_word2 == 0x82) {
434                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
435                 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
436         } else if (status_word1 == 0x6A && status_word2 == 0x87) {
437                 rst = SIM_ACCESS_FAILED;
438                 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
439         } else if (status_word1 == 0x6A && status_word2 == 0x82) {
440                 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
441                 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
442         } else if (status_word1 == 0x6A && status_word2 == 0x83) {
443                 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
444                 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
445         } else {
446                 rst = SIM_ACCESS_CARD_ERROR;
447                 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
448         }
449         return rst;
450 }
451
452 #if 0
453 static gboolean _sim_check_identity(CoreObject *co_sim, struct tel_sim_imsi *imsi)
454 {
455         gboolean is_changed = TRUE;
456         char new_imsi[16 + 1]; /* IMSI is 15 digit, but for distingushing between plmn and msin, define as 16 bytes. */
457         char *imsi_buf = NULL;
458         int ret_val = 0;
459
460         dbg("Entry");
461         if (NULL == imsi) {
462                 err("imsi is NULL");
463                 return FALSE;
464         }
465
466         memset(new_imsi, 0x5F, 16);
467         memcpy(new_imsi, imsi->plmn, strlen(imsi->plmn));
468         memcpy(&new_imsi[6], imsi->msin, strlen(imsi->msin));
469         new_imsi[6 + strlen(imsi->msin)] = '\0';
470
471         ret_val = ssa_get(SIM_SSM_FILE_IMSI1, &imsi_buf, SIM_SSM_GROUP_ID, NULL);
472         if (ret_val >= 0 && imsi_buf != NULL) {
473                 if (strncmp(imsi_buf, new_imsi, 16) == 0)
474                         is_changed = FALSE;
475                 free(imsi_buf);
476         }
477
478         if (is_changed) {
479                 dbg("NEW SIM");
480                 /* Update file */
481                 ret_val = ssa_put(SIM_SSM_FILE_IMSI1, new_imsi, strlen(new_imsi) + 1, SIM_SSM_GROUP_ID, NULL);
482                 if (ret_val < 0)
483                         err("ssa_put failed. ret_val=[%d]", ret_val);
484         }
485
486         /* Update sim identification */
487         tcore_sim_set_identification(co_sim, is_changed);
488         return TRUE;
489 }
490 #endif
491
492 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
493                                         char *encoded_data, unsigned int encoded_len, int rec_index)
494 {
495         TcoreHal *hal = NULL;
496         TcoreATRequest *req = NULL;
497         TcorePending *pending = NULL;
498         char *cmd_str = NULL;
499         struct imc_sim_property *meta_info = NULL;
500         int p1 = 0;
501         int p2 = 0;
502         int p3 = 0;
503         int cmd = 0;
504
505         dbg("Entry");
506
507         hal = tcore_object_get_hal(o);
508         pending = tcore_pending_new(o, 0);
509         if (!pending) {
510                 err("Pending is NULL");
511                 return TCORE_RETURN_FAILURE;
512         }
513         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
514
515         meta_info->file_id = ef;
516         dbg("File ID: [0x%x]", meta_info->file_id);
517
518         switch (ef) {
519         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
520         case SIM_EF_ELP:
521         case SIM_EF_LP:
522         case SIM_EF_CPHS_VOICE_MSG_WAITING:
523                 p1 = 0;
524                 p2 = 0;
525                 p3 = encoded_len;
526                 cmd = 214;
527         break;
528
529         case SIM_EF_USIM_CFIS:
530         case SIM_EF_USIM_MWIS:
531         case SIM_EF_CPHS_MAILBOX_NUMBERS:
532         case SIM_EF_MBDN:
533         case SIM_EF_USIM_MBI:
534                 p1 = rec_index;
535                 p2 = 0x04;
536                 p3 = encoded_len;
537                 cmd = 220;
538         break;
539
540         default:
541                 err("Unhandled File ID[0x%04x]", ef);
542                 tcore_pending_free(pending);
543                 return TCORE_RETURN_EINVAL;
544         }
545
546         cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d, \"%s\"", cmd, ef, p1, p2, p3, encoded_data);
547
548         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
549         if (req == NULL) {
550                 tcore_pending_free(pending);
551                 g_free(cmd_str);
552                 return TCORE_RETURN_FAILURE;
553         }
554         g_free(cmd_str);
555
556         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
557                                 req->cmd, req->prefix, strlen(req->cmd));
558
559         tcore_pending_set_request_data(pending, 0, req);
560         tcore_pending_set_response_callback(pending, on_response_update_file, hal);
561         tcore_pending_link_user_request(pending, ur);
562         tcore_hal_send_request(hal, pending);
563
564         dbg("Exit");
565         return TRUE;
566 }
567
568
569 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
570 {
571         struct imc_sim_property *meta_info = NULL;
572         TReturn ret_code = TCORE_RETURN_FAILURE;
573         int encoded_len = 0;
574         enum tcore_request_command command;
575         char *tmp = NULL;
576         char *encoded_data = NULL;
577         int rec_index = -1;
578
579         dbg("Entry");
580
581         if (!o || !ur) {
582                 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
583                 return TCORE_RETURN_EINVAL;
584         }
585         command = tcore_user_request_get_command(ur);
586         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
587
588         switch (command) {
589         case TREQ_SIM_SET_LANGUAGE: {
590                 const struct treq_sim_set_language *lang = NULL;
591                 struct tel_sim_language language = {0, };
592
593                 lang = tcore_user_request_ref_data(ur, NULL);
594                 language.language_count = 1;
595                 language.language[0] = lang->language;
596                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP) {
597                         dbg("Encoding EF-LP, language[%d]", lang->language);
598                         tmp = tcore_sim_encode_lp(&encoded_len, &language);
599                 } else {
600                         dbg("Encoding EF-ELP, language[%d]", lang->language);
601                         tmp = tcore_sim_encode_li(&encoded_len, &language);
602                 }
603         }
604         break;
605
606         case TREQ_SIM_SET_CALLFORWARDING: {
607                 const struct treq_sim_set_callforwarding *cf = NULL;
608
609                 cf = tcore_user_request_ref_data(ur, NULL);
610                 if (ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
611                         if (cf->b_cphs) {
612                                 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cf->cphs_cf, meta_info->data_size);
613                         } else {
614                                 /* Convert 3GPP data to CPHS data */
615                                 struct tel_sim_cphs_cf cphs_cf;
616
617                                 dbg("Convert 3GPP data to CPHS data");
618                                 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
619                                 if (cf->cf.cfu_status & 0x01)
620                                         cphs_cf.b_line1 = TRUE;
621
622                                 if (cf->cf.cfu_status & 0x02)
623                                         cphs_cf.b_fax = TRUE;
624
625                                 if (cf->cf.cfu_status & 0x04)
626                                         cphs_cf.b_data = TRUE;
627
628                                 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cphs_cf, meta_info->data_size);
629                         }
630
631                         if (tmp) {
632                                 encoded_len = strlen(tmp);
633                         } else {
634                                 err("NULL Encoding Data[%p].. No Updating EF", tmp);
635                                 goto EXIT;
636                         }
637                 } else if (ef == SIM_EF_USIM_CFIS) {
638                         tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis *)&cf->cf);
639                         rec_index = cf->cf.rec_index;
640                 } else {
641                         err("Invalid File ID[0x%04x]", ef);
642                         goto EXIT;
643                 }
644         }
645         break;
646
647         case TREQ_SIM_SET_MESSAGEWAITING: {
648                 const struct treq_sim_set_messagewaiting *mw = NULL;
649
650                 mw = tcore_user_request_ref_data(ur, NULL);
651                 if (ef == SIM_EF_CPHS_VOICE_MSG_WAITING) {
652                         if (mw->b_cphs) {
653                                 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&mw->cphs_mw, meta_info->data_size);
654                         } else {
655                                 /* Convert 3GPP data to CPHS data */
656                                 struct tel_sim_cphs_mw cphs_mw;
657
658                                 dbg("Convert 3GPP data to CPHS data");
659                                 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
660
661                                 if (mw->mw.indicator_status & 0x01)
662                                         cphs_mw.b_voice1 = TRUE;
663
664                                 if (mw->mw.indicator_status & 0x02)
665                                         cphs_mw.b_fax = TRUE;
666
667                                 if (mw->mw.indicator_status & 0x04)
668                                         cphs_mw.b_data = TRUE;
669
670                                 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&cphs_mw, meta_info->data_size);
671                         }
672                 } else if (ef == SIM_EF_USIM_MWIS) {
673                         tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw *)&mw->mw, meta_info->rec_length);
674                         rec_index = mw->mw.rec_index;
675                         if (tmp)
676                                 encoded_len = meta_info->rec_length;
677                 } else {
678                         err("Invalid File ID[0x%04x]", ef);
679                         goto EXIT;
680                 }
681         }
682         break;
683
684         case TREQ_SIM_SET_MAILBOX: {
685                 const struct treq_sim_set_mailbox *mb = NULL;
686
687                 mb = tcore_user_request_ref_data(ur, NULL);
688                 if (ef == SIM_EF_USIM_MBI) {
689                         gboolean mbi_changed = FALSE;
690                         struct tel_sim_mbi mbi;
691
692                         do {
693                                 meta_info->current_index++;
694                                 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
695
696                                 switch (mb->mb_info.mb_type) {
697                                 case SIM_MAILBOX_VOICE:
698                                         if (mbi.voice_index != mb->mb_info.rec_index) {
699                                                 mbi_changed = TRUE;
700                                                 mbi.voice_index = mb->mb_info.rec_index;
701                                         }
702                                 break;
703
704                                 case SIM_MAILBOX_FAX:
705                                         if (mbi.fax_index != mb->mb_info.rec_index) {
706                                                 mbi_changed = TRUE;
707                                                 mbi.fax_index = mb->mb_info.rec_index;
708                                         }
709                                 break;
710
711                                 case SIM_MAILBOX_EMAIL:
712                                         if (mbi.email_index != mb->mb_info.rec_index) {
713                                                 mbi_changed = TRUE;
714                                                 mbi.email_index = mb->mb_info.rec_index;
715                                         }
716                                 break;
717
718                                 case SIM_MAILBOX_OTHER:
719                                         if (mbi.other_index != mb->mb_info.rec_index) {
720                                                 mbi_changed = TRUE;
721                                                 mbi.other_index = mb->mb_info.rec_index;
722                                         }
723                                 break;
724
725                                 case SIM_MAILBOX_VIDEO:
726                                         if (mbi.video_index != mb->mb_info.rec_index) {
727                                                 mbi_changed = TRUE;
728                                                 mbi.video_index = mb->mb_info.rec_index;
729                                         }
730                                 break;
731
732                                 case SIM_MAILBOX_DATA:
733                                 default:
734                                 break;
735                                 }
736
737                                 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
738                                                 mbi_changed, meta_info->mbi_list.profile_count,
739                                                 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
740                         } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
741
742                         if (mbi_changed == TRUE) {
743                                 rec_index = meta_info->current_index;
744                                 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
745                                 if (tmp)
746                                         encoded_len = meta_info->rec_length;
747                         }
748                 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
749                         tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
750                         rec_index = mb->mb_info.rec_index;
751                         if (tmp)
752                                 encoded_len = meta_info->rec_length;
753                 } else if (ef == SIM_EF_MBDN) {
754                         tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
755                         rec_index = mb->mb_info.rec_index;
756                         if (tmp)
757                                 encoded_len = meta_info->rec_length;
758                 } else {
759                         err("Invalid File ID[0x%04x]", ef);
760                         goto EXIT;
761                 }
762         }
763         break;
764
765         default:
766                 err("Unhandled update REQUEST command[%d]", command);
767                 ret_code = TCORE_RETURN_EINVAL;
768                 goto EXIT;
769         }
770
771         if (tmp) {
772                 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
773                 if (encoded_data == NULL) {
774                         err("Memory allocation failed!!");
775                         free(tmp);
776                         return ret_code;
777                 }
778
779                 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
780                 util_byte_to_hex(tmp, encoded_data, encoded_len);
781                 free(tmp);
782         } else {
783                 err("Failed to Encode data");
784                 goto EXIT;
785         }
786
787         dbg("Encoded Data length =[%d]", encoded_len);
788         tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
789
790         switch (ef) {
791         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
792         case SIM_EF_ELP:
793         case SIM_EF_LP:
794         case SIM_EF_CPHS_VOICE_MSG_WAITING:
795                 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
796         break;
797
798         case SIM_EF_USIM_CFIS:
799         case SIM_EF_USIM_MWIS:
800         case SIM_EF_CPHS_MAILBOX_NUMBERS:
801         case SIM_EF_MBDN:
802                 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
803         break;
804
805         case SIM_EF_USIM_MBI:
806                 if (rec_index > 0)
807                         ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
808                 else
809                         memset(meta_info, 0x00, sizeof(struct imc_sim_property));
810         break;
811
812         default:
813                 err("Unhandled File ID[0x%04x]", ef);
814                 ret_code = TCORE_RETURN_EINVAL;
815         break;
816         }
817
818 EXIT:
819         if (encoded_data) {
820                 free(encoded_data);
821                 encoded_data = NULL;
822         }
823
824         return ret_code;
825 }
826
827 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
828 {
829         struct tresp_sim_read resp = {0, };
830         struct imc_sim_property *meta_info = NULL;
831         enum tcore_request_command command = TREQ_UNKNOWN;
832         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
833
834         dbg("EF[0x%x] access Result[%d]", ef, rt);
835
836         resp.result = rt;
837         memset(&resp.data, 0x00, sizeof(resp.data));
838         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
839         command = tcore_user_request_get_command(ur);
840         sim_type = tcore_sim_get_type(o);
841
842         if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
843                 && (rt != SIM_ACCESS_SUCCESS)) {
844                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
845                 return;
846         }
847
848         switch (ef) {
849         case SIM_EF_ELP:
850                 if (rt == SIM_ACCESS_SUCCESS) {
851                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
852                         if (command == TREQ_SIM_SET_LANGUAGE)
853                                 __set_file_data(o, ur, ef);
854                         else
855                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
856                 } else {
857                         if (sim_type == SIM_TYPE_GSM) {
858                                 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
859                                 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
860                                 _get_file_info(o, ur, SIM_EF_LP);
861                         } else if (sim_type == SIM_TYPE_USIM) {
862                                 dbg(
863                                         " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05), EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
864                                 /* EFELPand EFLI not present at this point. */
865                                 /*                                      po->language.lang_cnt = 0;*/
866                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
867                                         sizeof(struct tresp_sim_read), &resp);
868                                 return;
869                         }
870                 }
871                 break;
872
873         case SIM_EF_LP:   /* same with SIM_EF_USIM_LI */
874                 if (rt == SIM_ACCESS_SUCCESS) {
875                         dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
876                         if (command == TREQ_SIM_SET_LANGUAGE)
877                                 __set_file_data(o, ur, ef);
878                         else
879                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
880                 } else {
881                         dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
882                                 sim_type);
883                         if (sim_type == SIM_TYPE_GSM) {
884                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
885                                         sizeof(struct tresp_sim_read), &resp);
886                                 return;
887                         }
888                         /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level      */
889                         else if (sim_type == SIM_TYPE_USIM) {
890                                 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
891                                 _get_file_info(o, ur, SIM_EF_ELP);
892                         }
893                 }
894                 break;
895
896         case SIM_EF_USIM_PL:
897                 if (rt == SIM_ACCESS_SUCCESS) {
898                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
899                         if (command == TREQ_SIM_SET_LANGUAGE)
900                                 __set_file_data(o, ur, ef);
901                         else
902                                 _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
903                 } else {
904                         /* EFELIand EFPL not present, so set language count as zero and select ECC */
905                         dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
906                         tcore_user_request_send_response(ur, _find_resp_command(ur),
907                                                                                          sizeof(struct tresp_sim_read), &resp);
908                         return;
909                 }
910                 break;
911
912         case SIM_EF_ECC:
913                 if (sim_type == SIM_TYPE_GSM) {
914                         _get_file_data(o, ur, ef, 0, meta_info->data_size);
915                 } else if (sim_type == SIM_TYPE_USIM) {
916                         if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX)
917                                 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
918
919                         meta_info->current_index++;
920                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
921                 }
922                 break;
923
924         case SIM_EF_ICCID:
925         case SIM_EF_IMSI:
926         case SIM_EF_SST:
927         case SIM_EF_SPN:
928         case SIM_EF_SPDI:
929         case SIM_EF_CPHS_VOICE_MSG_WAITING:
930         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
931         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
932         case SIM_EF_CPHS_DYNAMICFLAGS:
933         case SIM_EF_CPHS_DYNAMIC2FLAG:
934         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
935         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
936         case SIM_EF_OPLMN_ACT:
937                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
938                 break;
939
940         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
941                 if (command == TREQ_SIM_SET_CALLFORWARDING)
942                         __set_file_data(o, ur, ef);
943                 else
944                         _get_file_data(o, ur, ef, 0, meta_info->data_size);
945         break;
946
947         case SIM_EF_CPHS_CPHS_INFO:
948                 if (rt == SIM_ACCESS_SUCCESS) {
949                         tcore_sim_set_cphs_status(o, TRUE);
950                         if (!tcore_user_request_ref_communicator(ur)) {
951                                 dbg("internal CPHS INFO request before sim status update");
952                                 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
953                         } else {
954                                 dbg("external CPHS INFO request");
955                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
956                         }
957                 } else {
958                         tcore_sim_set_cphs_status(o, FALSE);
959                         if (!tcore_user_request_ref_communicator(ur)) {
960                                 dbg("internal CPHS INFO request before sim status update");
961                                 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
962                         } else {
963                                 dbg("external CPHS INFO request");
964                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
965                                                                                                  sizeof(struct tresp_sim_read), &resp);
966                         }
967                 }
968                 break;
969
970         case SIM_EF_USIM_CFIS:
971                 if (command == TREQ_SIM_SET_CALLFORWARDING) {
972                         __set_file_data(o, ur, ef);
973                 } else {
974                         if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX)
975                                 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
976
977                         meta_info->current_index++;
978                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
979                 }
980                 break;
981
982         case SIM_EF_USIM_MWIS:
983                 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
984                         __set_file_data(o, ur, ef);
985                 } else {
986                         meta_info->current_index++;
987                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
988                 }
989                 break;
990
991         case SIM_EF_USIM_MBI:
992                 if (command == TREQ_SIM_SET_MAILBOX) {
993                         __set_file_data(o, ur, ef);
994                 } else {
995                         meta_info->current_index++;
996                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
997                 }
998                 break;
999
1000         case SIM_EF_OPL:
1001         case SIM_EF_PNN:
1002         case SIM_EF_CPHS_INFORMATION_NUMBERS:
1003         case SIM_EF_MSISDN:
1004                 meta_info->current_index++;
1005                 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1006                 break;
1007
1008         case SIM_EF_MBDN:
1009         case SIM_EF_CPHS_MAILBOX_NUMBERS:
1010                 if (command == TREQ_SIM_SET_MAILBOX) {
1011                         /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1012                         if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1013                                 err("Cyclic File ID. No update & return error.");
1014                                 meta_info->files.result = SIM_ACCESS_FAILED;
1015                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1016                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1017                                 break;
1018                         } else {
1019                                 __set_file_data(o, ur, ef);
1020                         }
1021                 } else {
1022                         /* Read MailBox */
1023                         meta_info->mb_count = 0;
1024                         meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1025                         if (meta_info->current_index == 0) {
1026                                 err("Invalid MBDN index");
1027                                 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1028                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1029                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1030                         } else {
1031                                 ur = tcore_user_request_ref(ur);
1032                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1033                         }
1034                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1035                 }
1036                 break;
1037
1038         default:
1039                 dbg("error - File id for get file info [0x%x]", ef);
1040                 break;
1041         }
1042 }
1043
1044 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1045 {
1046         struct imc_sim_property *meta_info = NULL;
1047
1048         dbg("Entry");
1049
1050         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1051         dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1052         switch (meta_info->file_id) {
1053         case SIM_EF_ELP:
1054         case SIM_EF_USIM_PL:
1055         case SIM_EF_LP:
1056         case SIM_EF_USIM_LI:
1057                 if (decode_ret == TRUE) {
1058 #if 0
1059                         if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1060                                 /* po->language_file = SIM_EF_LP;*/
1061                         else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL)
1062                                 /* po->language_file = SIM_EF_ELP;*/
1063 #endif
1064                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1065                 } else {
1066                         /* 2G */
1067                         /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1068                          -      EFELP is not available;
1069                          -      EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1070                          -      the ME does not support any of the languages in EFELP.
1071                          */
1072                         /* 3G */
1073                         /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1074                          -      if the EFLI has the value 'FFFF' in its highest priority position
1075                          -      if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1076                          */
1077                         if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1078                                 if (meta_info->file_id == SIM_EF_LP)
1079                                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1080                                 else
1081                                         _get_file_info(o, ur, SIM_EF_LP);
1082                         } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1083                                 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1084                                         _get_file_info(o, ur, SIM_EF_ELP);
1085                                 else
1086                                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1087                         }
1088                 }
1089                 break;
1090
1091         case SIM_EF_ECC:
1092                 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1093                         if (meta_info->current_index == meta_info->rec_count) {
1094                                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1095                         } else {
1096                                 meta_info->current_index++;
1097                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1098                         }
1099                 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1100                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1101                 } else {
1102                         dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1103                 }
1104                 break;
1105
1106         case SIM_EF_IMSI:
1107                 ur = tcore_user_request_new(NULL, NULL);   /* this is for using ur metainfo set/ref functionality. */
1108                 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1109                 break;
1110
1111         case SIM_EF_MSISDN:
1112                 if (meta_info->current_index == meta_info->rec_count) {
1113                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1114                 } else {
1115                         meta_info->current_index++;
1116                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1117                 }
1118                 break;
1119
1120         case SIM_EF_OPL:
1121                 if (meta_info->current_index == meta_info->rec_count) {
1122                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1123                 } else {
1124                         meta_info->current_index++;
1125                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1126                 }
1127                 break;
1128
1129         case SIM_EF_PNN:
1130                 if (meta_info->current_index == meta_info->rec_count) {
1131                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1132                 } else {
1133                         meta_info->current_index++;
1134                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1135                 }
1136                 break;
1137
1138         case SIM_EF_USIM_MBI:
1139                 if (meta_info->current_index == meta_info->rec_count) {
1140                         _get_file_info(0, ur, SIM_EF_MBDN);
1141                 } else {
1142                         meta_info->current_index++;
1143                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1144                 }
1145                 break;
1146
1147         case SIM_EF_MBDN:
1148         case SIM_EF_CPHS_MAILBOX_NUMBERS:
1149                 if (meta_info->mb_count == meta_info->mb_data.count) {
1150                         memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1151                         tcore_user_request_send_response(ur, _find_resp_command(ur),
1152                                                         sizeof(struct tresp_sim_read), &meta_info->files);
1153                 } else {
1154                         meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1155                         if (meta_info->current_index == 0) {
1156                                 err("Invalid MBDN index");
1157                                 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1158                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1159                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1160                         } else {
1161                                 ur = tcore_user_request_ref(ur);
1162                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1163                         }
1164                 }
1165                 break;
1166
1167         case SIM_EF_USIM_CFIS:
1168         case SIM_EF_USIM_MWIS:
1169         case SIM_EF_CPHS_INFORMATION_NUMBERS:
1170                 if (meta_info->current_index == meta_info->rec_count) {
1171                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1172                 } else {
1173                         meta_info->current_index++;
1174                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1175                 }
1176                 break;
1177
1178         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1179                 meta_info->files.result = rt;
1180                 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1181                 break;
1182
1183         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1184                 if (rt == SIM_ACCESS_SUCCESS)
1185                         meta_info->files.result = SIM_ACCESS_SUCCESS;
1186
1187                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1188                 break;
1189
1190         case SIM_EF_ICCID:
1191         case SIM_EF_SST:
1192         case SIM_EF_SPN:
1193         case SIM_EF_SPDI:
1194         case SIM_EF_OPLMN_ACT:
1195         case SIM_EF_CPHS_CPHS_INFO:
1196         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1197         case SIM_EF_CPHS_VOICE_MSG_WAITING:
1198         case SIM_EF_CPHS_DYNAMICFLAGS:
1199         case SIM_EF_CPHS_DYNAMIC2FLAG:
1200         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1201         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1202                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1203                 break;
1204
1205         default:
1206                 dbg("File id not handled [0x%x]", meta_info->file_id);
1207                 break;
1208         }
1209 }
1210
1211 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1212 {
1213         struct tnoti_sim_status noti_data = {0, };
1214
1215         if (sim_status != tcore_sim_get_status(o)) {
1216                 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1217                                 tcore_sim_get_status(o), sim_status);
1218
1219                 /* Update SIM Status */
1220                 tcore_sim_set_status(o, sim_status);
1221                 noti_data.sim_status = sim_status;
1222
1223                 /* Send notification */
1224                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1225                                 o, TNOTI_SIM_STATUS, sizeof(noti_data), &noti_data);
1226         }
1227 }
1228
1229 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1230 {
1231         const TcoreATResponse *resp = data;
1232         UserRequest *ur = NULL;
1233         CoreObject *o = NULL;
1234         GSList *tokens = NULL;
1235         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1236         const char *line;
1237         int state;
1238
1239         dbg("Entry");
1240
1241         o = tcore_pending_ref_core_object(p);
1242         ur = tcore_pending_ref_user_request(p);
1243
1244         if (resp->success > 0) {
1245                 dbg("RESPONSE OK");
1246                 if (resp->lines) {
1247                         line = (const char *)resp->lines->data;
1248                         tokens = tcore_at_tok_new(line);
1249                         if (g_slist_length(tokens) != 1) {
1250                                 msg("Invalid message");
1251                                 tcore_at_tok_free(tokens);
1252                                 return;
1253                         }
1254                 }
1255                 state = atoi(g_slist_nth_data(tokens, 0));
1256                 dbg("SIM Type is %d", state);
1257
1258                 if (state == 0) {
1259                         sim_type = SIM_TYPE_GSM;
1260                         tcore_sim_set_app_list(o, SIM_APP_TYPE_SIM);
1261                 } else if (state == 1) {
1262                         sim_type = SIM_TYPE_USIM;
1263                         tcore_sim_set_app_list(o, SIM_APP_TYPE_USIM);
1264                 } else {
1265                         sim_type = SIM_TYPE_UNKNOWN;
1266                 }
1267         } else {
1268                 dbg("RESPONSE NOK");
1269                 sim_type = SIM_TYPE_UNKNOWN;
1270         }
1271
1272         tcore_sim_set_type(o, sim_type);
1273
1274         if (sim_type != SIM_TYPE_UNKNOWN) {
1275                 /* set user request for using ur metainfo set/ref functionality */
1276                 ur = tcore_user_request_new(NULL, NULL);
1277                 _get_file_info(o, ur, SIM_EF_IMSI);
1278         }
1279
1280         tcore_at_tok_free(tokens);
1281         dbg("Exit");
1282 }
1283
1284 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1285 {
1286         const TcoreATResponse *resp = data;
1287         UserRequest *ur = NULL;
1288         CoreObject *o = NULL;
1289         struct imc_sim_property *meta_info = NULL;
1290         GSList *tokens = NULL;
1291         enum tel_sim_access_result rt;
1292         const char *line = NULL;
1293         int sw1 = 0;
1294         int sw2 = 0;
1295
1296         dbg("Entry");
1297
1298         o = tcore_pending_ref_core_object(p);
1299         ur = tcore_pending_ref_user_request(p);
1300         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1301
1302         if (resp->success > 0) {
1303                 dbg("RESPONSE OK");
1304                 if (resp->lines) {
1305                         line = (const char *)resp->lines->data;
1306                         tokens = tcore_at_tok_new(line);
1307                         if (g_slist_length(tokens) < 2) {
1308                                 err("Invalid message");
1309                                 tcore_at_tok_free(tokens);
1310                                 return;
1311                         }
1312                 }
1313                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1314                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1315
1316                 /*1. SIM access success case*/
1317                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1318                         unsigned char tag_len = 0; /*   1 or 2 bytes ??? */
1319                         unsigned short record_len = 0;
1320                         char num_of_records = 0;
1321                         unsigned char file_id_len = 0;
1322                         unsigned short file_id = 0;
1323                         unsigned short file_size = 0;
1324                         unsigned short file_type = 0;
1325                         unsigned short arr_file_id = 0;
1326
1327                         /*      handling only last 3 bits */
1328                         unsigned char file_type_tag = 0x07;
1329                         unsigned char *ptr_data;
1330
1331                         char *hexData;
1332                         char *tmp;
1333                         char *recordData = NULL;
1334                         hexData = g_slist_nth_data(tokens, 2);
1335                         dbg("hexData: %s", hexData);
1336                         dbg("hexData: %s", hexData + 1);
1337
1338                         tmp = tcore_at_tok_extract(hexData);
1339                         recordData = util_hexStringToBytes(tmp);
1340                         if (!recordData) {
1341                                 err("util_hexStringToBytes Failed!!");
1342                                 tcore_at_tok_free(tokens);
1343                                 return;
1344                         }
1345                         tcore_util_hex_dump("   ", strlen(hexData) / 2, recordData);
1346                         g_free(tmp);
1347
1348                         ptr_data = (unsigned char *)recordData;
1349                         if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1350                                 /*
1351                                  ETSI TS 102 221 v7.9.0
1352                                  - Response Data
1353                                  '62'   FCP template tag
1354                                  - Response for an EF
1355                                  '82'   M       File Descriptor
1356                                  '83'   M       File Identifier
1357                                  'A5'   O       Proprietary information
1358                                  '8A'   M       Life Cycle Status Integer
1359                                  '8B', '8C' or 'AB'     C1      Security attributes
1360                                  '80'   M       File size
1361                                  '81'   O       Total file size
1362                                  '88'   O       Short File Identifier (SFI)
1363                                  */
1364
1365                                 /* rsim.res_len has complete data length received */
1366
1367                                 /* FCP template tag - File Control Parameters tag*/
1368                                 if (*ptr_data == 0x62) {
1369                                         /* parse complete FCP tag*/
1370                                         /* increment to next byte */
1371                                         ptr_data++;
1372                                         tag_len = *ptr_data++;
1373                                         dbg("tag_len: %02x", tag_len);
1374                                         /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1375                                         if (*ptr_data == 0x82) {
1376                                                 /* increment to next byte */
1377                                                 ptr_data++;
1378                                                 /* 2 or 5 value*/
1379                                                 ptr_data++;
1380                                                 /*      unsigned char file_desc_len = *ptr_data++;*/
1381                                                 /*      dbg("file descriptor length: [%d]", file_desc_len);*/
1382                                                 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1383                                                 /* consider only last 3 bits*/
1384                                                 dbg("file_type_tag: %02x", file_type_tag);
1385                                                 file_type_tag = file_type_tag & (*ptr_data);
1386                                                 dbg("file_type_tag: %02x", file_type_tag);
1387
1388                                                 switch (file_type_tag) {
1389                                                 /* increment to next byte */
1390                                                 case 0x1:
1391                                                         dbg("Getting FileType: [Transparent file type]");
1392                                                         file_type = SIM_FTYPE_TRANSPARENT;
1393
1394                                                         /* increment to next byte */
1395                                                         ptr_data++;
1396                                                         /* increment to next byte */
1397                                                         ptr_data++;
1398                                                         break;
1399
1400                                                 case 0x2:
1401                                                         dbg("Getting FileType: [Linear fixed file type]");
1402                                                         /* increment to next byte */
1403                                                         ptr_data++;
1404                                                         /*      data coding byte - value 21 */
1405                                                         ptr_data++;
1406                                                         /*      2bytes */
1407                                                         memcpy(&record_len, ptr_data, 2);
1408                                                         /* swap bytes */
1409                                                         SWAPBYTES16(record_len);
1410                                                         ptr_data = ptr_data + 2;
1411                                                         num_of_records = *ptr_data++;
1412                                                         /* Data lossy conversation from enum (int) to unsigned char */
1413                                                         file_type = SIM_FTYPE_LINEAR_FIXED;
1414                                                         break;
1415
1416                                                 case 0x6:
1417                                                         dbg("Cyclic fixed file type");
1418                                                         /* increment to next byte */
1419                                                         ptr_data++;
1420                                                         /*      data coding byte - value 21 */
1421                                                         ptr_data++;
1422                                                         /*      2bytes */
1423                                                         memcpy(&record_len, ptr_data, 2);
1424                                                         /* swap bytes */
1425                                                         SWAPBYTES16(record_len);
1426                                                         ptr_data = ptr_data + 2;
1427                                                         num_of_records = *ptr_data++;
1428                                                         file_type = SIM_FTYPE_CYCLIC;
1429                                                         break;
1430
1431                                                 default:
1432                                                         dbg("not handled file type [0x%x]", *ptr_data);
1433                                                         break;
1434                                                 }
1435                                         } else {
1436                                                 dbg("INVALID FCP received - DEbug!");
1437                                                 tcore_at_tok_free(tokens);
1438                                                 g_free(recordData);
1439                                                 return;
1440                                         }
1441
1442                                         /*
1443                                          * File identifier - file id??
1444                                          *
1445                                          * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1446                                          */
1447                                         if (*ptr_data == 0x83) {
1448                                                 /* increment to next byte */
1449                                                 ptr_data++;
1450                                                 file_id_len = *ptr_data++;
1451                                                 dbg("file_id_len: %02x", file_id_len);
1452
1453                                                 memcpy(&file_id, ptr_data, file_id_len);
1454                                                 dbg("file_id: %x", file_id);
1455
1456                                                 /* swap bytes    */
1457                                                 SWAPBYTES16(file_id);
1458                                                 dbg("file_id: %x", file_id);
1459
1460                                                 ptr_data = ptr_data + 2;
1461                                                 dbg("Getting FileID=[0x%x]", file_id);
1462                                         } else {
1463                                                 dbg("INVALID FCP received - DEbug!");
1464                                                 tcore_at_tok_free(tokens);
1465                                                 g_free(recordData);
1466                                                 return;
1467                                         }
1468
1469                                         /*      proprietary information */
1470                                         if (*ptr_data == 0xA5) {
1471                                                 unsigned short prop_len;
1472                                                 /* increment to next byte */
1473                                                 ptr_data++;
1474
1475                                                 /* length */
1476                                                 prop_len = *ptr_data;
1477                                                 dbg("prop_len: %02x", prop_len);
1478
1479                                                 /* skip data */
1480                                                 ptr_data = ptr_data + prop_len + 1;
1481                                         } else {
1482                                                 dbg("INVALID FCP received - DEbug!");
1483                                         }
1484
1485                                         /* life cycle status integer [8A][length:0x01][status]*/
1486                                         /*
1487                                          status info b8~b1
1488                                          00000000 : No information given
1489                                          00000001 : creation state
1490                                          00000011 : initialization state
1491                                          000001-1 : operation state -activated
1492                                          000001-0 : operation state -deactivated
1493                                          000011-- : Termination state
1494                                          b8~b5 !=0, b4~b1=X : Proprietary
1495                                          Any other value : RFU
1496                                          */
1497                                         if (*ptr_data == 0x8A) {
1498                                                 /* increment to next byte */
1499                                                 ptr_data++;
1500                                                 /* length - value 1 */
1501                                                 ptr_data++;
1502
1503                                                 switch (*ptr_data) {
1504                                                 case 0x04:
1505                                                 case 0x06:
1506                                                         dbg("<RX> operation state -deactivated");
1507                                                         ptr_data++;
1508                                                         break;
1509
1510                                                 case 0x05:
1511                                                 case 0x07:
1512                                                         dbg("<RX> operation state -activated");
1513                                                         ptr_data++;
1514                                                         break;
1515
1516                                                 default:
1517                                                         dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1518                                                         ptr_data++;
1519                                                         break;
1520                                                 }
1521                                         }
1522
1523                                         /* related to security attributes : currently not handled*/
1524                                         if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1525                                                 /* increment to next byte */
1526                                                 ptr_data++;
1527                                                 /* if tag length is 3 */
1528                                                 if (*ptr_data == 0x03) {
1529                                                         /* increment to next byte */
1530                                                         ptr_data++;
1531                                                         /* EFARR file id */
1532                                                         memcpy(&arr_file_id, ptr_data, 2);
1533                                                         /* swap byes */
1534                                                         SWAPBYTES16(arr_file_id);
1535                                                         ptr_data = ptr_data + 2;
1536                                                         ptr_data++;     /*arr_file_id_rec_num = *ptr_data++; */
1537                                                 } else {
1538                                                         /* if tag length is not 3 */
1539                                                         /* ignoring bytes       */
1540                                                         dbg("Useless security attributes, so jump to next tag");
1541                                                         ptr_data = ptr_data + (*ptr_data + 1);
1542                                                 }
1543                                         } else {
1544                                                 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1545                                                 tcore_at_tok_free(tokens);
1546                                                 g_free(recordData);
1547                                                 return;
1548                                         }
1549
1550                                         dbg("Current ptr_data value is [%x]", *ptr_data);
1551
1552                                         /* file size excluding structural info*/
1553                                         if (*ptr_data == 0x80) {
1554                                                 /* for EF file size is body of file and for Linear or cyclic it is
1555                                                  * number of recXsizeof(one record)
1556                                                  */
1557                                                 /* increment to next byte */
1558                                                 ptr_data++;
1559                                                 /* length is 1 byte - value is 2 bytes or more */
1560                                                 ptr_data++;
1561                                                 memcpy(&file_size, ptr_data, 2);
1562                                                 /* swap bytes */
1563                                                 SWAPBYTES16(file_size);
1564                                                 ptr_data = ptr_data + 2;
1565                                         } else {
1566                                                 dbg("INVALID FCP received - DEbug!");
1567                                                 tcore_at_tok_free(tokens);
1568                                                 g_free(recordData);
1569                                                 return;
1570                                         }
1571
1572                                         /* total file size including structural info*/
1573                                         if (*ptr_data == 0x81) {
1574                                                 /* int len; */
1575                                                 /* increment to next byte */
1576                                                 ptr_data++;
1577                                                 /* length */
1578                                                 /* len = *ptr_data; */
1579                                                 /* ignored bytes */
1580                                                 ptr_data = ptr_data + 3;
1581                                         } else {
1582                                                 dbg("INVALID FCP received - DEbug!");
1583                                                 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1584                                                 /* return -1; */
1585                                         }
1586                                         /*short file identifier ignored*/
1587                                         if (*ptr_data == 0x88) {
1588                                                 dbg("0x88: Do Nothing");
1589                                                 /*DO NOTHING*/
1590                                         }
1591                                 } else {
1592                                         dbg("INVALID FCP received - DEbug!");
1593                                         tcore_at_tok_free(tokens);
1594                                         g_free(recordData);
1595                                         return;
1596                                 }
1597                         } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1598                                 unsigned char gsm_specific_file_data_len = 0;
1599                                 /*      ignore RFU byte1 and byte2 */
1600                                 ptr_data++;
1601                                 ptr_data++;
1602                                 /*      file size */
1603                                 memcpy(&file_size, ptr_data, 2);
1604                                 /* swap bytes */
1605                                 SWAPBYTES16(file_size);
1606                                 /*      parsed file size */
1607                                 ptr_data = ptr_data + 2;
1608                                 /* file id */
1609                                 memcpy(&file_id, ptr_data, 2);
1610                                 SWAPBYTES16(file_id);
1611                                 dbg("FILE id --> [%x]", file_id);
1612                                 ptr_data = ptr_data + 2;
1613                                 /* save file type - transparent, linear fixed or cyclic */
1614                                 file_type_tag = (*(ptr_data + 7));
1615
1616                                 switch (*ptr_data) {
1617                                 case 0x0:
1618                                         /* RFU file type */
1619                                         dbg("RFU file type- not handled - Debug!");
1620                                         break;
1621
1622                                 case 0x1:
1623                                         /* MF file type */
1624                                         dbg("MF file type - not handled - Debug!");
1625                                         break;
1626
1627                                 case 0x2:
1628                                         /* DF file type */
1629                                         dbg("DF file type - not handled - Debug!");
1630                                         break;
1631
1632                                 case 0x4:
1633                                         /* EF file type */
1634                                         dbg("EF file type [%d] ", file_type_tag);
1635                                         /*      increment to next byte */
1636                                         ptr_data++;
1637
1638                                         if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1639                                                 /* increament to next byte as this byte is RFU */
1640                                                 ptr_data++;
1641                                                 file_type =
1642                                                         (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1643                                         } else {
1644                                                 /* increment to next byte */
1645                                                 ptr_data++;
1646                                                 /*      For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1647                                                 /* the INCREASE command is allowed on the selected cyclic file. */
1648                                                 file_type = SIM_FTYPE_CYCLIC;
1649                                         }
1650                                         /* bytes 9 to 11 give SIM file access conditions */
1651                                         ptr_data++;
1652                                         /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1653                                         ptr_data++;
1654                                         /* byte 11 is invalidate and rehabilate nibbles */
1655                                         ptr_data++;
1656                                         /* byte 12 - file status */
1657                                         ptr_data++;
1658                                         /* byte 13 - GSM specific data */
1659                                         gsm_specific_file_data_len = *ptr_data;
1660                                         dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1661                                         ptr_data++;
1662                                         /*      byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1663                                         ptr_data++;
1664                                         /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1665                                         record_len = *ptr_data;
1666                                         dbg("record length[%d], file size[%d]", record_len, file_size);
1667
1668                                         if (record_len != 0)
1669                                                 num_of_records = (file_size / record_len);
1670
1671                                         dbg("Number of records [%d]", num_of_records);
1672                                         break;
1673
1674                                 default:
1675                                         dbg("not handled file type");
1676                                         break;
1677                                 }
1678                         } else {
1679                                 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1680                         }
1681
1682                         dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1683                                 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1684
1685                         meta_info->file_type = file_type;
1686                         meta_info->data_size = file_size;
1687                         meta_info->rec_length = record_len;
1688                         meta_info->rec_count = num_of_records;
1689                         meta_info->current_index = 0; /* reset for new record type EF */
1690                         rt = SIM_ACCESS_SUCCESS;
1691                         g_free(recordData);
1692                 } else {
1693                         /*2. SIM access fail case*/
1694                         dbg("error to get ef[0x%x]", meta_info->file_id);
1695                         dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1696                         rt = _decode_status_word(sw1, sw2);
1697                 }
1698                 ur = tcore_user_request_ref(ur);
1699
1700                 dbg("Calling _next_from_get_file_info");
1701                 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1702                 tcore_at_tok_free(tokens);
1703         } else {
1704                 dbg("RESPONSE NOK");
1705                 dbg("error to get ef[0x%x]", meta_info->file_id);
1706                 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1707                 rt = SIM_ACCESS_FAILED;
1708
1709                 ur = tcore_user_request_ref(ur);
1710                 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1711         }
1712         dbg("Exit");
1713 }
1714
1715 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1716 {
1717         const TcoreATResponse *resp = data;
1718         UserRequest *ur = NULL;
1719         CoreObject *o = NULL;
1720         struct imc_sim_property *meta_info = NULL;
1721         GSList *tokens = NULL;
1722         enum tel_sim_access_result rt;
1723         gboolean dr = FALSE;
1724         const char *line = NULL;
1725         char *res = NULL;
1726         char *tmp = NULL;
1727         int res_len;
1728         int sw1 = 0;
1729         int sw2 = 0;
1730
1731         dbg("Entry");
1732
1733         o = tcore_pending_ref_core_object(p);
1734         ur = tcore_pending_ref_user_request(p);
1735         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1736
1737         if (resp->success > 0) {
1738                 dbg("RESPONSE OK");
1739                 if (resp->lines) {
1740                         line = (const char *)resp->lines->data;
1741                         tokens = tcore_at_tok_new(line);
1742                         if (g_slist_length(tokens) != 3) {
1743                                 msg("Invalid message");
1744                                 tcore_at_tok_free(tokens);
1745                                 return;
1746                         }
1747                 }
1748                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1749                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1750                 res = g_slist_nth_data(tokens, 2);
1751
1752                 tmp = tcore_at_tok_extract(res);
1753                 if (!tmp)
1754                         return;
1755                 res = util_hexStringToBytes(tmp);
1756                 res_len = strlen(tmp) / 2;
1757                 dbg("Response: [%s] Response length: [%d]", res, res_len);
1758
1759                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1760                         rt = SIM_ACCESS_SUCCESS;
1761                         meta_info->files.result = rt;
1762
1763                         dbg("File ID: [0x%x]", meta_info->file_id);
1764                         switch (meta_info->file_id) {
1765                         case SIM_EF_IMSI:
1766                         {
1767                                 struct tel_sim_imsi *imsi = NULL;
1768
1769                                 dbg("Data: [%s]", res);
1770                                 imsi = g_try_new0(struct tel_sim_imsi, 1);
1771                                 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1772                                 if (dr == FALSE) {
1773                                         err("IMSI decoding failed");
1774                                 } else {
1775                                         //_sim_check_identity(o, imsi);
1776                                         tcore_sim_set_imsi(o, imsi);
1777                                 }
1778
1779                                 /* Free memory */
1780                                 g_free(imsi);
1781                         }
1782                         break;
1783
1784                         case SIM_EF_ICCID:
1785                                 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1786                         break;
1787
1788                         case SIM_EF_ELP:                        /* 2G EF - 2 bytes decoding */
1789                         case SIM_EF_USIM_LI:            /* 3G EF - 2 bytes decoding */
1790                         case SIM_EF_USIM_PL:            /* 3G EF - same as EFELP, so 2 byte decoding */
1791                         case SIM_EF_LP:                         /* 1 byte encoding */
1792                                 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1793                                                 && (meta_info->file_id == SIM_EF_LP)) {
1794                                         /*
1795                                          * 2G LP(0x6F05) has 1 byte for each language
1796                                          */
1797                                         dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1798                                                                 (unsigned char *)res, res_len);
1799                                 } else {
1800                                         /*
1801                                          * 3G LI(0x6F05)/PL(0x2F05),
1802                                          * 2G ELP(0x2F05) has 2 bytes for each language
1803                                          */
1804                                         dr = tcore_sim_decode_li(meta_info->file_id,
1805                                                                 &meta_info->files.data.language,
1806                                                                 (unsigned char *)res, res_len);
1807                                 }
1808                         break;
1809
1810                         case SIM_EF_SPN:
1811                                 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1812                                                                 (unsigned char *)res, res_len);
1813                         break;
1814
1815                         case SIM_EF_SPDI:
1816                                 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1817                                                                 (unsigned char *)res, res_len);
1818                         break;
1819
1820                         case SIM_EF_SST: /* EF UST has same address */
1821                         {
1822                                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1823                                         dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1824                                         if (dr == FALSE) {
1825                                                 dbg("SST decoding failed");
1826                                                 tcore_sim_set_service_table(o, NULL);
1827                                         } else {
1828                                                 int i = 0, size = sizeof(struct tel_sim_sst);
1829                                                 char *temp = NULL;
1830                                                 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1831                                                 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1832                                                         memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1833                                                         for (i = 0; i < size; i++) {
1834                                                                 if (temp[i] == 1)
1835                                                                         temp[i] = '1';
1836                                                                 else
1837                                                                         temp[i] = '0';
1838                                                         }
1839                                                         dbg("svct.table.sst=[%s]", temp);
1840                                                         g_free(temp);
1841                                                 }
1842                                                 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1843                                         }
1844                                 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1845                                         dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1846                                         if (dr == FALSE) {
1847                                                 dbg("SST decoding failed");
1848                                                 tcore_sim_set_service_table(o, NULL);
1849                                         } else {
1850                                                 int i = 0, size = sizeof(struct tel_sim_ust);
1851                                                 char *temp = NULL;
1852                                                 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1853                                                 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1854                                                         memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1855                                                         for (i = 0; i < size; i++) {
1856                                                                 if (temp[i] == 1)
1857                                                                         temp[i] = '1';
1858                                                                 else
1859                                                                         temp[i] = '0';
1860                                                         }
1861                                                         dbg("svct.table.ust=[%s]", temp);
1862                                                         g_free(temp);
1863                                                 }
1864                                                 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1865                                         }
1866                                 } else {
1867                                         dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(o));
1868                                 }
1869                         }
1870                         break;
1871
1872                         case SIM_EF_ECC:
1873                         {
1874                                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1875                                         dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1876                                 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1877                                         struct tel_sim_ecc *ecc = NULL;
1878
1879                                         ecc = g_try_new0(struct tel_sim_ecc, 1);
1880                                         dbg("Index [%d]", meta_info->current_index);
1881
1882                                         dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1883                                         if (dr == TRUE) {
1884                                                 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1885                                                 meta_info->files.data.ecc.ecc_count++;
1886                                         }
1887
1888                                         /* Free memory */
1889                                         g_free(ecc);
1890                                 } else {
1891                                         dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1892                                 }
1893                         }
1894                         break;
1895
1896                         case SIM_EF_MSISDN:
1897                         {
1898                                 struct tel_sim_msisdn *msisdn = NULL;
1899
1900                                 dbg("Index [%d]", meta_info->current_index);
1901                                 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1902                                 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1903                                 if (dr == TRUE) {
1904                                         memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1905                                                                 msisdn, sizeof(struct tel_sim_msisdn));
1906
1907                                         meta_info->files.data.msisdn_list.count++;
1908                                 }
1909
1910                                 /* Free memory */
1911                                 g_free(msisdn);
1912                         }
1913                         break;
1914
1915                         case SIM_EF_OPL:
1916                         {
1917                                 struct tel_sim_opl *opl = NULL;
1918
1919                                 dbg("decode w/ index [%d]", meta_info->current_index);
1920
1921                                 opl = g_try_new0(struct tel_sim_opl, 1);
1922                                 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1923                                 if (dr == TRUE) {
1924                                         memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1925                                                         opl, sizeof(struct tel_sim_opl));
1926                                         meta_info->files.data.opl.opl_count++;
1927                                 }
1928
1929                                 /* Free memory */
1930                                 g_free(opl);
1931                         }
1932                         break;
1933
1934                         case SIM_EF_PNN:
1935                         {
1936                                 struct tel_sim_pnn *pnn = NULL;
1937
1938                                 dbg("decode w/ index [%d]", meta_info->current_index);
1939
1940                                 pnn = g_try_new0(struct tel_sim_pnn, 1);
1941                                 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1942                                 if (dr == TRUE) {
1943                                         memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1944                                                                 pnn, sizeof(struct tel_sim_pnn));
1945
1946                                         meta_info->files.data.pnn.pnn_count++;
1947                                 }
1948
1949                                 /* Free memory */
1950                                 g_free(pnn);
1951                         }
1952                         break;
1953
1954                         case SIM_EF_OPLMN_ACT:
1955                                 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1956                                                                                 (unsigned char *)res, res_len);
1957                         break;
1958
1959                         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1960                                 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1961                         break;
1962
1963                         case SIM_EF_USIM_MBI: /* linear type */
1964                         {
1965                                 struct tel_sim_mbi *mbi = NULL;
1966
1967                                 mbi = g_try_new0(struct tel_sim_mbi, 1);
1968                                 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
1969                                 if (dr == TRUE) {
1970                                         memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
1971                                                                                 mbi, sizeof(struct tel_sim_mbi));
1972                                         meta_info->mbi_list.profile_count++;
1973
1974                                         dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
1975                                         dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].voice_index);
1976                                         dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].fax_index);
1977                                         dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].email_index);
1978                                         dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].other_index);
1979                                         dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].video_index);
1980                                 }
1981
1982                                 /* Free memory */
1983                                 g_free(mbi);
1984                         }
1985                         break;
1986
1987                         case SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1988                         case SIM_EF_MBDN: /* linear type */
1989                                 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
1990                                                                         (unsigned char *)res, res_len);
1991                                 meta_info->mb_count++;
1992                         break;
1993
1994                         case SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1995                                 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
1996                                                                         (unsigned char *)res, res_len);
1997                         break;
1998
1999                         case SIM_EF_USIM_MWIS: /* linear type */
2000                         {
2001                                 struct tel_sim_mw *mw = NULL;
2002
2003                                 mw = g_try_new0(struct tel_sim_mw, 1);
2004
2005                                 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
2006                                 if (dr == TRUE) {
2007                                         memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
2008                                         meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
2009                                         meta_info->files.data.mw.mw_list.profile_count++;
2010                                 }
2011
2012                                 /* Free memory */
2013                                 g_free(mw);
2014                         }
2015                         break;
2016
2017                         case SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
2018                                 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2019                                                                         (unsigned char *)res, res_len);
2020                         break;
2021
2022                         case SIM_EF_USIM_CFIS: /* linear type */
2023                         {
2024                                 struct tel_sim_cfis *cf = NULL;
2025
2026                                 cf = g_try_new0(struct tel_sim_cfis, 1);
2027                                 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2028                                 if (dr == TRUE) {
2029                                         memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2030                                                                         cf, sizeof(struct tel_sim_cfis));
2031
2032                                         meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2033                                         meta_info->files.data.cf.cf_list.profile_count++;
2034                                 }
2035
2036                                 /* Free memory */
2037                                 g_free(cf);
2038                         }
2039                         break;
2040
2041                         case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2042                                 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2043                         break;
2044
2045                         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2046                                 dr = tcore_sim_decode_ons((unsigned char *)&meta_info->files.data.cphs_net.full_name,
2047                                                                         (unsigned char *)res, res_len);
2048                                 dbg("meta_info->files.result[%d], meta_info->files.data.cphs_net.full_name[%s]",
2049                                                 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2050                         break;
2051
2052                         case SIM_EF_CPHS_DYNAMICFLAGS:
2053                                 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2054                                                                                 p_data->response, p_data->response_len);*/
2055                         break;
2056
2057                         case SIM_EF_CPHS_DYNAMIC2FLAG:
2058                                 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2059                                                                                 p_data->response_len);*/
2060                         break;
2061
2062                         case SIM_EF_CPHS_CPHS_INFO:
2063                                 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2064                                                                                 (unsigned char *)res, res_len);
2065                         break;
2066
2067                         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2068                                 dr = tcore_sim_decode_short_ons((unsigned char *)&meta_info->files.data.cphs_net.short_name,
2069                                                                                 (unsigned char *)res, res_len);
2070                         break;
2071
2072                         case SIM_EF_CPHS_INFORMATION_NUMBERS:
2073                                 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2074                         break;
2075
2076                         default:
2077                                 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2078                                 dr = 0;
2079                         break;
2080                         }
2081                 } else {
2082                         rt = _decode_status_word(sw1, sw2);
2083                         meta_info->files.result = rt;
2084                 }
2085
2086                 /* Free memory */
2087                 g_free(tmp);
2088                 g_free(res);
2089
2090                 /* Free tokens */
2091                 tcore_at_tok_free(tokens);
2092         } else {
2093                 dbg("RESPONSE NOK");
2094                 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2095                 rt = SIM_ACCESS_FAILED;
2096         }
2097
2098         /* Reference User Request */
2099         ur = tcore_user_request_ref(ur);
2100
2101         /* Get File data */
2102         _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2103
2104         dbg("Exit");
2105 }
2106
2107 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2108 {
2109         const TcoreATResponse *resp = data;
2110         UserRequest *ur = NULL;
2111         CoreObject *o = NULL;
2112         struct imc_sim_property *sp = NULL;
2113         GSList *tokens = NULL;
2114         const char *line = NULL;
2115         int lock_type = 0;
2116         int attempts_left = 0;
2117         int time_penalty = 0;
2118
2119         dbg("Entry");
2120
2121         o = tcore_pending_ref_core_object(p);
2122         sp = tcore_sim_ref_userdata(o);
2123         if (!sp) {
2124                 err("user data is null");
2125                 return;
2126         }
2127         ur = tcore_pending_ref_user_request(p);
2128
2129         if (resp->success > 0) {
2130                 dbg("RESPONSE OK");
2131                 if (resp->lines) {
2132                         line = (const char *)resp->lines->data;
2133                         tokens = tcore_at_tok_new(line);
2134                         if (g_slist_length(tokens) < 3) {
2135                                 msg("Invalid message");
2136                                 tcore_at_tok_free(tokens);
2137                                 return;
2138                         }
2139                 }
2140                 lock_type = atoi(g_slist_nth_data(tokens, 0));
2141                 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2142                 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2143
2144                 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2145                         lock_type, attempts_left, time_penalty);
2146
2147                 switch (sp->current_sec_op) {
2148                 case SEC_PIN1_VERIFY:
2149                 case SEC_PIN2_VERIFY:
2150                 case SEC_SIM_VERIFY:
2151                 case SEC_ADM_VERIFY:
2152                 {
2153                         struct tresp_sim_verify_pins v_pin = {0, };
2154
2155                         v_pin.result = SIM_INCORRECT_PASSWORD;
2156                         v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2157                         v_pin.retry_count = attempts_left;
2158                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2159                                                                                          sizeof(struct tresp_sim_verify_pins), &v_pin);
2160                 }
2161                 break;
2162
2163                 case SEC_PUK1_VERIFY:
2164                 case SEC_PUK2_VERIFY:
2165                 {
2166                         struct tresp_sim_verify_puks v_puk = {0, };
2167
2168                         v_puk.result = SIM_INCORRECT_PASSWORD;
2169                         v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2170                         v_puk.retry_count = attempts_left;
2171                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2172                                                                                          sizeof(struct tresp_sim_verify_puks), &v_puk);
2173                 }
2174                 break;
2175
2176                 case SEC_PIN1_CHANGE:
2177                 case SEC_PIN2_CHANGE:
2178                 {
2179                         struct tresp_sim_change_pins change_pin = {0, };
2180
2181                         change_pin.result = SIM_INCORRECT_PASSWORD;
2182                         change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2183                         change_pin.retry_count = attempts_left;
2184                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2185                                                                                          sizeof(struct tresp_sim_change_pins), &change_pin);
2186                 }
2187                 break;
2188
2189                 case SEC_PIN1_DISABLE:
2190                 case SEC_PIN2_DISABLE:
2191                 case SEC_FDN_DISABLE:
2192                 case SEC_SIM_DISABLE:
2193                 case SEC_NET_DISABLE:
2194                 case SEC_NS_DISABLE:
2195                 case SEC_SP_DISABLE:
2196                 case SEC_CP_DISABLE:
2197                 {
2198                         struct tresp_sim_disable_facility dis_facility = {0, };
2199
2200                         dis_facility.result = SIM_INCORRECT_PASSWORD;
2201                         dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2202                         dis_facility.retry_count = attempts_left;
2203                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2204                                                                                          sizeof(struct tresp_sim_disable_facility), &dis_facility);
2205                 }
2206                 break;
2207
2208                 case SEC_PIN1_ENABLE:
2209                 case SEC_PIN2_ENABLE:
2210                 case SEC_FDN_ENABLE:
2211                 case SEC_SIM_ENABLE:
2212                 case SEC_NET_ENABLE:
2213                 case SEC_NS_ENABLE:
2214                 case SEC_SP_ENABLE:
2215                 case SEC_CP_ENABLE:
2216                 {
2217                         struct tresp_sim_enable_facility en_facility = {0, };
2218
2219                         en_facility.result = SIM_INCORRECT_PASSWORD;
2220                         en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2221                         en_facility.retry_count = attempts_left;
2222                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2223                                                                                          sizeof(struct tresp_sim_enable_facility), &en_facility);
2224                 }
2225                 break;
2226
2227                 default:
2228                         dbg("not handled sec op[%d]", sp->current_sec_op);
2229                 break;
2230                 }
2231
2232                 /* Free tokens */
2233                 tcore_at_tok_free(tokens);
2234         }
2235
2236         dbg("Exit");
2237 }
2238
2239 static gboolean _get_sim_type(CoreObject *o)
2240 {
2241         TcoreHal *hal = NULL;
2242         TcoreATRequest *req = NULL;
2243         TcorePending *pending = NULL;
2244         UserRequest *ur = NULL;
2245         char *cmd_str = NULL;
2246
2247         dbg("Entry");
2248
2249         hal = tcore_object_get_hal(o);
2250         pending = tcore_pending_new(o, 0);
2251         if (!pending) {
2252                 err("Pending is NULL");
2253                 return FALSE;
2254         }
2255         cmd_str = g_strdup_printf("AT+XUICC?");
2256         req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2257         if (req == NULL) {
2258                 tcore_pending_free(pending);
2259                 g_free(cmd_str);
2260                 return FALSE;
2261         }
2262         g_free(cmd_str);
2263
2264         dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2265                                 req->cmd, req->prefix, strlen(req->cmd));
2266
2267         tcore_pending_set_request_data(pending, 0, req);
2268         tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2269         tcore_pending_link_user_request(pending, ur);
2270         tcore_hal_send_request(hal, pending);
2271
2272         dbg("Exit");
2273         return TRUE;
2274 }
2275
2276 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2277 {
2278         TcoreHal *hal = NULL;
2279         TcorePending *pending = NULL;
2280         struct imc_sim_property meta_info = {0, };
2281         char *cmd_str = NULL;
2282         TReturn ret = TCORE_RETURN_FAILURE;
2283         int trt = 0;
2284
2285         dbg("Entry");
2286
2287         meta_info.file_id = ef;
2288         dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2289         hal = tcore_object_get_hal(o);
2290         dbg("hal: %x", hal);
2291
2292         trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2293         dbg("trt[%d]", trt);
2294         cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef);      /*command - 192 : GET RESPONSE*/
2295         dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2296
2297         pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2298         tcore_pending_link_user_request(pending, ur);
2299         ret = tcore_hal_send_request(hal, pending);
2300         if (TCORE_RETURN_SUCCESS != ret)
2301                 tcore_user_request_free(ur);
2302
2303         g_free(cmd_str);
2304         dbg("Exit");
2305         return TCORE_RETURN_SUCCESS;
2306 }
2307
2308 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2309 {
2310         TcoreHal *hal = NULL;
2311         TcoreATRequest *req = NULL;
2312         TcorePending *pending = NULL;
2313         char *cmd_str = NULL;
2314         int p1 = 0;
2315         int p2 = 0;
2316         int p3 = 0;
2317
2318         dbg("Entry");
2319         hal = tcore_object_get_hal(o);
2320         pending = tcore_pending_new(o, 0);
2321         if (!pending) {
2322                 err("Pending is NULL");
2323                 return FALSE;
2324         }
2325
2326         dbg("file_id: %x", ef);
2327
2328         p1 = (unsigned char) (offset & 0xFF00) >> 8;
2329         p2 = (unsigned char) offset & 0x00FF; /* offset low */
2330         p3 = (unsigned char) length;
2331
2332         cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3);     /*command - 176 : READ BINARY*/
2333
2334         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2335         if (req == NULL) {
2336                 tcore_pending_free(pending);
2337                 g_free(cmd_str);
2338                 return FALSE;
2339         }
2340         g_free(cmd_str);
2341
2342         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2343                                 req->cmd, req->prefix, strlen(req->cmd));
2344
2345         tcore_pending_set_request_data(pending, 0, req);
2346         tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2347         tcore_pending_link_user_request(pending, ur);
2348         tcore_hal_send_request(hal, pending);
2349
2350         dbg("Exit");
2351         return TRUE;
2352 }
2353
2354 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2355 {
2356         TcoreHal *hal = NULL;
2357         TcoreATRequest *req = NULL;
2358         TcorePending *pending = NULL;
2359         char *cmd_str = NULL;
2360         int p1 = 0;
2361         int p2 = 0;
2362         int p3 = 0;
2363
2364         dbg("Entry");
2365
2366         hal = tcore_object_get_hal(o);
2367         pending = tcore_pending_new(o, 0);
2368         if (!pending) {
2369                 err("Pending is NULL");
2370                 return FALSE;
2371         }
2372
2373         p1 = (unsigned char) index;
2374         p2 = (unsigned char) 0x04;    /* 0x4 for absolute mode */
2375         p3 = (unsigned char) length;
2376
2377         cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3);     /*command - 178 : READ RECORD*/
2378
2379         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2380         if (req == NULL) {
2381                 tcore_pending_free(pending);
2382                 g_free(cmd_str);
2383                 return FALSE;
2384         }
2385         g_free(cmd_str);
2386
2387         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2388                                 req->cmd, req->prefix, strlen(req->cmd));
2389
2390         tcore_pending_set_request_data(pending, 0, req);
2391         tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2392         tcore_pending_link_user_request(pending, ur);
2393         tcore_hal_send_request(hal, pending);
2394
2395         dbg("Exit");
2396         return TRUE;
2397 }
2398
2399 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2400 {
2401         TcoreHal *hal = NULL;
2402         TcoreATRequest *req = NULL;
2403         TcorePending *pending = NULL;
2404         char *cmd_str = NULL;
2405         int lock_type = 0;
2406         struct imc_sim_property *sp = NULL;
2407
2408         dbg("Entry");
2409
2410         hal = tcore_object_get_hal(o);
2411         pending = tcore_pending_new(o, 0);
2412         if (!pending) {
2413                 err("Pending is NULL");
2414                 return TCORE_RETURN_FAILURE;
2415         }
2416         sp = tcore_sim_ref_userdata(o);
2417         if (!sp) {
2418                 err("user data is null");
2419                 tcore_pending_free(pending);
2420                 return TCORE_RETURN_FAILURE;
2421         }
2422
2423         switch (sp->current_sec_op) {
2424         case SEC_PIN1_VERIFY:
2425         case SEC_PIN1_CHANGE:
2426         case SEC_PIN1_ENABLE:
2427         case SEC_PIN1_DISABLE:
2428                 lock_type = 1;
2429                 break;
2430
2431         case SEC_PIN2_VERIFY:
2432         case SEC_PIN2_CHANGE:
2433         case SEC_PIN2_ENABLE:
2434         case SEC_PIN2_DISABLE:
2435         case SEC_FDN_ENABLE:
2436         case SEC_FDN_DISABLE:
2437                 lock_type = 2;
2438                 break;
2439
2440         case SEC_PUK1_VERIFY:
2441                 lock_type = 3;
2442                 break;
2443
2444         case SEC_PUK2_VERIFY:
2445                 lock_type = 4;
2446                 break;
2447
2448         case SEC_NET_ENABLE:
2449         case SEC_NET_DISABLE:
2450                 lock_type = 5;
2451                 break;
2452
2453         case SEC_NS_ENABLE:
2454         case SEC_NS_DISABLE:
2455                 lock_type = 6;
2456                 break;
2457
2458         case SEC_SP_ENABLE:
2459         case SEC_SP_DISABLE:
2460                 lock_type = 7;
2461                 break;
2462
2463         case SEC_CP_ENABLE:
2464         case SEC_CP_DISABLE:
2465                 lock_type = 8;
2466                 break;
2467
2468         case SEC_ADM_VERIFY:
2469                 lock_type = 9;
2470                 break;
2471
2472         default:
2473                 break;
2474         }
2475
2476         cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2477         req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2478         if (req == NULL) {
2479                 tcore_pending_free(pending);
2480                 g_free(cmd_str);
2481                 return TCORE_RETURN_FAILURE;
2482         }
2483         g_free(cmd_str);
2484
2485         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2486                                 req->cmd, req->prefix, strlen(req->cmd));
2487
2488         tcore_pending_set_request_data(pending, 0, req);
2489         tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2490         tcore_pending_link_user_request(pending, ur);
2491         tcore_hal_send_request(hal, pending);
2492
2493         dbg("Exit");
2494         return TCORE_RETURN_SUCCESS;
2495 }
2496
2497 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2498 {
2499         char *line = NULL;
2500         GSList *tokens = NULL;
2501         GSList *lines = NULL;
2502
2503         dbg("Function entry");
2504
2505         lines = (GSList *)event_info;
2506         if (1 != g_slist_length(lines)) {
2507                 dbg("unsolicited msg but multiple line");
2508                 goto OUT;
2509         }
2510         line = (char *)(lines->data);
2511         tokens = tcore_at_tok_new(line);
2512         if (g_slist_length(tokens) != 1) {
2513                 msg("Invalid message");
2514                 tcore_at_tok_free(tokens);
2515                 return TRUE;
2516         }
2517
2518 OUT:
2519         dbg("Exit");
2520         if (NULL != tokens)
2521                 tcore_at_tok_free(tokens);
2522         return TRUE;
2523 }
2524
2525 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2526                                 unsigned int sms_ready)
2527 {
2528         Server *server = tcore_plugin_ref_server(plugin);
2529         struct tnoti_sms_ready_status sms_ready_noti;
2530         CoreObject *co_sms;
2531
2532         dbg("Entry");
2533
2534         co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2535         if (co_sms == NULL) {
2536                 err("Can't find SMS core object");
2537                 return;
2538         }
2539
2540         if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2541                 return;
2542
2543         tcore_sms_set_ready_status(co_sms, sms_ready);
2544
2545         if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2546                 sms_ready_noti.status = sms_ready;
2547                 tcore_server_send_notification(server, co_sms,
2548                                                 TNOTI_SMS_DEVICE_READY,
2549                                                 sizeof(sms_ready_noti),
2550                                                 &sms_ready_noti);
2551         }
2552
2553         dbg("Exit");
2554 }
2555
2556 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2557 {
2558         TcorePlugin *plugin = tcore_object_ref_plugin(o);
2559         enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2560         GSList *tokens = NULL;
2561         GSList *lines;
2562         const char *line;
2563         int sim_state = 0;
2564         enum telephony_sms_ready_status sms_state = 0;
2565
2566         dbg("Entry");
2567
2568         lines = (GSList *)event_info;
2569         if (g_slist_length(lines) != 1) {
2570                 err("Unsolicited message BUT multiple lines");
2571                 goto out;
2572         }
2573
2574         line = lines->data;
2575
2576         /* Create 'tokens' */
2577         tokens = tcore_at_tok_new(line);
2578
2579         /* SIM State */
2580         if (g_slist_length(tokens) == 4) {
2581                 sim_state = atoi(g_slist_nth_data(tokens, 1));
2582                 sms_state = atoi(g_slist_nth_data(tokens, 3));
2583
2584                 notify_sms_state(plugin, o, sms_state);
2585         } else if (g_slist_length(tokens) == 1) {
2586                 sim_state = atoi(g_slist_nth_data(tokens, 0));
2587         } else {
2588                 err("Invalid message");
2589                 goto out;
2590         }
2591
2592         switch (sim_state) {
2593         case 0:
2594                 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2595                 dbg("NO SIM");
2596                 break;
2597
2598         case 1:
2599                 sim_status = SIM_STATUS_PIN_REQUIRED;
2600                 dbg("PIN REQUIRED");
2601                 break;
2602
2603         case 2:
2604                 sim_status = SIM_STATUS_INITIALIZING;
2605                 dbg("PIN DISABLED AT BOOT UP");
2606                 break;
2607
2608         case 3:
2609                 sim_status = SIM_STATUS_INITIALIZING;
2610                 dbg("PIN VERIFIED");
2611                 break;
2612
2613         case 4:
2614                 sim_status = SIM_STATUS_PUK_REQUIRED;
2615                 dbg("PUK REQUIRED");
2616                 break;
2617
2618         case 5:
2619                 sim_status = SIM_STATUS_CARD_BLOCKED;
2620                 dbg("CARD PERMANENTLY BLOCKED");
2621                 break;
2622
2623         case 6:
2624                 sim_status = SIM_STATUS_CARD_ERROR;
2625                 dbg("SIM CARD ERROR");
2626                 break;
2627
2628         case 7:
2629                 sim_status = SIM_STATUS_INIT_COMPLETED;
2630                 dbg("SIM INIT COMPLETED");
2631                 break;
2632
2633         case 8:
2634                 sim_status = SIM_STATUS_CARD_ERROR;
2635                 dbg("SIM CARD ERROR");
2636                 break;
2637
2638         case 9:
2639                 sim_status = SIM_STATUS_CARD_REMOVED;
2640                 dbg("SIM REMOVED");
2641                 break;
2642
2643         case 12:
2644                 dbg("SIM SMS Ready");
2645                 notify_sms_state(plugin, o, SMS_STATE_READY);
2646                 goto out;
2647
2648         case 99:
2649                 sim_status = SIM_STATUS_UNKNOWN;
2650                 dbg("SIM STATE UNKNOWN");
2651                 break;
2652
2653         default:
2654                 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2655                 goto out;
2656         }
2657
2658         switch (sim_status) {
2659         case SIM_STATUS_INIT_COMPLETED:
2660                 dbg("[SIM] SIM INIT COMPLETED");
2661                 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2662                         _get_sim_type(o);
2663                         goto out;
2664                 }
2665
2666                 break;
2667
2668         case SIM_STATUS_CARD_REMOVED:
2669                 dbg("[SIM] SIM CARD REMOVED");
2670                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2671                 break;
2672
2673         case SIM_STATUS_CARD_NOT_PRESENT:
2674                 dbg("[SIM] SIM CARD NOT PRESENT");
2675                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2676                 break;
2677
2678         case SIM_STATUS_CARD_ERROR:
2679                 dbg("[SIM] SIM CARD ERROR");
2680                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2681                 break;
2682
2683         default:
2684                 dbg("SIM Status: [0x%02x]", sim_status);
2685                 break;
2686         }
2687
2688         _sim_status_update(o, sim_status);
2689
2690 out:
2691         tcore_at_tok_free(tokens);
2692
2693         dbg("Exit");
2694         return TRUE;
2695 }
2696
2697 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2698 {
2699         const TcoreATResponse *resp = data;
2700         CoreObject *o = NULL;
2701
2702         dbg("Entry");
2703
2704         o = tcore_pending_ref_core_object(p);
2705
2706         if (resp->success > 0) {
2707                 dbg("RESPONSE OK");
2708                 if (resp->lines)
2709                         on_event_pin_status(o, resp->lines, NULL);
2710         } else {
2711                 dbg("RESPONSE NOK");
2712         }
2713
2714         dbg("Exit");
2715 }
2716
2717 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2718                                                                                           unsigned int data_len, void *data, void *user_data)
2719 {
2720         TcorePlugin *plugin = tcore_object_ref_plugin(source);
2721         CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2722
2723         if (o == NULL)
2724                 return TCORE_HOOK_RETURN_CONTINUE;
2725
2726         dbg("Get SIM status");
2727
2728         sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2729
2730         return TCORE_HOOK_RETURN_CONTINUE;
2731 }
2732
2733 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2734 {
2735         const TcoreATResponse *resp = data;
2736         UserRequest *ur = NULL;
2737         CoreObject *co_sim = NULL;
2738         struct imc_sim_property *sp = NULL;
2739         GSList *tokens = NULL;
2740         struct tresp_sim_verify_pins res;
2741         const char *line;
2742         int err;
2743
2744         dbg("Entry");
2745
2746         co_sim = tcore_pending_ref_core_object(p);
2747         sp = tcore_sim_ref_userdata(co_sim);
2748         if (!sp) {
2749                 err("user data is null");
2750                 return;
2751         }
2752
2753         ur = tcore_pending_ref_user_request(p);
2754
2755         memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2756
2757         if (resp->success > 0) {
2758                 dbg("RESPONSE OK");
2759                 res.result = SIM_PIN_OPERATION_SUCCESS;
2760
2761                 /* Get PIN facility */
2762                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2763                 if ((res.pin_type == SIM_PTYPE_PIN1)
2764                                 || (res.pin_type == SIM_PTYPE_SIM)) {
2765                         if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2766                                 /* Update SIM Status */
2767                                 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2768                         }
2769                 }
2770
2771                 /* Send Response */
2772                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2773                                         sizeof(struct tresp_sim_verify_pins), &res);
2774         } else {
2775                 dbg("RESPONSE NOK");
2776                 line = (const char *)resp->final_response;
2777                 tokens = tcore_at_tok_new(line);
2778                 if (g_slist_length(tokens) < 1) {
2779                         dbg("Unkown Error OR String corrupted");
2780                         res.result = TCORE_RETURN_3GPP_ERROR;
2781
2782                         /* Send Response */
2783                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2784                                                                 sizeof(struct tresp_sim_verify_pins), &res);
2785                 } else {
2786                         err = atoi(g_slist_nth_data(tokens, 0));
2787                         dbg("Error: [%d]", err);
2788
2789                         ur = tcore_user_request_ref(ur);
2790
2791                         /* Get retry count */
2792                         _get_retry_count(co_sim, ur);
2793                 }
2794
2795                 /* Free tokens */
2796                 tcore_at_tok_free(tokens);
2797         }
2798
2799         dbg("Exit");
2800 }
2801
2802 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2803 {
2804         const TcoreATResponse *resp = data;
2805         UserRequest *ur = NULL;
2806         CoreObject *co_sim = NULL;
2807         struct imc_sim_property *sp = NULL;
2808         GSList *tokens = NULL;
2809         struct tresp_sim_verify_puks res;
2810         const char *line;
2811         int err;
2812
2813         dbg("Entry");
2814
2815         co_sim = tcore_pending_ref_core_object(p);
2816         sp = tcore_sim_ref_userdata(co_sim);
2817         if (!sp) {
2818                 err("user data is null");
2819                 return;
2820         }
2821
2822         ur = tcore_pending_ref_user_request(p);
2823
2824         memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2825
2826         if (resp->success > 0) {
2827                 dbg("RESPONSE OK");
2828                 res.result = SIM_PIN_OPERATION_SUCCESS;
2829                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2830
2831                 /* Send Response */
2832                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2833                                                         sizeof(struct tresp_sim_verify_pins), &res);
2834         } else {
2835                 dbg("RESPONSE NOK");
2836                 line = (const char *)resp->final_response;
2837                 tokens = tcore_at_tok_new(line);
2838
2839                 if (g_slist_length(tokens) < 1) {
2840                         dbg("Unkown Error OR String corrupted");
2841                         res.result = TCORE_RETURN_3GPP_ERROR;
2842
2843                         /* Send Response */
2844                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2845                                                         sizeof(struct tresp_sim_verify_pins), &res);
2846                 } else {
2847                         err = atoi(g_slist_nth_data(tokens, 0));
2848                         dbg("Error: [%d]", err);
2849                         ur = tcore_user_request_ref(ur);
2850                         _get_retry_count(co_sim, ur);
2851                 }
2852                 tcore_at_tok_free(tokens);
2853         }
2854         dbg("Exit");
2855 }
2856
2857 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2858 {
2859         const TcoreATResponse *resp = data;
2860         UserRequest *ur = NULL;
2861         CoreObject *co_sim = NULL;
2862         struct imc_sim_property *sp = NULL;
2863         GSList *tokens = NULL;
2864         struct tresp_sim_change_pins res;
2865         const char *line;
2866         int err;
2867
2868         dbg("Entry");
2869
2870         co_sim = tcore_pending_ref_core_object(p);
2871         sp = tcore_sim_ref_userdata(co_sim);
2872         if (!sp) {
2873                 err("user data is null");
2874                 return;
2875         }
2876
2877         ur = tcore_pending_ref_user_request(p);
2878
2879         memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2880
2881         if (resp->success > 0) {
2882                 dbg("RESPONSE OK");
2883                 res.result = SIM_PIN_OPERATION_SUCCESS;
2884                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2885
2886                 /* Send Response */
2887                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2888                                                         sizeof(struct tresp_sim_change_pins), &res);
2889         } else {
2890                 dbg("RESPONSE NOK");
2891                 line = (const char *)resp->final_response;
2892                 tokens = tcore_at_tok_new(line);
2893
2894                 if (g_slist_length(tokens) < 1) {
2895                         dbg("Unkown Error OR String corrupted");
2896                         res.result = TCORE_RETURN_3GPP_ERROR;
2897
2898                         /* Send Response */
2899                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2900                                                         sizeof(struct tresp_sim_change_pins), &res);
2901                 } else {
2902                         err = atoi(g_slist_nth_data(tokens, 0));
2903                         dbg("Error: [%d]", err);
2904                         ur = tcore_user_request_ref(ur);
2905                         _get_retry_count(co_sim, ur);
2906                 }
2907
2908                 /* Free tokens */
2909                 tcore_at_tok_free(tokens);
2910         }
2911         dbg("Exit");
2912 }
2913
2914 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2915 {
2916         const TcoreATResponse *resp = data;
2917         UserRequest *ur = NULL;
2918         GSList *tokens = NULL;
2919         struct tresp_sim_get_facility_status *res = user_data;
2920         const char *line;
2921
2922         dbg("Entry");
2923
2924         ur = tcore_pending_ref_user_request(p);
2925
2926         res->result = SIM_PIN_OPERATION_SUCCESS;
2927
2928         if (resp->success > 0) {
2929                 dbg("RESPONSE OK");
2930                 if (resp->lines) {
2931                         line = (const char *)resp->lines->data;
2932                         tokens = tcore_at_tok_new(line);
2933                         if (g_slist_length(tokens) != 1) {
2934                                 msg("Invalid message");
2935                                 tcore_at_tok_free(tokens);
2936                                 return;
2937                         }
2938                 }
2939                 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2940         } else {
2941                 dbg("RESPONSE NOK");
2942                 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2943         }
2944
2945         /* Send Response */
2946         if (ur) {
2947                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2948                                                 sizeof(struct tresp_sim_get_facility_status), res);
2949         }
2950         tcore_at_tok_free(tokens);
2951         g_free(res);
2952         dbg("Exit");
2953 }
2954
2955 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2956 {
2957         const TcoreATResponse *resp = data;
2958         UserRequest *ur = NULL;
2959         CoreObject *co_sim = NULL;
2960         struct imc_sim_property *sp = NULL;
2961         GSList *tokens = NULL;
2962         struct tresp_sim_enable_facility res;
2963         const char *line;
2964
2965         dbg("Entry");
2966
2967         co_sim = tcore_pending_ref_core_object(p);
2968         sp = tcore_sim_ref_userdata(co_sim);
2969         if (!sp) {
2970                 err("user data is null");
2971                 return;
2972         }
2973
2974         ur = tcore_pending_ref_user_request(p);
2975
2976         memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2977
2978         res.result = SIM_CARD_ERROR;
2979         res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2980
2981         if (resp->success > 0) {
2982                 dbg("RESPONSE OK");
2983                 if (resp->lines) {
2984                         line = (const char *)resp->lines->data;
2985                         tokens = tcore_at_tok_new(line);
2986                         if (g_slist_length(tokens) != 1) {
2987                                 msg("Invalid message");
2988
2989                                 /* Send Response */
2990                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2991                                                                          sizeof(struct tresp_sim_enable_facility), &res);
2992                                 tcore_at_tok_free(tokens);
2993                                 return;
2994                         }
2995                 }
2996
2997                 res.result = SIM_PIN_OPERATION_SUCCESS;
2998
2999                 /* Send Response */
3000                 if (ur) {
3001                         tcore_user_request_send_response(ur, _find_resp_command(ur),
3002                                                                  sizeof(struct tresp_sim_enable_facility), &res);
3003                 }
3004
3005                 /* Free tokens */
3006                 tcore_at_tok_free(tokens);
3007         } else {
3008                 dbg("RESPONSE NOK");
3009                 ur = tcore_user_request_ref(ur);
3010                 _get_retry_count(co_sim, ur);
3011         }
3012         dbg("Exit");
3013 }
3014
3015 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
3016 {
3017         const TcoreATResponse *resp = data;
3018         UserRequest *ur = NULL;
3019         CoreObject *co_sim = NULL;
3020         struct imc_sim_property *sp = NULL;
3021         GSList *tokens = NULL;
3022         struct tresp_sim_disable_facility res;
3023         const char *line;
3024
3025         dbg("Entry");
3026
3027         co_sim = tcore_pending_ref_core_object(p);
3028         sp = tcore_sim_ref_userdata(co_sim);
3029         if (!sp) {
3030                 err("user data is null");
3031                 return;
3032         }
3033
3034         ur = tcore_pending_ref_user_request(p);
3035
3036         memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
3037
3038         res.result = SIM_CARD_ERROR;
3039         res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3040
3041         if (resp->success > 0) {
3042                 dbg("RESPONSE OK");
3043                 if (resp->lines) {
3044                         line = (const char *)resp->lines->data;
3045                         tokens = tcore_at_tok_new(line);
3046                         if (g_slist_length(tokens) != 1) {
3047                                 msg("Invalid message");
3048
3049                                 /* Send Response */
3050                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3051                                                                                 sizeof(struct tresp_sim_disable_facility), &res);
3052                                 tcore_at_tok_free(tokens);
3053                                 return;
3054                         }
3055                 }
3056
3057                 res.result = SIM_PIN_OPERATION_SUCCESS;
3058                 /* Send Response */
3059                 if (ur)
3060                         tcore_user_request_send_response(ur, _find_resp_command(ur),
3061                                                                         sizeof(struct tresp_sim_disable_facility), &res);
3062
3063                 /* Free tokens */
3064                 tcore_at_tok_free(tokens);
3065         } else {
3066                 dbg("RESPONSE NOK");
3067                 ur = tcore_user_request_ref(ur);
3068                 _get_retry_count(co_sim, ur);
3069         }
3070         dbg("Exit");
3071 }
3072
3073 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
3074 {
3075         const TcoreATResponse *response = (TcoreATResponse *)data;
3076         UserRequest *ur = NULL;
3077         GSList *tokens = NULL;
3078         struct treq_sim_get_lock_info *req_data = NULL;
3079         struct tresp_sim_get_lock_info resp;
3080         const char *line;
3081         int pin1_attempts_left = 0;
3082         int puk1_attempts_left = 0;
3083         int pin2_attempts_left = 0;
3084         int puk2_attempts_left = 0;
3085         int length_tokens = 0;
3086
3087         dbg("Entry");
3088
3089         memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3090
3091         ur = tcore_pending_ref_user_request(p);
3092
3093         if (!ur || !response) {
3094                 err("NULL data : ur[%p], response[%p]", ur, response);
3095                 resp.result = SIM_CARD_ERROR;
3096                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3097                                                 sizeof(struct tresp_sim_get_lock_info), &resp);
3098                 return;
3099         }
3100
3101         req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3102
3103         resp.result = SIM_PIN_OPERATION_SUCCESS;
3104         resp.type = req_data->type;
3105
3106         if (response->success > 0) {
3107                 dbg("RESPONSE OK");
3108                 if (response->lines) {
3109                         line = (const char *)response->lines->data;
3110                         tokens = tcore_at_tok_new(line);
3111                         length_tokens = g_slist_length(tokens);
3112                         dbg("No of Tokens [%d]", length_tokens);
3113                         switch (length_tokens) {
3114                         case 4:
3115                                 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3116                         case 3:
3117                                 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3118                         case 2:
3119                                 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3120                         case 1:
3121                                 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3122                         break;
3123
3124                         default:
3125                                 err("Invalid response");
3126                                 tcore_at_tok_free(tokens);
3127                                 resp.result = SIM_CARD_ERROR;
3128                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3129                                                                 sizeof(struct tresp_sim_get_lock_info), &resp);
3130                                 return;
3131                         }
3132
3133
3134                         dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3135                                                 pin1_attempts_left, puk1_attempts_left);
3136                         dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3137                                                 pin2_attempts_left, puk2_attempts_left);
3138
3139                         resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3140
3141                         switch (resp.type) {
3142                         case SIM_FACILITY_SC:
3143                                 resp.retry_count = pin1_attempts_left;
3144                                 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3145                                         resp.lock_status = SIM_LOCK_STATUS_PIN;
3146                                 } else if (pin1_attempts_left == 0) {
3147                                         if (puk1_attempts_left) {
3148                                                 resp.lock_status = SIM_LOCK_STATUS_PUK;
3149                                                 resp.retry_count = puk1_attempts_left;
3150                                         } else {
3151                                                 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3152                                         }
3153                                 }
3154                         break;
3155
3156                         case SIM_FACILITY_FD:
3157                                 resp.retry_count = pin2_attempts_left;
3158                                 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3159                                         resp.lock_status = SIM_LOCK_STATUS_PIN2;
3160                                 } else if (pin2_attempts_left == 0) {
3161                                         if (puk2_attempts_left) {
3162                                                 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3163                                                 resp.retry_count = puk2_attempts_left;
3164                                         } else {
3165                                                 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3166                                         }
3167                                 }
3168                         break;
3169
3170                         default:
3171                                 err("Unhandled facility type : [%d]", resp.type);
3172                         break;
3173                         }
3174                         dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3175                         tcore_at_tok_free(tokens);
3176                 }
3177         } else {
3178                 err("RESPONSE NOK");
3179                 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3180         }
3181
3182         /* Send Response */
3183         tcore_user_request_send_response(ur, _find_resp_command(ur),
3184                                         sizeof(struct tresp_sim_get_lock_info), &resp);
3185 }
3186
3187 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
3188 {
3189         UserRequest *ur = NULL;
3190         GSList *tokens = NULL;
3191         const char *line = NULL;
3192         const TcoreATResponse *response = (TcoreATResponse *)data;
3193         CoreObject *co_sim = NULL;
3194         struct imc_sim_property *meta_info = NULL;
3195         struct tresp_sim_set_data resp;
3196         int sw1 = 0;
3197         int sw2 = 0;
3198         gboolean cphs_sim = FALSE;
3199         enum tcore_request_command command;
3200         dbg("Entry");
3201
3202         memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3203
3204         ur = tcore_pending_ref_user_request(p);
3205         command = tcore_user_request_get_command(ur);
3206         co_sim = tcore_pending_ref_core_object(p);
3207         cphs_sim = tcore_sim_get_cphs_status(co_sim);
3208         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3209
3210         if (!ur || !co_sim || !meta_info || !response) {
3211                 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3212                 resp.result = SIM_CARD_ERROR;
3213                 goto EXIT;
3214         } else {
3215                 if (response->success > 0) {
3216                         dbg("RESPONSE OK");
3217                         if (response->lines) {
3218                                 line = (const char *)response->lines->data;
3219                                 tokens = tcore_at_tok_new(line);
3220                                 if (g_slist_length(tokens) < 2) {
3221                                         err("Invalid response");
3222                                         resp.result = SIM_CARD_ERROR;
3223                                 } else {
3224                                         sw1 = atoi(g_slist_nth_data(tokens, 0));
3225                                         sw2 = atoi(g_slist_nth_data(tokens, 1));
3226
3227                                         if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
3228                                                 resp.result = SIM_ACCESS_SUCCESS;
3229                                         else
3230                                                 resp.result = _decode_status_word(sw1, sw2);
3231                                 }
3232                                 tcore_at_tok_free(tokens);
3233                         }
3234                 } else {
3235                         err("RESPONSE NOK");
3236                         resp.result = SIM_ACCESS_FAILED;
3237                 }
3238         }
3239
3240         if (cphs_sim == FALSE) {
3241                 switch (command) {
3242                 case TREQ_SIM_SET_MAILBOX:
3243                         if (meta_info->file_id == SIM_EF_USIM_MBI) {
3244                                 if (resp.result == SIM_ACCESS_SUCCESS) {
3245                                         ur = tcore_user_request_ref(ur);
3246                                         _get_file_info(co_sim, ur, SIM_EF_MBDN);
3247                                 } else {
3248                                         dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3249                                         memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3250                                         ur = tcore_user_request_ref(ur);
3251                                         _get_file_info(co_sim, ur, SIM_EF_MBDN);
3252                                 }
3253                                 return;
3254                         }
3255                         break;
3256                 default:
3257                         break;
3258                 }
3259         } else {
3260                 switch (command) {
3261                 case TREQ_SIM_SET_MAILBOX:
3262                         if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3263                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3264                                 return;
3265                         }
3266                 break;
3267
3268                 case TREQ_SIM_SET_CALLFORWARDING:
3269                         if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3270                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3271                                 return;
3272                         }
3273                 break;
3274
3275                 case TREQ_SIM_SET_MESSAGEWAITING:
3276                         if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3277                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3278                                 return;
3279                         }
3280                 break;
3281
3282                 default:
3283                 break;
3284                 }
3285         }
3286
3287 EXIT:
3288         /* Send Response */
3289         tcore_user_request_send_response(ur, _find_resp_command(ur),
3290                                         sizeof(struct tresp_sim_set_data), &resp);
3291 }
3292
3293 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3294 {
3295         const TcoreATResponse *resp = data;
3296         UserRequest *ur = NULL;
3297         struct tresp_sim_transmit_apdu res;
3298         const char *line;
3299
3300         dbg("Entry");
3301
3302         ur = tcore_pending_ref_user_request(p);
3303
3304         memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3305         res.result = SIM_ACCESS_FAILED;
3306
3307         if (resp->success > 0) {
3308                 dbg("RESPONSE OK");
3309                 if (resp->lines) {
3310                         GSList *tokens = NULL;
3311                         char *tmp = NULL;
3312                         char *decoded_data = NULL;
3313                         line = (const char *)resp->lines->data;
3314                         tokens = tcore_at_tok_new(line);
3315                         if (g_slist_length(tokens) != 2) {
3316                                 msg("Invalid message");
3317                                 tcore_at_tok_free(tokens);
3318                                 res.result = SIM_CARD_ERROR;
3319                                 goto OUT;
3320                         }
3321
3322                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3323                         if (tmp) {
3324                                 decoded_data = util_hexStringToBytes(tmp);
3325                                 if (decoded_data) {
3326                                         res.apdu_resp_length = strlen(tmp) / 2;
3327                                         res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3328                                         if (res.apdu_resp == NULL) {
3329                                                 err("Memory allocation failed!!");
3330                                                 tcore_at_tok_free(tokens);
3331                                                 g_free(tmp);
3332                                                 g_free(decoded_data);
3333                                                 goto OUT;
3334                                         }
3335                                         memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3336                                         g_free(tmp);
3337                                         g_free(decoded_data);
3338                                         res.result = SIM_ACCESS_SUCCESS;
3339                                         tcore_at_tok_free(tokens);
3340                                 } else {
3341                                         err("util_hexStringToBytes Failed!!");
3342                                         g_free(tmp);
3343                                 }
3344                         }
3345                 }
3346         } else {
3347                 dbg("RESPONSE NOK");
3348         }
3349
3350 OUT:
3351         /* Send Response */
3352         if (ur) {
3353                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3354                                                         sizeof(struct tresp_sim_transmit_apdu), &res);
3355         }
3356         dbg("Exit");
3357 }
3358
3359 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3360 {
3361         const TcoreATResponse *resp = data;
3362         UserRequest *ur = NULL;
3363         GSList *tokens = NULL;
3364         struct tresp_sim_get_atr res;
3365         const char *line;
3366
3367         dbg("Entry");
3368
3369         memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3370         ur = tcore_pending_ref_user_request(p);
3371
3372         res.result = SIM_ACCESS_FAILED;
3373         if (resp->success > 0) {
3374                 dbg("RESPONSE OK");
3375                 if (resp->lines) {
3376                         char *tmp = NULL;
3377                         char *decoded_data = NULL;
3378                         line = (const char *)resp->lines->data;
3379                         tokens = tcore_at_tok_new(line);
3380                         if (g_slist_length(tokens) < 1) {
3381                                 msg("Invalid message");
3382                                 goto OUT;
3383                         }
3384
3385                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3386                         if (tmp) {
3387                                 decoded_data = util_hexStringToBytes(tmp);
3388                                 if (!decoded_data) {
3389                                         err("util_hexStringToBytes Failed!!");
3390                                         goto OUT;
3391                                 }
3392
3393                                 res.atr_length = strlen(tmp) / 2;
3394                                 memcpy((char *)res.atr, decoded_data, res.atr_length);
3395                                 g_free(tmp);
3396                                 g_free(decoded_data);
3397                                 res.result = SIM_ACCESS_SUCCESS;
3398                         }
3399                 }
3400         } else {
3401                 dbg("RESPONSE NOK");
3402         }
3403
3404 OUT:
3405         /* Send Response */
3406         if (ur) {
3407                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3408                                                         sizeof(struct tresp_sim_get_atr), &res);
3409         }
3410         tcore_at_tok_free(tokens);
3411         dbg("Exit");
3412 }
3413
3414 static void on_response_req_authentication(TcorePending *p, int data_len,
3415                                         const void *data, void *user_data)
3416 {
3417         const TcoreATResponse *at_resp = data;
3418         GSList *tokens = NULL;
3419         struct tresp_sim_req_authentication resp_auth;
3420         const struct treq_sim_req_authentication *req_data;
3421         UserRequest *ur = tcore_pending_ref_user_request(p);
3422
3423         dbg("Entry");
3424
3425         memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3426
3427         if (at_resp == NULL) {
3428                 err("at_resp is NULL");
3429                 resp_auth.result = SIM_ACCESS_FAILED;
3430                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3431                 goto out;
3432         }
3433
3434         req_data = tcore_user_request_ref_data(ur, NULL);
3435         if (req_data == NULL) {
3436                 err("req_data is NULL");
3437                 resp_auth.result = SIM_ACCESS_FAILED;
3438                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3439                 goto out;
3440         }
3441         resp_auth.auth_type = req_data->auth_type;
3442
3443         if (at_resp->success == TRUE) {
3444                 const char *line;
3445                 int status;
3446
3447                 dbg("RESPONSE OK");
3448                 if (at_resp->lines != NULL) {
3449                         line = at_resp->lines->data;
3450                         dbg("Received data: [%s]", line);
3451                 } else {
3452                         err("at_resp->lines is NULL");
3453                         resp_auth.result = SIM_ACCESS_FAILED;
3454                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3455                         goto out;
3456                 }
3457
3458                 tokens = tcore_at_tok_new(line);
3459                 if (tokens == NULL) {
3460                         err("tokens is NULL");
3461                         resp_auth.result = SIM_ACCESS_FAILED;
3462                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3463                         goto out;
3464                 }
3465
3466                 status = atoi(g_slist_nth_data(tokens, 0));
3467                 switch (status) {
3468                 case 0:
3469                         dbg("Authentications successful");
3470                         resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3471                         break;
3472                 case 1:
3473                         err("Synchronize fail");
3474                         resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3475                         goto out;
3476                 case 2:
3477                         err("MAC wrong");
3478                         resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3479                         goto out;
3480                 case 3:
3481                         err("Does not support security context");
3482                         resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3483                         goto out;
3484                 default:
3485                         err("Other failure");
3486                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3487                         goto out;
3488                 }
3489
3490                 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3491                         char *kc, *sres;
3492                         char *convert_kc, *convert_sres;
3493
3494                         kc = g_slist_nth_data(tokens, 1);
3495                         if (kc != NULL) {
3496                                 kc = tcore_at_tok_extract(kc);
3497                                 dbg("Kc: [%s]", kc);
3498                                 convert_kc = util_hexStringToBytes(kc);
3499                                 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3500                                         resp_auth.authentication_key_length = strlen(convert_kc);
3501                                         memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3502                                 } else {
3503                                         err("Invalid Kc");
3504                                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3505                                 }
3506                                 g_free(kc);
3507                                 g_free(convert_kc);
3508                         }
3509
3510                         sres = g_slist_nth_data(tokens, 2);
3511                         if (sres != NULL) {
3512                                 sres = tcore_at_tok_extract(sres);
3513                                 dbg("SRES: [%s]", sres);
3514                                 convert_sres = util_hexStringToBytes(sres);
3515                                 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3516                                         resp_auth.resp_length = strlen(convert_sres);
3517                                         memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3518                                 } else {
3519                                         err("Invalid SRES");
3520                                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3521                                 }
3522                                 g_free(sres);
3523                                 g_free(convert_sres);
3524                         }
3525                 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3526                                 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3527                         /* TODO */
3528                 }
3529         } else {
3530                 err("RESPONSE NOK");
3531                 resp_auth.result = SIM_ACCESS_FAILED;
3532                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3533         }
3534
3535 out:
3536         tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3537                         sizeof(struct tresp_sim_req_authentication), &resp_auth);
3538
3539         tcore_at_tok_free(tokens);
3540 }
3541
3542 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3543 {
3544         TcoreHal *hal = NULL;
3545         TcoreATRequest *req = NULL;
3546         TcorePending *pending = NULL;
3547         char *cmd_str = NULL;
3548         const struct treq_sim_verify_pins *req_data = NULL;
3549         struct imc_sim_property *sp = NULL;
3550         TReturn ret = TCORE_RETURN_FAILURE;
3551
3552         dbg("Entry");
3553
3554         if ((o == NULL) || (ur == NULL))
3555                 return TCORE_RETURN_EINVAL;
3556
3557         hal = tcore_object_get_hal(o);
3558         if (FALSE == tcore_hal_get_power_state(hal)) {
3559                 err("CP NOT READY");
3560                 return TCORE_RETURN_ENOSYS;
3561         }
3562
3563         sp = tcore_sim_ref_userdata(o);
3564         if (!sp) {
3565                 err("user data is null");
3566                 return TCORE_RETURN_FAILURE;
3567         }
3568
3569         pending = tcore_pending_new(o, 0);
3570         if (!pending) {
3571                 err("Pending is NULL");
3572                 return TCORE_RETURN_FAILURE;
3573         }
3574
3575         req_data = tcore_user_request_ref_data(ur, NULL);
3576
3577         if (req_data->pin_type == SIM_PTYPE_PIN1) {
3578                 sp->current_sec_op = SEC_PIN1_VERIFY;
3579                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3580         } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3581                 sp->current_sec_op = SEC_PIN2_VERIFY;
3582                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3583         } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3584                 sp->current_sec_op = SEC_SIM_VERIFY;
3585                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3586         } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3587                 sp->current_sec_op = SEC_ADM_VERIFY;
3588                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3589         } else {
3590                 tcore_pending_free(pending);
3591                 return TCORE_RETURN_EINVAL;
3592         }
3593
3594         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3595         if (req == NULL) {
3596                 tcore_pending_free(pending);
3597                 g_free(cmd_str);
3598                 return TCORE_RETURN_FAILURE;
3599         }
3600         g_free(cmd_str);
3601
3602         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3603                                 req->cmd, req->prefix, strlen(req->cmd));
3604
3605         tcore_pending_set_request_data(pending, 0, req);
3606         tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3607         tcore_pending_link_user_request(pending, ur);
3608         ret = tcore_hal_send_request(hal, pending);
3609
3610         dbg("Exit");
3611         return ret;
3612 }
3613
3614 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3615 {
3616         TcoreHal *hal = NULL;
3617         TcoreATRequest *req = NULL;
3618         TcorePending *pending = NULL;
3619         char *cmd_str = NULL;
3620         const struct treq_sim_verify_puks *req_data;
3621         struct imc_sim_property *sp = NULL;
3622         TReturn ret = TCORE_RETURN_FAILURE;
3623
3624         dbg("Entry");
3625
3626         if ((o == NULL) || (ur == NULL))
3627                 return TCORE_RETURN_EINVAL;
3628
3629         hal = tcore_object_get_hal(o);
3630         if (FALSE == tcore_hal_get_power_state(hal)) {
3631                 err("CP NOT READY");
3632                 return TCORE_RETURN_ENOSYS;
3633         }
3634
3635         sp = tcore_sim_ref_userdata(o);
3636         if (!sp) {
3637                 err("user data is null");
3638                 return TCORE_RETURN_FAILURE;
3639         }
3640
3641         pending = tcore_pending_new(o, 0);
3642         if (!pending) {
3643                 err("Pending is NULL");
3644                 return TCORE_RETURN_FAILURE;
3645         }
3646
3647         req_data = tcore_user_request_ref_data(ur, NULL);
3648
3649         if (req_data->puk_type == SIM_PTYPE_PUK1) {
3650                 sp->current_sec_op = SEC_PUK1_VERIFY;
3651                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3652         } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3653                 sp->current_sec_op = SEC_PUK2_VERIFY;
3654                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3655         } else {
3656                 tcore_pending_free(pending);
3657                 return TCORE_RETURN_EINVAL;
3658         }
3659
3660         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3661         if (req == NULL) {
3662                 tcore_pending_free(pending);
3663                 g_free(cmd_str);
3664                 return TCORE_RETURN_FAILURE;
3665         }
3666         g_free(cmd_str);
3667
3668         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3669                                 req->cmd, req->prefix, strlen(req->cmd));
3670
3671         tcore_pending_set_request_data(pending, 0, req);
3672         tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3673         tcore_pending_link_user_request(pending, ur);
3674         ret = tcore_hal_send_request(hal, pending);
3675
3676         dbg("Exit");
3677         return ret;
3678 }
3679
3680 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3681 {
3682         TcoreHal *hal = NULL;
3683         TcoreATRequest *req = NULL;
3684         TcorePending *pending = NULL;
3685         char *cmd_str = NULL;
3686         const struct treq_sim_change_pins *req_data;
3687         struct imc_sim_property *sp = NULL;
3688         char *pin1 = "SC";
3689         char *pin2 = "P2";
3690         TReturn ret = TCORE_RETURN_FAILURE;
3691
3692         dbg("Entry");
3693
3694         if ((o == NULL) || (ur == NULL))
3695                 return TCORE_RETURN_EINVAL;
3696
3697         hal = tcore_object_get_hal(o);
3698         if (FALSE == tcore_hal_get_power_state(hal)) {
3699                 err("CP NOT READY");
3700                 return TCORE_RETURN_ENOSYS;
3701         }
3702
3703         sp = tcore_sim_ref_userdata(o);
3704         if (!sp) {
3705                 err("user data is null");
3706                 return TCORE_RETURN_FAILURE;
3707         }
3708
3709         pending = tcore_pending_new(o, 0);
3710         if (!pending) {
3711                 err("Pending is NULL");
3712                 return TCORE_RETURN_FAILURE;
3713         }
3714
3715         req_data = tcore_user_request_ref_data(ur, NULL);
3716
3717         if (req_data->type == SIM_PTYPE_PIN1) {
3718                 sp->current_sec_op = SEC_PIN1_CHANGE;
3719                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3720         } else if (req_data->type == SIM_PTYPE_PIN2) {
3721                 sp->current_sec_op = SEC_PIN2_CHANGE;
3722                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3723         } else {
3724                 tcore_pending_free(pending);
3725                 return TCORE_RETURN_EINVAL;
3726         }
3727         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3728         if (req == NULL) {
3729                 tcore_pending_free(pending);
3730                 g_free(cmd_str);
3731                 return TCORE_RETURN_FAILURE;
3732         }
3733         g_free(cmd_str);
3734
3735         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3736                                 req->cmd, req->prefix, strlen(req->cmd));
3737
3738         tcore_pending_set_request_data(pending, 0, req);
3739         tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3740         tcore_pending_link_user_request(pending, ur);
3741         ret = tcore_hal_send_request(hal, pending);
3742
3743         dbg("Exit");
3744         return ret;
3745 }
3746
3747 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3748 {
3749         TcoreHal *hal = NULL;
3750         TcoreATRequest *req = NULL;
3751         TcorePending *pending = NULL;
3752         char *cmd_str = NULL;
3753         const struct treq_sim_get_facility_status *req_data;
3754         struct tresp_sim_get_facility_status *res;
3755         char *fac = "SC";
3756         int mode = 2;    /* 0:unlock, 1:lock, 2:query*/
3757         TReturn ret = TCORE_RETURN_FAILURE;
3758
3759         dbg("Entry");
3760
3761         if ((o == NULL) || (ur == NULL))
3762                 return TCORE_RETURN_EINVAL;
3763
3764         hal = tcore_object_get_hal(o);
3765         if (FALSE == tcore_hal_get_power_state(hal)) {
3766                 err("CP NOT READY");
3767                 return TCORE_RETURN_ENOSYS;
3768         }
3769
3770         pending = tcore_pending_new(o, 0);
3771         if (!pending) {
3772                 err("Pending is NULL");
3773                 return TCORE_RETURN_FAILURE;
3774         }
3775
3776         req_data = tcore_user_request_ref_data(ur, NULL);
3777
3778         res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3779         if (!res) {
3780                 tcore_pending_free(pending);
3781                 return TCORE_RETURN_ENOMEM;
3782         }
3783
3784         res->type = req_data->type;
3785
3786         if (req_data->type == SIM_FACILITY_PS)
3787                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3788         else if (req_data->type == SIM_FACILITY_SC)
3789                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3790         else if (req_data->type == SIM_FACILITY_FD)
3791                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3792         else if (req_data->type == SIM_FACILITY_PN)
3793                 fac = "PN";               /*Network Personalization*/
3794         else if (req_data->type == SIM_FACILITY_PU)
3795                 fac = "PU";               /*network sUbset Personalization*/
3796         else if (req_data->type == SIM_FACILITY_PP)
3797                 fac = "PP";               /*service Provider Personalization*/
3798         else if (req_data->type == SIM_FACILITY_PC)
3799                 fac = "PC";               /*Corporate Personalization*/
3800         else
3801                 return TCORE_RETURN_EINVAL;
3802
3803         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3804         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3805         if (req == NULL) {
3806                 tcore_pending_free(pending);
3807                 g_free(cmd_str);
3808                 return TCORE_RETURN_FAILURE;
3809         }
3810         g_free(cmd_str);
3811
3812         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3813                                 req->cmd, req->prefix, strlen(req->cmd));
3814
3815         tcore_pending_set_request_data(pending, 0, req);
3816         tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3817         tcore_pending_link_user_request(pending, ur);
3818         ret = tcore_hal_send_request(hal, pending);
3819
3820         dbg("Exit");
3821         return ret;
3822 }
3823
3824 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3825 {
3826         TcoreHal *hal = NULL;
3827         TcoreATRequest *req = NULL;
3828         TcorePending *pending = NULL;
3829         char *cmd_str = NULL;
3830         const struct treq_sim_enable_facility *req_data;
3831         struct imc_sim_property *sp = NULL;
3832         char *fac = "SC";
3833         int mode = 1;    /* 0:unlock, 1:lock, 2:query*/
3834         TReturn ret = TCORE_RETURN_FAILURE;
3835
3836         dbg("Entry");
3837
3838         if ((o == NULL) || (ur == NULL))
3839                 return TCORE_RETURN_EINVAL;
3840
3841         hal = tcore_object_get_hal(o);
3842         if (FALSE == tcore_hal_get_power_state(hal)) {
3843                 err("CP NOT READY");
3844                 return TCORE_RETURN_ENOSYS;
3845         }
3846
3847         sp = tcore_sim_ref_userdata(o);
3848         if (!sp) {
3849                 err("user data is null");
3850                 return TCORE_RETURN_FAILURE;
3851         }
3852
3853         pending = tcore_pending_new(o, 0);
3854         if (!pending) {
3855                 err("Pending is NULL");
3856                 return TCORE_RETURN_FAILURE;
3857         }
3858
3859         req_data = tcore_user_request_ref_data(ur, NULL);
3860
3861         if (req_data->type == SIM_FACILITY_PS) {
3862                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3863                 sp->current_sec_op = SEC_SIM_ENABLE;
3864         } else if (req_data->type == SIM_FACILITY_SC) {
3865                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3866                 sp->current_sec_op = SEC_PIN1_ENABLE;
3867         } else if (req_data->type == SIM_FACILITY_FD) {
3868                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3869                 sp->current_sec_op = SEC_FDN_ENABLE;
3870         } else if (req_data->type == SIM_FACILITY_PN) {
3871                 fac = "PN";               /*Network Personalization*/
3872                 sp->current_sec_op = SEC_NET_ENABLE;
3873         } else if (req_data->type == SIM_FACILITY_PU) {
3874                 fac = "PU";               /*network sUbset Personalization*/
3875                 sp->current_sec_op = SEC_NS_ENABLE;
3876         } else if (req_data->type == SIM_FACILITY_PP) {
3877                 fac = "PP";               /*service Provider Personalization*/
3878                 sp->current_sec_op = SEC_SP_ENABLE;
3879         } else if (req_data->type == SIM_FACILITY_PC) {
3880                 fac = "PC";               /*Corporate Personalization*/
3881                 sp->current_sec_op = SEC_CP_ENABLE;
3882         } else {
3883                 return TCORE_RETURN_EINVAL;
3884         }
3885         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3886         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3887         if (req == NULL) {
3888                 tcore_pending_free(pending);
3889                 g_free(cmd_str);
3890                 return TCORE_RETURN_FAILURE;
3891         }
3892         g_free(cmd_str);
3893
3894         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3895                                 req->cmd, req->prefix, strlen(req->cmd));
3896
3897         tcore_pending_set_request_data(pending, 0, req);
3898         tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3899         tcore_pending_link_user_request(pending, ur);
3900         ret = tcore_hal_send_request(hal, pending);
3901
3902         dbg("Exit");
3903         return ret;
3904 }
3905
3906 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3907 {
3908         TcoreHal *hal;
3909         TcoreATRequest *req;
3910         TcorePending *pending = NULL;
3911         char *cmd_str = NULL;
3912         const struct treq_sim_enable_facility *req_data;
3913         struct imc_sim_property *sp = NULL;
3914         char *fac = "SC";
3915         int mode = 0;    /* 0:unlock, 1:lock, 2:query*/
3916         TReturn ret = TCORE_RETURN_FAILURE;
3917
3918         dbg("Entry");
3919
3920         if ((o == NULL) || (ur == NULL))
3921                 return TCORE_RETURN_EINVAL;
3922
3923         hal = tcore_object_get_hal(o);
3924         if (FALSE == tcore_hal_get_power_state(hal)) {
3925                 err("CP NOT READY");
3926                 return TCORE_RETURN_ENOSYS;
3927         }
3928
3929         sp = tcore_sim_ref_userdata(o);
3930         if (!sp) {
3931                 err("user data is null");
3932                 return TCORE_RETURN_FAILURE;
3933         }
3934
3935         pending = tcore_pending_new(o, 0);
3936         if (!pending) {
3937                 err("Pending is NULL");
3938                 return TCORE_RETURN_FAILURE;
3939         }
3940
3941         req_data = tcore_user_request_ref_data(ur, NULL);
3942
3943         if (req_data->type == SIM_FACILITY_PS) {
3944                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3945                 sp->current_sec_op = SEC_SIM_DISABLE;
3946         } else if (req_data->type == SIM_FACILITY_SC) {
3947                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3948                 sp->current_sec_op = SEC_PIN1_DISABLE;
3949         } else if (req_data->type == SIM_FACILITY_FD) {
3950                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3951                 sp->current_sec_op = SEC_FDN_DISABLE;
3952         } else if (req_data->type == SIM_FACILITY_PN) {
3953                 fac = "PN";               /*Network Personalization*/
3954                 sp->current_sec_op = SEC_NET_DISABLE;
3955         } else if (req_data->type == SIM_FACILITY_PU) {
3956                 fac = "PU";               /*network sUbset Personalization*/
3957                 sp->current_sec_op = SEC_NS_DISABLE;
3958         } else if (req_data->type == SIM_FACILITY_PP) {
3959                 fac = "PP";               /*service Provider Personalization*/
3960                 sp->current_sec_op = SEC_SP_DISABLE;
3961         } else if (req_data->type == SIM_FACILITY_PC) {
3962                 fac = "PC";               /*Corporate Personalization*/
3963                 sp->current_sec_op = SEC_CP_DISABLE;
3964         } else {
3965                 return TCORE_RETURN_EINVAL;
3966         }
3967         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3968         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3969         if (req == NULL) {
3970                 tcore_pending_free(pending);
3971                 g_free(cmd_str);
3972                 return TCORE_RETURN_FAILURE;
3973         }
3974         g_free(cmd_str);
3975
3976         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3977                                 req->cmd, req->prefix, strlen(req->cmd));
3978
3979         tcore_pending_set_request_data(pending, 0, req);
3980         tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
3981         tcore_pending_link_user_request(pending, ur);
3982         ret = tcore_hal_send_request(hal, pending);
3983
3984         dbg("Exit");
3985         return ret;
3986 }
3987
3988 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
3989 {
3990         TcoreHal *hal = NULL;
3991         TcoreATRequest *req = NULL;
3992         TcorePending *pending = NULL;
3993
3994         dbg("Entry");
3995
3996         hal = tcore_object_get_hal(o);
3997         pending = tcore_pending_new(o, 0);
3998         if (!pending) {
3999                 err("Pending is NULL");
4000                 return TCORE_RETURN_FAILURE;
4001         }
4002
4003         if ((o == NULL) || (ur == NULL)) {
4004                 tcore_pending_free(pending);
4005                 return TCORE_RETURN_EINVAL;
4006         }
4007         req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
4008
4009         if (req == NULL) {
4010                 tcore_pending_free(pending);
4011                 return TCORE_RETURN_FAILURE;
4012         }
4013
4014         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4015                                 req->cmd, req->prefix, strlen(req->cmd));
4016
4017         tcore_pending_set_request_data(pending, 0, req);
4018         tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
4019         tcore_pending_link_user_request(pending, ur);
4020         tcore_hal_send_request(hal, pending);
4021
4022         dbg("Exit");
4023         return TCORE_RETURN_SUCCESS;
4024 }
4025
4026 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
4027 {
4028         TReturn api_ret = TCORE_RETURN_SUCCESS;
4029         enum tcore_request_command command;
4030
4031         dbg("Entry");
4032
4033         if ((o == NULL) || (ur == NULL))
4034                 return TCORE_RETURN_EINVAL;
4035
4036         command = tcore_user_request_get_command(ur);
4037         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
4038                 err("CP NOT READY");
4039                 return TCORE_RETURN_ENOSYS;
4040         }
4041
4042         switch (command) {
4043         case TREQ_SIM_GET_ECC:
4044                 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
4045                 break;
4046
4047         case TREQ_SIM_GET_LANGUAGE:
4048                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
4049                         api_ret = _get_file_info(o, ur, SIM_EF_ELP);
4050                 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
4051                         api_ret = _get_file_info(o, ur, SIM_EF_LP);
4052                 else
4053                         api_ret = TCORE_RETURN_ENOSYS;
4054                 break;
4055
4056         case TREQ_SIM_GET_ICCID:
4057                 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
4058                 break;
4059
4060         case TREQ_SIM_GET_MAILBOX:
4061                 if (tcore_sim_get_cphs_status(o))
4062                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4063                 else
4064                         api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
4065                 break;
4066
4067         case TREQ_SIM_GET_CALLFORWARDING:
4068                 if (tcore_sim_get_cphs_status(o))
4069                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4070                 else
4071                         api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
4072                 break;
4073
4074         case TREQ_SIM_GET_MESSAGEWAITING:
4075                 if (tcore_sim_get_cphs_status(o))
4076                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4077                 else
4078                         api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
4079                 break;
4080
4081         case TREQ_SIM_GET_CPHS_INFO:
4082                 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
4083                 break;
4084
4085         case TREQ_SIM_GET_MSISDN:
4086                 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
4087                 break;
4088
4089         case TREQ_SIM_GET_SPN:
4090                 dbg("enter case SPN");
4091                 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
4092                 break;
4093
4094         case TREQ_SIM_GET_SPDI:
4095                 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
4096                 break;
4097
4098         case TREQ_SIM_GET_OPL:
4099                 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
4100                 break;
4101
4102         case TREQ_SIM_GET_PNN:
4103                 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
4104                 break;
4105
4106         case TREQ_SIM_GET_CPHS_NETNAME:
4107                 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
4108                 break;
4109
4110         case TREQ_SIM_GET_OPLMNWACT:
4111                 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
4112                 break;
4113
4114         case TREQ_SIM_GET_SERVICE_TABLE:
4115                 api_ret = _get_file_info(o, ur, SIM_EF_SST);
4116                 break;
4117
4118         default:
4119                 dbg("error - not handled read treq command[%d]", command);
4120                 api_ret = TCORE_RETURN_EINVAL;
4121                 break;
4122         }
4123         dbg("Exit");
4124         return api_ret;
4125 }
4126
4127
4128 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
4129 {
4130         TReturn ret_code = TCORE_RETURN_SUCCESS;
4131         enum tcore_request_command command;
4132         enum tel_sim_file_id ef = SIM_EF_INVALID;
4133         struct imc_sim_property meta_info = {0, };
4134         enum tel_sim_type sim_type;
4135         gboolean cphs_sim = FALSE;
4136         dbg("Entry");
4137
4138         command = tcore_user_request_get_command(ur);
4139         cphs_sim = tcore_sim_get_cphs_status(co_sim);
4140         sim_type = tcore_sim_get_type(co_sim);
4141
4142         if ((co_sim == NULL) || (ur == NULL))
4143                 return TCORE_RETURN_EINVAL;
4144
4145         switch (command) {
4146         case TREQ_SIM_SET_LANGUAGE:
4147                 if (sim_type == SIM_TYPE_GSM)
4148                         ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
4149                 else if (sim_type == SIM_TYPE_USIM)
4150                         ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
4151                 else
4152                         ret_code = TCORE_RETURN_ENOSYS;
4153         break;
4154
4155         case TREQ_SIM_SET_MAILBOX:
4156                 if (cphs_sim) {
4157                         struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4158
4159                         if (!svct)
4160                                 break;
4161                         if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MBDN]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MBDN])) {
4162                                 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4163                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4164                         } else {
4165                                 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
4166                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4167                         }
4168                         free(svct);
4169                 } else {
4170                         ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4171                 }
4172         break;
4173
4174         case TREQ_SIM_SET_CALLFORWARDING:
4175         {
4176                 const struct treq_sim_set_callforwarding *cf = NULL;
4177                 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
4178
4179                 if (cf) {
4180                         if (cphs_sim) {
4181                                 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4182                                 if (!svct)
4183                                         break;
4184                                 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_CFIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_CFIS])) {
4185                                         if (cf->b_cphs == FALSE)
4186                                                 ef = SIM_EF_USIM_CFIS;
4187                                         else
4188                                                 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4189
4190                                         tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4191                                         ret_code = _get_file_info(co_sim, ur, ef);
4192                                 } else {
4193                                         dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4194                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4195                                 }
4196                                 free(svct);
4197                         } else {
4198                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4199                         }
4200                 } else {
4201                         ret_code = TCORE_RETURN_EINVAL;
4202                 }
4203         }
4204         break;
4205
4206         case TREQ_SIM_SET_MESSAGEWAITING:
4207         {
4208                 const struct treq_sim_set_messagewaiting *mw = NULL;
4209                 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4210                 if (mw) {
4211                         if (cphs_sim) {
4212                                 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4213                                 if (!svct)
4214                                         break;
4215                                 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MWIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MWIS])) {
4216                                         if (mw->b_cphs == FALSE)
4217                                                 ef = SIM_EF_USIM_MWIS;
4218                                         else
4219                                                 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4220
4221                                         tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4222                                         ret_code = _get_file_info(co_sim, ur, ef);
4223                                 } else {
4224                                         dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4225                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4226                                 }
4227                                 free(svct);
4228                                 } else {
4229                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4230                         }
4231                 } else{
4232                         ret_code = TCORE_RETURN_EINVAL;
4233                 }
4234         }
4235         break;
4236
4237         default:
4238                 err("Unhandled UPDATE command[%d]", command);
4239                 return TCORE_RETURN_EINVAL;
4240         }
4241
4242         return ret_code;
4243 }
4244
4245 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4246 {
4247         const struct treq_sim_transmit_apdu *req_data;
4248         TcoreHal *hal = NULL;
4249         char *cmd_str = NULL;
4250         char *apdu = NULL;
4251         int result = 0;
4252         TReturn ret = TCORE_RETURN_FAILURE;
4253
4254         dbg("Entry");
4255
4256         if ((o == NULL) || (ur == NULL))
4257                 return TCORE_RETURN_EINVAL;
4258
4259         hal = tcore_object_get_hal(o);
4260         if (FALSE == tcore_hal_get_power_state(hal)) {
4261                 err("CP NOT READY");
4262                 return TCORE_RETURN_ENOSYS;
4263         }
4264
4265         req_data = tcore_user_request_ref_data(ur, NULL);
4266
4267         apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4268         if (apdu == NULL) {
4269                 err("Memory allocation failed!!");
4270                 return TCORE_RETURN_ENOMEM;
4271         }
4272         result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4273         dbg("result %d", result);
4274
4275         cmd_str = g_strdup_printf("AT+CSIM=%d, \"%s\"", (unsigned int)strlen(apdu), apdu);
4276
4277         ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4278                                                                 TCORE_AT_SINGLELINE, ur,
4279                                                                 on_response_transmit_apdu, hal,
4280                                                                 NULL, NULL, 0, NULL, NULL);
4281         g_free(cmd_str);
4282         g_free(apdu);
4283
4284         dbg("Exit");
4285         return ret;
4286 }
4287
4288 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4289 {
4290         TcoreHal *hal = NULL;
4291
4292         dbg("Entry");
4293
4294         if ((o == NULL) || (ur == NULL)) {
4295                 err("Invalid parameters");
4296                 return TCORE_RETURN_EINVAL;
4297         }
4298
4299         hal = tcore_object_get_hal(o);
4300         if (FALSE == tcore_hal_get_power_state(hal)) {
4301                 err("CP NOT READY");
4302                 return TCORE_RETURN_ENOSYS;
4303         }
4304
4305         return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4306                                                                 TCORE_AT_SINGLELINE, ur,
4307                                                                 on_response_get_atr, hal,
4308                                                                 NULL, NULL, 0, NULL, NULL);
4309 }
4310
4311 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4312 {
4313         const struct treq_sim_req_authentication *req_data;
4314         char *cmd_str = NULL;
4315         enum tel_sim_type sim_type;
4316         int session_id;
4317         int context_type;
4318         TReturn ret = TCORE_RETURN_FAILURE;
4319         char *convert_rand = NULL;
4320         char *convert_autn = NULL;
4321
4322         dbg("Entry");
4323
4324         req_data = tcore_user_request_ref_data(ur, NULL);
4325         if (req_data == NULL) {
4326                 err("req_data is NULL");
4327                 return ret;
4328         }
4329
4330         convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
4331         dbg("Convert RAND hex to string: [%s]", convert_rand);
4332
4333         sim_type = tcore_sim_get_type(co);
4334         switch (sim_type) {
4335         case SIM_TYPE_GSM:
4336         case SIM_TYPE_USIM:
4337                 session_id = 0;
4338                 break;
4339         default:
4340                 err("Not supported");
4341                 ret = TCORE_RETURN_ENOSYS;
4342                 goto out;
4343         }
4344
4345         switch (req_data->auth_type) {
4346         case SIM_AUTH_TYPE_GSM:
4347                 context_type = 2;
4348                 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\"", session_id,
4349                                                 context_type, convert_rand);
4350                 break;
4351         case SIM_AUTH_TYPE_3G:
4352                 context_type = 1;
4353                 convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
4354                 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4355
4356                 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\", \"%s\"",
4357                                                 session_id, context_type,
4358                                                 convert_rand, convert_autn);
4359                 break;
4360         default:
4361                 err("Not supported");
4362                 ret = TCORE_RETURN_ENOSYS;
4363                 goto out;
4364         }
4365
4366         ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4367                         TCORE_AT_SINGLELINE, ur,
4368                         on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4369
4370 out:
4371         g_free(cmd_str);
4372         g_free(convert_rand);
4373         g_free(convert_autn);
4374
4375         return ret;
4376 }
4377
4378 /* SIM Operations */
4379 static struct tcore_sim_operations sim_ops = {
4380         .verify_pins = imc_verify_pins,
4381         .verify_puks = imc_verify_puks,
4382         .change_pins = imc_change_pins,
4383         .get_facility_status = imc_get_facility_status,
4384         .enable_facility = imc_enable_facility,
4385         .disable_facility = imc_disable_facility,
4386         .get_lock_info = imc_get_lock_info,
4387         .read_file = imc_read_file,
4388         .update_file = imc_update_file,
4389         .transmit_apdu = imc_transmit_apdu,
4390         .get_atr = imc_get_atr,
4391         .req_authentication = imc_req_authentication,
4392         .set_powerstate = NULL,
4393 };
4394
4395 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4396 {
4397         struct imc_sim_property *meta_info;
4398
4399         dbg("Entry");
4400
4401         /* Set operations */
4402         tcore_sim_set_ops(co_sim, &sim_ops, TCORE_OPS_TYPE_CP);
4403
4404         meta_info = g_try_new0(struct imc_sim_property, 1);
4405         if (meta_info == NULL)
4406                 return FALSE;
4407
4408         tcore_sim_link_userdata(co_sim, meta_info);
4409
4410         tcore_object_add_callback(co_sim, "+XLOCK:",
4411                                                         on_event_facility_lock_status, NULL);
4412         tcore_object_add_callback(co_sim, "+XSIM:",
4413                                                         on_event_pin_status, NULL);
4414
4415         tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4416                                                         TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4417
4418         dbg("Exit");
4419
4420         return TRUE;
4421 }
4422
4423 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4424 {
4425         struct imc_sim_property *meta_info;
4426
4427         meta_info = tcore_sim_ref_userdata(co_sim);
4428         g_free(meta_info);
4429
4430         dbg("Exit");
4431 }