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