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