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