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