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