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