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