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