5f2287de620f611e4b5f4d4248aa2aa6d8405715
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sim.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ankit Jogi <ankit.jogi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <tcore.h>
26 #include <hal.h>
27 #include <core_object.h>
28 #include <plugin.h>
29 #include <queue.h>
30 #include <co_sim.h>
31 #include <co_sms.h>
32 #include <storage.h>
33 #include <user_request.h>
34 #include <server.h>
35 #include <at.h>
36 #include <ckmc/ckmc-manager.h>
37
38 #include "imc_common.h"
39 #include "imc_sms.h"
40 #include "imc_sim.h"
41
42 #define ID_RESERVED_AT 0x0229
43 #define SIM_PIN_MAX_RETRY_COUNT  3
44 #define SMS_STATE_READY 1
45
46 #define SIM_STORE_KEY "telephony_sim_imsi1"
47
48 #define SWAPBYTES16(x) \
49         { \
50                 unsigned short int data = *(unsigned short int *)&(x);  \
51                 data = ((data & 0xff00) >> 8) |   \
52                            ((data & 0x00ff) << 8);        \
53                 *(unsigned short int *)&(x) = data;      \
54         }
55
56 enum imc_sim_sec_op_e {
57         SEC_PIN1_VERIFY,
58         SEC_PIN2_VERIFY,
59         SEC_PUK1_VERIFY,
60         SEC_PUK2_VERIFY,
61         SEC_SIM_VERIFY,
62         SEC_ADM_VERIFY,
63         SEC_PIN1_CHANGE,
64         SEC_PIN2_CHANGE,
65         SEC_PIN1_ENABLE,
66         SEC_PIN1_DISABLE,
67         SEC_PIN2_ENABLE,
68         SEC_PIN2_DISABLE, /* 10 */
69         SEC_SIM_ENABLE,
70         SEC_SIM_DISABLE,
71         SEC_NET_ENABLE,
72         SEC_NET_DISABLE,
73         SEC_NS_ENABLE,
74         SEC_NS_DISABLE,
75         SEC_SP_ENABLE,
76         SEC_SP_DISABLE,
77         SEC_CP_ENABLE,
78         SEC_CP_DISABLE, /* 20 */
79         SEC_FDN_ENABLE,
80         SEC_FDN_DISABLE,
81         SEC_PIN1_STATUS,
82         SEC_PIN2_STATUS,
83         SEC_FDN_STATUS,
84         SEC_NET_STATUS,
85         SEC_NS_STATUS,
86         SEC_SP_STATUS,
87         SEC_CP_STATUS,
88         SEC_SIM_STATUS,
89         SEC_SIM_UNKNOWN = 0xff
90 };
91
92 struct imc_sim_property {
93         gboolean b_valid; /**< Valid or not */
94         enum tel_sim_file_id file_id; /**< File identifier */
95         enum tcore_sim_file_type_e file_type; /**< File type and structure */
96         int rec_length; /**< Length of one record in file */
97         int rec_count; /**< Number of records in file */
98         int data_size; /**< File size */
99         int current_index; /**< current index to read */
100         enum imc_sim_sec_op_e current_sec_op; /**< current index to read */
101         int mb_count; /**< Number of MB records in file */
102         struct tel_sim_mbi_list mbi_list;
103         struct tel_sim_mailbox mb_data;
104         struct tresp_sim_read files;
105 };
106
107 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data);
108 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
109 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
110 static gboolean _get_sim_type(CoreObject *o);
111 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
112 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
113 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
114 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
115 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
116
117 static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
118 {
119         TcoreATRequest *req = NULL;
120         TcoreHal *hal = NULL;
121         TcorePending *pending = NULL;
122         TReturn ret;
123
124
125         hal = tcore_object_get_hal(co);
126         dbg("hal: %p", hal);
127
128         pending = tcore_pending_new(co, 0);
129         if (!pending) {
130                 dbg("Pending is NULL");
131                 return;
132         }
133         req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
134         if (req == NULL) {
135                 tcore_pending_free(pending);
136                 return;
137         }
138
139         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
140
141         tcore_pending_set_request_data(pending, 0, req);
142         tcore_pending_set_response_callback(pending, callback, NULL);
143         tcore_pending_link_user_request(pending, NULL); /* set user request to NULL - this is internal request */
144         ret = tcore_hal_send_request(hal, pending);
145         if (ret != TCORE_RETURN_SUCCESS) {
146                 err("error: [0x%x]", ret);
147                 tcore_pending_free(pending);
148                 tcore_at_request_free(req);
149         }
150         return;
151 }
152
153
154 static enum tcore_response_command _find_resp_command(UserRequest *ur)
155 {
156         enum tcore_request_command command;
157
158         command = tcore_user_request_get_command(ur);
159         switch (command) {
160         case TREQ_SIM_VERIFY_PINS:
161                 return TRESP_SIM_VERIFY_PINS;
162                 break;
163
164         case TREQ_SIM_VERIFY_PUKS:
165                 return TRESP_SIM_VERIFY_PUKS;
166                 break;
167
168         case TREQ_SIM_CHANGE_PINS:
169                 return TRESP_SIM_CHANGE_PINS;
170                 break;
171
172         case TREQ_SIM_GET_FACILITY_STATUS:
173                 return TRESP_SIM_GET_FACILITY_STATUS;
174                 break;
175
176         case TREQ_SIM_DISABLE_FACILITY:
177                 return TRESP_SIM_DISABLE_FACILITY;
178                 break;
179
180         case TREQ_SIM_ENABLE_FACILITY:
181                 return TRESP_SIM_ENABLE_FACILITY;
182                 break;
183
184         case TREQ_SIM_GET_LOCK_INFO:
185                 return TRESP_SIM_GET_LOCK_INFO;
186                 break;
187
188         case TREQ_SIM_TRANSMIT_APDU:
189                 return TRESP_SIM_TRANSMIT_APDU;
190                 break;
191
192         case TREQ_SIM_GET_ATR:
193                 return TRESP_SIM_GET_ATR;
194                 break;
195
196         case TREQ_SIM_GET_ECC:
197                 return TRESP_SIM_GET_ECC;
198                 break;
199
200         case TREQ_SIM_GET_LANGUAGE:
201                 return TRESP_SIM_GET_LANGUAGE;
202                 break;
203
204         case TREQ_SIM_SET_LANGUAGE:
205                 return TRESP_SIM_SET_LANGUAGE;
206                 break;
207
208         case TREQ_SIM_GET_ICCID:
209                 return TRESP_SIM_GET_ICCID;
210                 break;
211
212         case TREQ_SIM_GET_MAILBOX:
213                 return TRESP_SIM_GET_MAILBOX;
214                 break;
215
216         case TREQ_SIM_SET_MAILBOX:
217                 return TRESP_SIM_SET_MAILBOX;
218                 break;
219
220         case TREQ_SIM_GET_CALLFORWARDING:
221                 return TRESP_SIM_GET_CALLFORWARDING;
222                 break;
223
224         case TREQ_SIM_SET_CALLFORWARDING:
225                 return TRESP_SIM_SET_CALLFORWARDING;
226                 break;
227
228         case TREQ_SIM_GET_MESSAGEWAITING:
229                 return TRESP_SIM_GET_MESSAGEWAITING;
230                 break;
231
232         case TREQ_SIM_SET_MESSAGEWAITING:
233                 return TRESP_SIM_SET_MESSAGEWAITING;
234                 break;
235
236         case TREQ_SIM_GET_CPHS_INFO:
237                 return TRESP_SIM_GET_CPHS_INFO;
238                 break;
239
240         case TREQ_SIM_GET_MSISDN:
241                 return TRESP_SIM_GET_MSISDN;
242                 break;
243
244         case TREQ_SIM_GET_SPN:
245                 return TRESP_SIM_GET_SPN;
246                 break;
247
248         case TREQ_SIM_GET_SPDI:
249                 return TRESP_SIM_GET_SPDI;
250                 break;
251
252         case TREQ_SIM_GET_OPL:
253                 return TRESP_SIM_GET_OPL;
254                 break;
255
256         case TREQ_SIM_GET_PNN:
257                 return TRESP_SIM_GET_PNN;
258                 break;
259
260         case TREQ_SIM_GET_CPHS_NETNAME:
261                 return TRESP_SIM_GET_CPHS_NETNAME;
262                 break;
263
264         case TREQ_SIM_GET_OPLMNWACT:
265                 return TRESP_SIM_GET_OPLMNWACT;
266                 break;
267
268         case TREQ_SIM_REQ_AUTHENTICATION:
269                 return TRESP_SIM_REQ_AUTHENTICATION;
270                 break;
271
272         case TREQ_SIM_GET_SERVICE_TABLE:
273                 return TRESP_SIM_GET_SERVICE_TABLE;
274                 break;
275
276         default:
277                 break;
278         }
279         return TRESP_UNKNOWN;
280 }
281
282 static int _sim_get_current_pin_facility(enum imc_sim_sec_op_e op)
283 {
284         int ret_type = 0;
285
286         dbg("current sec_op[%d]", op);
287
288         switch (op) {
289         case SEC_PIN1_VERIFY:
290         case SEC_PIN1_CHANGE:
291                 ret_type = SIM_PTYPE_PIN1;
292                 break;
293
294         case SEC_PIN2_VERIFY:
295         case SEC_PIN2_CHANGE:
296                 ret_type = SIM_PTYPE_PIN2;
297                 break;
298
299         case SEC_PUK1_VERIFY:
300                 ret_type = SIM_PTYPE_PUK1;
301                 break;
302
303         case SEC_PUK2_VERIFY:
304                 ret_type = SIM_PTYPE_PUK2;
305                 break;
306
307         case SEC_SIM_VERIFY:
308                 ret_type = SIM_PTYPE_SIM;
309                 break;
310
311         case SEC_ADM_VERIFY:
312                 ret_type = SIM_PTYPE_ADM;
313                 break;
314
315         case SEC_PIN1_ENABLE:
316         case SEC_PIN1_DISABLE:
317         case SEC_PIN1_STATUS:
318                 ret_type = SIM_FACILITY_SC;
319                 break;
320
321         case SEC_SIM_ENABLE:
322         case SEC_SIM_DISABLE:
323         case SEC_SIM_STATUS:
324                 ret_type = SIM_FACILITY_PS;
325                 break;
326
327         case SEC_NET_ENABLE:
328         case SEC_NET_DISABLE:
329         case SEC_NET_STATUS:
330                 ret_type = SIM_FACILITY_PN;
331                 break;
332
333         case SEC_NS_ENABLE:
334         case SEC_NS_DISABLE:
335         case SEC_NS_STATUS:
336                 ret_type = SIM_FACILITY_PU;
337                 break;
338
339         case SEC_SP_ENABLE:
340         case SEC_SP_DISABLE:
341         case SEC_SP_STATUS:
342                 ret_type = SIM_FACILITY_PP;
343                 break;
344
345         case SEC_CP_ENABLE:
346         case SEC_CP_DISABLE:
347         case SEC_CP_STATUS:
348                 ret_type = SIM_FACILITY_PC;
349                 break;
350
351         case SEC_FDN_ENABLE:
352         case SEC_FDN_DISABLE:
353         case SEC_FDN_STATUS:
354                 ret_type = SIM_FACILITY_FD;
355                 break;
356
357         default:
358                 dbg("not handled current sec op[%d]", op);
359                 break;
360         }
361         return ret_type;
362 }
363
364 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
365 {
366         enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
367
368         if (status_word1 == 0x93 && status_word2 == 0x00) {
369                 rst = SIM_ACCESS_FAILED;
370                 /*Failed SIM request command*/
371                 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
372         } else if (status_word1 == 0x94 && status_word2 == 0x00) {
373                 rst = SIM_ACCESS_FAILED;
374                 /*Failed SIM request command*/
375                 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
376         } else if (status_word1 == 0x94 && status_word2 == 0x02) {
377                 rst = SIM_ACCESS_FAILED;
378                 /*Failed SIM request command*/
379                 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
380                         status_word1, status_word2);
381         } else if (status_word1 == 0x94 && status_word2 == 0x04) {
382                 rst = SIM_ACCESS_FILE_NOT_FOUND;
383                 /*Failed SIM request command*/
384                 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
385         } else if (status_word1 == 0x94 && status_word2 == 0x08) {
386                 rst = SIM_ACCESS_FAILED; /* MOdem not support */
387                 /*Failed SIM request command*/
388                 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
389                         status_word1, status_word2);
390         } else if (status_word1 == 0x98 && status_word2 == 0x02) {
391                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
392                 /*Failed SIM request command*/
393                 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
394         } else if (status_word1 == 0x98 && status_word2 == 0x04) {
395                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
396                 /*Failed SIM request command*/
397                 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
398                 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
399                         status_word1, status_word2);
400                 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
401                         status_word1, status_word2);
402                 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
403         } else if (status_word1 == 0x98 && status_word2 == 0x08) {
404                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
405                 /*Failed SIM request command*/
406                 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
407         } else if (status_word1 == 0x98 && status_word2 == 0x10) {
408                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
409                 /*Failed SIM request command*/
410                 dbg("error - Contradiction with invalidation status [%x][%x]",
411                         status_word1, status_word2);
412         } else if (status_word1 == 0x98 && status_word2 == 0x40) {
413                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
414                 /*Failed SIM request command*/
415                 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
416                         status_word1, status_word2);
417                 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
418                         status_word1, status_word2);
419                 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
420         } else if (status_word1 == 0x67 && status_word2 == 0x00) {
421                 rst = SIM_ACCESS_FAILED;
422                 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
423         } else if (status_word1 == 0x6B && status_word2 == 0x00) {
424                 rst = SIM_ACCESS_FAILED;
425                 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
426         } else if (status_word1 == 0x6D && status_word2 == 0x00) {
427                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
428                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
429         } else if (status_word1 == 0x6E && status_word2 == 0x00) {
430                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
431                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
432         } else if (status_word1 == 0x69 && status_word2 == 0x82) {
433                 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
434                 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
435         } else if (status_word1 == 0x6A && status_word2 == 0x87) {
436                 rst = SIM_ACCESS_FAILED;
437                 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
438         } else if (status_word1 == 0x6A && status_word2 == 0x82) {
439                 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
440                 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
441         } else if (status_word1 == 0x6A && status_word2 == 0x83) {
442                 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
443                 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
444         } else {
445                 rst = SIM_ACCESS_CARD_ERROR;
446                 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
447         }
448         return rst;
449 }
450
451 static char *_add_shared_owner_prefix(const char *name)
452 {
453         size_t alias_len = strlen(name) + strlen(ckmc_label_shared_owner) + strlen(ckmc_label_name_separator);
454         char *ckm_alias = (char *)malloc(alias_len + 1);
455         if (!ckm_alias) {
456                 err("Failed to allocate memory");
457                 return NULL;
458         }
459         memset(ckm_alias, 0, alias_len);
460         strncat(ckm_alias, ckmc_label_shared_owner, strlen(ckmc_label_shared_owner));
461         strncat(ckm_alias, ckmc_label_name_separator, strlen(ckmc_label_name_separator));
462         strncat(ckm_alias, name, strlen(name));
463
464         return ckm_alias;
465 }
466
467 static gboolean _sim_check_identity(CoreObject *co_sim, struct tel_sim_imsi *imsi)
468 {
469         gboolean is_changed = TRUE;
470         char new_imsi[16 + 1]; /* IMSI is 15 digit, but for distingushing between plmn and msin, define as 16 bytes. */
471         char *imsi_buf = NULL;
472         int ret_val = 0;
473
474         char *alias = NULL;
475         char *passwd = NULL;
476         ckmc_raw_buffer_s *ckmc_buffer;
477
478
479         dbg("Entry");
480         if (NULL == imsi) {
481                 err("imsi is NULL");
482                 return FALSE;
483         }
484
485         alias = _add_shared_owner_prefix(SIM_STORE_KEY);
486         if (alias == NULL) {
487                 err("Failed to allocate alias name.");
488                 return FALSE;
489         }
490
491         memset(new_imsi, 0x5F, 16);
492         memcpy(new_imsi, imsi->plmn, strlen(imsi->plmn));
493         memcpy(&new_imsi[6], imsi->msin, strlen(imsi->msin));
494         new_imsi[6 + strlen(imsi->msin)] = '\0';
495
496         ret_val = ckmc_get_data(alias, passwd, &ckmc_buffer);
497         imsi_buf = (char*)ckmc_buffer->data;
498         if (ret_val == CKMC_ERROR_NONE && imsi_buf != NULL) {
499                 if (strncmp(imsi_buf, new_imsi, 16) == 0)
500                         is_changed = FALSE;
501                 ckmc_buffer_free(ckmc_buffer);
502         }
503
504         if (is_changed) {
505                 ckmc_policy_s policy;
506                 ckmc_raw_buffer_s store_buffer;
507
508                 policy.password = passwd;
509                 policy.extractable = true;
510                 store_buffer.data = (unsigned char*)new_imsi;
511                 store_buffer.size = strlen(new_imsi) + 1;
512
513                 dbg("NEW SIM");
514                 /* Update file */
515                 ret_val = ckmc_save_data(alias, store_buffer, policy);
516                 if (ret_val != CKMC_ERROR_NONE)
517                         err("ckmc_save_data failed. ret_val=[%d]", ret_val);
518         }
519
520         /* Update sim identification */
521         tcore_sim_set_identification(co_sim, is_changed);
522
523         if (alias)
524                 free(alias);
525
526         return TRUE;
527 }
528
529 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
530                                         char *encoded_data, unsigned int encoded_len, int rec_index)
531 {
532         TcoreHal *hal = NULL;
533         TcoreATRequest *req = NULL;
534         TcorePending *pending = NULL;
535         char *cmd_str = NULL;
536         struct imc_sim_property *meta_info = NULL;
537         int p1 = 0;
538         int p2 = 0;
539         int p3 = 0;
540         int cmd = 0;
541
542         dbg("Entry");
543
544         hal = tcore_object_get_hal(o);
545         pending = tcore_pending_new(o, 0);
546         if (!pending) {
547                 err("Pending is NULL");
548                 return TCORE_RETURN_FAILURE;
549         }
550         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
551
552         meta_info->file_id = ef;
553         dbg("File ID: [0x%x]", meta_info->file_id);
554
555         switch (ef) {
556         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
557         case SIM_EF_ELP:
558         case SIM_EF_LP:
559         case SIM_EF_CPHS_VOICE_MSG_WAITING:
560                 p1 = 0;
561                 p2 = 0;
562                 p3 = encoded_len;
563                 cmd = 214;
564         break;
565
566         case SIM_EF_USIM_CFIS:
567         case SIM_EF_USIM_MWIS:
568         case SIM_EF_CPHS_MAILBOX_NUMBERS:
569         case SIM_EF_MBDN:
570         case SIM_EF_USIM_MBI:
571                 p1 = rec_index;
572                 p2 = 0x04;
573                 p3 = encoded_len;
574                 cmd = 220;
575         break;
576
577         default:
578                 err("Unhandled File ID[0x%04x]", ef);
579                 tcore_pending_free(pending);
580                 return TCORE_RETURN_EINVAL;
581         }
582
583         cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d, \"%s\"", cmd, ef, p1, p2, p3, encoded_data);
584
585         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
586         if (req == NULL) {
587                 tcore_pending_free(pending);
588                 g_free(cmd_str);
589                 return TCORE_RETURN_FAILURE;
590         }
591         g_free(cmd_str);
592
593         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
594                                 req->cmd, req->prefix, strlen(req->cmd));
595
596         tcore_pending_set_request_data(pending, 0, req);
597         tcore_pending_set_response_callback(pending, on_response_update_file, hal);
598         tcore_pending_link_user_request(pending, ur);
599         tcore_hal_send_request(hal, pending);
600
601         dbg("Exit");
602         return TRUE;
603 }
604
605
606 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
607 {
608         struct imc_sim_property *meta_info = NULL;
609         TReturn ret_code = TCORE_RETURN_FAILURE;
610         int encoded_len = 0;
611         enum tcore_request_command command;
612         char *tmp = NULL;
613         char *encoded_data = NULL;
614         int rec_index = -1;
615
616         dbg("Entry");
617
618         if (!o || !ur) {
619                 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
620                 return TCORE_RETURN_EINVAL;
621         }
622         command = tcore_user_request_get_command(ur);
623         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
624
625         switch (command) {
626         case TREQ_SIM_SET_LANGUAGE: {
627                 const struct treq_sim_set_language *lang = NULL;
628                 struct tel_sim_language language = {0, };
629
630                 lang = tcore_user_request_ref_data(ur, NULL);
631                 language.language_count = 1;
632                 language.language[0] = lang->language;
633                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP) {
634                         dbg("Encoding EF-LP, language[%d]", lang->language);
635                         tmp = tcore_sim_encode_lp(&encoded_len, &language);
636                 } else {
637                         dbg("Encoding EF-ELP, language[%d]", lang->language);
638                         tmp = tcore_sim_encode_li(&encoded_len, &language);
639                 }
640         }
641         break;
642
643         case TREQ_SIM_SET_CALLFORWARDING: {
644                 const struct treq_sim_set_callforwarding *cf = NULL;
645
646                 cf = tcore_user_request_ref_data(ur, NULL);
647                 if (ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
648                         if (cf->b_cphs) {
649                                 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cf->cphs_cf, meta_info->data_size);
650                         } else {
651                                 /* Convert 3GPP data to CPHS data */
652                                 struct tel_sim_cphs_cf cphs_cf;
653
654                                 dbg("Convert 3GPP data to CPHS data");
655                                 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
656                                 if (cf->cf.cfu_status & 0x01)
657                                         cphs_cf.b_line1 = TRUE;
658
659                                 if (cf->cf.cfu_status & 0x02)
660                                         cphs_cf.b_fax = TRUE;
661
662                                 if (cf->cf.cfu_status & 0x04)
663                                         cphs_cf.b_data = TRUE;
664
665                                 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cphs_cf, meta_info->data_size);
666                         }
667
668                         if (tmp) {
669                                 encoded_len = strlen(tmp);
670                         } else {
671                                 err("NULL Encoding Data[%p].. No Updating EF", tmp);
672                                 goto EXIT;
673                         }
674                 } else if (ef == SIM_EF_USIM_CFIS) {
675                         tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis *)&cf->cf);
676                         rec_index = cf->cf.rec_index;
677                 } else {
678                         err("Invalid File ID[0x%04x]", ef);
679                         goto EXIT;
680                 }
681         }
682         break;
683
684         case TREQ_SIM_SET_MESSAGEWAITING: {
685                 const struct treq_sim_set_messagewaiting *mw = NULL;
686
687                 mw = tcore_user_request_ref_data(ur, NULL);
688                 if (ef == SIM_EF_CPHS_VOICE_MSG_WAITING) {
689                         if (mw->b_cphs) {
690                                 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&mw->cphs_mw, meta_info->data_size);
691                         } else {
692                                 /* Convert 3GPP data to CPHS data */
693                                 struct tel_sim_cphs_mw cphs_mw;
694
695                                 dbg("Convert 3GPP data to CPHS data");
696                                 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
697
698                                 if (mw->mw.indicator_status & 0x01)
699                                         cphs_mw.b_voice1 = TRUE;
700
701                                 if (mw->mw.indicator_status & 0x02)
702                                         cphs_mw.b_fax = TRUE;
703
704                                 if (mw->mw.indicator_status & 0x04)
705                                         cphs_mw.b_data = TRUE;
706
707                                 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&cphs_mw, meta_info->data_size);
708                         }
709                 } else if (ef == SIM_EF_USIM_MWIS) {
710                         tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw *)&mw->mw, meta_info->rec_length);
711                         rec_index = mw->mw.rec_index;
712                         if (tmp)
713                                 encoded_len = meta_info->rec_length;
714                 } else {
715                         err("Invalid File ID[0x%04x]", ef);
716                         goto EXIT;
717                 }
718         }
719         break;
720
721         case TREQ_SIM_SET_MAILBOX: {
722                 const struct treq_sim_set_mailbox *mb = NULL;
723
724                 mb = tcore_user_request_ref_data(ur, NULL);
725                 if (ef == SIM_EF_USIM_MBI) {
726                         gboolean mbi_changed = FALSE;
727                         struct tel_sim_mbi mbi;
728
729                         do {
730                                 meta_info->current_index++;
731                                 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
732
733                                 switch (mb->mb_info.mb_type) {
734                                 case SIM_MAILBOX_VOICE:
735                                         if (mbi.voice_index != mb->mb_info.rec_index) {
736                                                 mbi_changed = TRUE;
737                                                 mbi.voice_index = mb->mb_info.rec_index;
738                                         }
739                                 break;
740
741                                 case SIM_MAILBOX_FAX:
742                                         if (mbi.fax_index != mb->mb_info.rec_index) {
743                                                 mbi_changed = TRUE;
744                                                 mbi.fax_index = mb->mb_info.rec_index;
745                                         }
746                                 break;
747
748                                 case SIM_MAILBOX_EMAIL:
749                                         if (mbi.email_index != mb->mb_info.rec_index) {
750                                                 mbi_changed = TRUE;
751                                                 mbi.email_index = mb->mb_info.rec_index;
752                                         }
753                                 break;
754
755                                 case SIM_MAILBOX_OTHER:
756                                         if (mbi.other_index != mb->mb_info.rec_index) {
757                                                 mbi_changed = TRUE;
758                                                 mbi.other_index = mb->mb_info.rec_index;
759                                         }
760                                 break;
761
762                                 case SIM_MAILBOX_VIDEO:
763                                         if (mbi.video_index != mb->mb_info.rec_index) {
764                                                 mbi_changed = TRUE;
765                                                 mbi.video_index = mb->mb_info.rec_index;
766                                         }
767                                 break;
768
769                                 case SIM_MAILBOX_DATA:
770                                 default:
771                                 break;
772                                 }
773
774                                 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
775                                                 mbi_changed, meta_info->mbi_list.profile_count,
776                                                 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
777                         } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
778
779                         if (mbi_changed == TRUE) {
780                                 rec_index = meta_info->current_index;
781                                 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
782                                 if (tmp)
783                                         encoded_len = meta_info->rec_length;
784                         }
785                 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
786                         tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
787                         rec_index = mb->mb_info.rec_index;
788                         if (tmp)
789                                 encoded_len = meta_info->rec_length;
790                 } else if (ef == SIM_EF_MBDN) {
791                         tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
792                         rec_index = mb->mb_info.rec_index;
793                         if (tmp)
794                                 encoded_len = meta_info->rec_length;
795                 } else {
796                         err("Invalid File ID[0x%04x]", ef);
797                         goto EXIT;
798                 }
799         }
800         break;
801
802         default:
803                 err("Unhandled update REQUEST command[%d]", command);
804                 ret_code = TCORE_RETURN_EINVAL;
805                 goto EXIT;
806         }
807
808         if (tmp) {
809                 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
810                 if (encoded_data == NULL) {
811                         err("Memory allocation failed!!");
812                         free(tmp);
813                         return ret_code;
814                 }
815
816                 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
817                 util_byte_to_hex(tmp, encoded_data, encoded_len);
818                 free(tmp);
819         } else {
820                 err("Failed to Encode data");
821                 goto EXIT;
822         }
823
824         dbg("Encoded Data length =[%d]", encoded_len);
825         tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
826
827         switch (ef) {
828         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
829         case SIM_EF_ELP:
830         case SIM_EF_LP:
831         case SIM_EF_CPHS_VOICE_MSG_WAITING:
832                 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
833         break;
834
835         case SIM_EF_USIM_CFIS:
836         case SIM_EF_USIM_MWIS:
837         case SIM_EF_CPHS_MAILBOX_NUMBERS:
838         case SIM_EF_MBDN:
839                 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
840         break;
841
842         case SIM_EF_USIM_MBI:
843                 if (rec_index > 0)
844                         ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
845                 else
846                         memset(meta_info, 0x00, sizeof(struct imc_sim_property));
847         break;
848
849         default:
850                 err("Unhandled File ID[0x%04x]", ef);
851                 ret_code = TCORE_RETURN_EINVAL;
852         break;
853         }
854
855 EXIT:
856         if (encoded_data) {
857                 free(encoded_data);
858                 encoded_data = NULL;
859         }
860
861         return ret_code;
862 }
863
864 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
865 {
866         struct tresp_sim_read resp = {0, };
867         struct imc_sim_property *meta_info = NULL;
868         enum tcore_request_command command = TREQ_UNKNOWN;
869         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
870
871         dbg("EF[0x%x] access Result[%d]", ef, rt);
872
873         resp.result = rt;
874         memset(&resp.data, 0x00, sizeof(resp.data));
875         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
876         command = tcore_user_request_get_command(ur);
877         sim_type = tcore_sim_get_type(o);
878
879         if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
880                 && (rt != SIM_ACCESS_SUCCESS)) {
881                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
882                 return;
883         }
884
885         switch (ef) {
886         case SIM_EF_ELP:
887                 if (rt == SIM_ACCESS_SUCCESS) {
888                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
889                         if (command == TREQ_SIM_SET_LANGUAGE)
890                                 __set_file_data(o, ur, ef);
891                         else
892                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
893                 } else {
894                         if (sim_type == SIM_TYPE_GSM) {
895                                 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
896                                 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
897                                 _get_file_info(o, ur, SIM_EF_LP);
898                         } else if (sim_type == SIM_TYPE_USIM) {
899                                 dbg(
900                                         " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05), EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
901                                 /* EFELPand EFLI not present at this point. */
902                                 /*                                      po->language.lang_cnt = 0;*/
903                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
904                                         sizeof(struct tresp_sim_read), &resp);
905                                 return;
906                         }
907                 }
908                 break;
909
910         case SIM_EF_LP:   /* same with SIM_EF_USIM_LI */
911                 if (rt == SIM_ACCESS_SUCCESS) {
912                         dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
913                         if (command == TREQ_SIM_SET_LANGUAGE)
914                                 __set_file_data(o, ur, ef);
915                         else
916                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
917                 } else {
918                         dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
919                                 sim_type);
920                         if (sim_type == SIM_TYPE_GSM) {
921                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
922                                         sizeof(struct tresp_sim_read), &resp);
923                                 return;
924                         }
925                         /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level      */
926                         else if (sim_type == SIM_TYPE_USIM) {
927                                 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
928                                 _get_file_info(o, ur, SIM_EF_ELP);
929                         }
930                 }
931                 break;
932
933         case SIM_EF_USIM_PL:
934                 if (rt == SIM_ACCESS_SUCCESS) {
935                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
936                         if (command == TREQ_SIM_SET_LANGUAGE)
937                                 __set_file_data(o, ur, ef);
938                         else
939                                 _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
940                 } else {
941                         /* EFELIand EFPL not present, so set language count as zero and select ECC */
942                         dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
943                         tcore_user_request_send_response(ur, _find_resp_command(ur),
944                                                                                          sizeof(struct tresp_sim_read), &resp);
945                         return;
946                 }
947                 break;
948
949         case SIM_EF_ECC:
950                 if (sim_type == SIM_TYPE_GSM) {
951                         _get_file_data(o, ur, ef, 0, meta_info->data_size);
952                 } else if (sim_type == SIM_TYPE_USIM) {
953                         if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX)
954                                 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
955
956                         meta_info->current_index++;
957                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
958                 }
959                 break;
960
961         case SIM_EF_ICCID:
962         case SIM_EF_IMSI:
963         case SIM_EF_SST:
964         case SIM_EF_SPN:
965         case SIM_EF_SPDI:
966         case SIM_EF_CPHS_VOICE_MSG_WAITING:
967         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
968         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
969         case SIM_EF_CPHS_DYNAMICFLAGS:
970         case SIM_EF_CPHS_DYNAMIC2FLAG:
971         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
972         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
973         case SIM_EF_OPLMN_ACT:
974                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
975                 break;
976
977         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
978                 if (command == TREQ_SIM_SET_CALLFORWARDING)
979                         __set_file_data(o, ur, ef);
980                 else
981                         _get_file_data(o, ur, ef, 0, meta_info->data_size);
982         break;
983
984         case SIM_EF_CPHS_CPHS_INFO:
985                 if (rt == SIM_ACCESS_SUCCESS) {
986                         tcore_sim_set_cphs_status(o, TRUE);
987                         if (!tcore_user_request_ref_communicator(ur)) {
988                                 dbg("internal CPHS INFO request before sim status update");
989                                 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
990                         } else {
991                                 dbg("external CPHS INFO request");
992                                 _get_file_data(o, ur, ef, 0, meta_info->data_size);
993                         }
994                 } else {
995                         tcore_sim_set_cphs_status(o, FALSE);
996                         if (!tcore_user_request_ref_communicator(ur)) {
997                                 dbg("internal CPHS INFO request before sim status update");
998                                 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
999                         } else {
1000                                 dbg("external CPHS INFO request");
1001                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1002                                                                                                  sizeof(struct tresp_sim_read), &resp);
1003                         }
1004                 }
1005                 break;
1006
1007         case SIM_EF_USIM_CFIS:
1008                 if (command == TREQ_SIM_SET_CALLFORWARDING) {
1009                         __set_file_data(o, ur, ef);
1010                 } else {
1011                         if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX)
1012                                 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
1013
1014                         meta_info->current_index++;
1015                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1016                 }
1017                 break;
1018
1019         case SIM_EF_USIM_MWIS:
1020                 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
1021                         __set_file_data(o, ur, ef);
1022                 } else {
1023                         meta_info->current_index++;
1024                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1025                 }
1026                 break;
1027
1028         case SIM_EF_USIM_MBI:
1029                 if (command == TREQ_SIM_SET_MAILBOX) {
1030                         __set_file_data(o, ur, ef);
1031                 } else {
1032                         meta_info->current_index++;
1033                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1034                 }
1035                 break;
1036
1037         case SIM_EF_OPL:
1038         case SIM_EF_PNN:
1039         case SIM_EF_CPHS_INFORMATION_NUMBERS:
1040         case SIM_EF_MSISDN:
1041                 meta_info->current_index++;
1042                 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1043                 break;
1044
1045         case SIM_EF_MBDN:
1046         case SIM_EF_CPHS_MAILBOX_NUMBERS:
1047                 if (command == TREQ_SIM_SET_MAILBOX) {
1048                         /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1049                         if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1050                                 err("Cyclic File ID. No update & return error.");
1051                                 meta_info->files.result = SIM_ACCESS_FAILED;
1052                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1053                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1054                                 break;
1055                         } else {
1056                                 __set_file_data(o, ur, ef);
1057                         }
1058                 } else {
1059                         /* Read MailBox */
1060                         meta_info->mb_count = 0;
1061                         meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1062                         if (meta_info->current_index == 0) {
1063                                 err("Invalid MBDN index");
1064                                 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1065                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1066                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1067                         } else {
1068                                 ur = tcore_user_request_ref(ur);
1069                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1070                         }
1071                         _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1072                 }
1073                 break;
1074
1075         default:
1076                 dbg("error - File id for get file info [0x%x]", ef);
1077                 break;
1078         }
1079 }
1080
1081 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1082 {
1083         struct imc_sim_property *meta_info = NULL;
1084
1085         dbg("Entry");
1086
1087         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1088         dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1089         switch (meta_info->file_id) {
1090         case SIM_EF_ELP:
1091         case SIM_EF_USIM_PL:
1092         case SIM_EF_LP:
1093         case SIM_EF_USIM_LI:
1094                 if (decode_ret == TRUE) {
1095 #if 0
1096                         if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1097                                 /* po->language_file = SIM_EF_LP;*/
1098                         else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL)
1099                                 /* po->language_file = SIM_EF_ELP;*/
1100 #endif
1101                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1102                 } else {
1103                         /* 2G */
1104                         /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1105                          -      EFELP is not available;
1106                          -      EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1107                          -      the ME does not support any of the languages in EFELP.
1108                          */
1109                         /* 3G */
1110                         /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1111                          -      if the EFLI has the value 'FFFF' in its highest priority position
1112                          -      if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1113                          */
1114                         if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1115                                 if (meta_info->file_id == SIM_EF_LP)
1116                                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1117                                 else
1118                                         _get_file_info(o, ur, SIM_EF_LP);
1119                         } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1120                                 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1121                                         _get_file_info(o, ur, SIM_EF_ELP);
1122                                 else
1123                                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1124                         }
1125                 }
1126                 break;
1127
1128         case SIM_EF_ECC:
1129                 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1130                         if (meta_info->current_index == meta_info->rec_count) {
1131                                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1132                         } else {
1133                                 meta_info->current_index++;
1134                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1135                         }
1136                 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1137                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1138                 } else {
1139                         dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1140                 }
1141                 break;
1142
1143         case SIM_EF_IMSI:
1144                 ur = tcore_user_request_new(NULL, NULL);   /* this is for using ur metainfo set/ref functionality. */
1145                 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1146                 break;
1147
1148         case SIM_EF_MSISDN:
1149                 if (meta_info->current_index == meta_info->rec_count) {
1150                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1151                 } else {
1152                         meta_info->current_index++;
1153                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1154                 }
1155                 break;
1156
1157         case SIM_EF_OPL:
1158                 if (meta_info->current_index == meta_info->rec_count) {
1159                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1160                 } else {
1161                         meta_info->current_index++;
1162                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1163                 }
1164                 break;
1165
1166         case SIM_EF_PNN:
1167                 if (meta_info->current_index == meta_info->rec_count) {
1168                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1169                 } else {
1170                         meta_info->current_index++;
1171                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1172                 }
1173                 break;
1174
1175         case SIM_EF_USIM_MBI:
1176                 if (meta_info->current_index == meta_info->rec_count) {
1177                         _get_file_info(0, ur, SIM_EF_MBDN);
1178                 } else {
1179                         meta_info->current_index++;
1180                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1181                 }
1182                 break;
1183
1184         case SIM_EF_MBDN:
1185         case SIM_EF_CPHS_MAILBOX_NUMBERS:
1186                 if (meta_info->mb_count == meta_info->mb_data.count) {
1187                         memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1188                         tcore_user_request_send_response(ur, _find_resp_command(ur),
1189                                                         sizeof(struct tresp_sim_read), &meta_info->files);
1190                 } else {
1191                         meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1192                         if (meta_info->current_index == 0) {
1193                                 err("Invalid MBDN index");
1194                                 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1195                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
1196                                                                 sizeof(struct tresp_sim_read), &meta_info->files);
1197                         } else {
1198                                 ur = tcore_user_request_ref(ur);
1199                                 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1200                         }
1201                 }
1202                 break;
1203
1204         case SIM_EF_USIM_CFIS:
1205         case SIM_EF_USIM_MWIS:
1206         case SIM_EF_CPHS_INFORMATION_NUMBERS:
1207                 if (meta_info->current_index == meta_info->rec_count) {
1208                         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1209                 } else {
1210                         meta_info->current_index++;
1211                         _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1212                 }
1213                 break;
1214
1215         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1216                 meta_info->files.result = rt;
1217                 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1218                 break;
1219
1220         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1221                 if (rt == SIM_ACCESS_SUCCESS)
1222                         meta_info->files.result = SIM_ACCESS_SUCCESS;
1223
1224                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1225                 break;
1226
1227         case SIM_EF_ICCID:
1228         case SIM_EF_SST:
1229         case SIM_EF_SPN:
1230         case SIM_EF_SPDI:
1231         case SIM_EF_OPLMN_ACT:
1232         case SIM_EF_CPHS_CPHS_INFO:
1233         case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1234         case SIM_EF_CPHS_VOICE_MSG_WAITING:
1235         case SIM_EF_CPHS_DYNAMICFLAGS:
1236         case SIM_EF_CPHS_DYNAMIC2FLAG:
1237         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1238         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1239                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1240                 break;
1241
1242         default:
1243                 dbg("File id not handled [0x%x]", meta_info->file_id);
1244                 break;
1245         }
1246 }
1247
1248 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1249 {
1250         struct tnoti_sim_status noti_data = {0, };
1251
1252         if (sim_status != tcore_sim_get_status(o)) {
1253                 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1254                                 tcore_sim_get_status(o), sim_status);
1255
1256                 /* Update SIM Status */
1257                 tcore_sim_set_status(o, sim_status);
1258                 noti_data.sim_status = sim_status;
1259
1260                 /* Send notification */
1261                 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1262                                 o, TNOTI_SIM_STATUS, sizeof(noti_data), &noti_data);
1263         }
1264 }
1265
1266 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1267 {
1268         const TcoreATResponse *resp = data;
1269         UserRequest *ur = NULL;
1270         CoreObject *o = NULL;
1271         GSList *tokens = NULL;
1272         enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1273         const char *line;
1274         int state;
1275
1276         dbg("Entry");
1277
1278         o = tcore_pending_ref_core_object(p);
1279         ur = tcore_pending_ref_user_request(p);
1280
1281         if (resp->success > 0) {
1282                 dbg("RESPONSE OK");
1283                 if (resp->lines) {
1284                         line = (const char *)resp->lines->data;
1285                         tokens = tcore_at_tok_new(line);
1286                         if (g_slist_length(tokens) != 1) {
1287                                 msg("Invalid message");
1288                                 tcore_at_tok_free(tokens);
1289                                 return;
1290                         }
1291                 }
1292                 state = atoi(g_slist_nth_data(tokens, 0));
1293                 dbg("SIM Type is %d", state);
1294
1295                 if (state == 0) {
1296                         sim_type = SIM_TYPE_GSM;
1297                         tcore_sim_set_app_list(o, SIM_APP_TYPE_SIM);
1298                 } else if (state == 1) {
1299                         sim_type = SIM_TYPE_USIM;
1300                         tcore_sim_set_app_list(o, SIM_APP_TYPE_USIM);
1301                 } else {
1302                         sim_type = SIM_TYPE_UNKNOWN;
1303                 }
1304         } else {
1305                 dbg("RESPONSE NOK");
1306                 sim_type = SIM_TYPE_UNKNOWN;
1307         }
1308
1309         tcore_sim_set_type(o, sim_type);
1310
1311         if (sim_type != SIM_TYPE_UNKNOWN) {
1312                 /* set user request for using ur metainfo set/ref functionality */
1313                 ur = tcore_user_request_new(NULL, NULL);
1314                 _get_file_info(o, ur, SIM_EF_IMSI);
1315         }
1316
1317         tcore_at_tok_free(tokens);
1318         dbg("Exit");
1319 }
1320
1321 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1322 {
1323         const TcoreATResponse *resp = data;
1324         UserRequest *ur = NULL;
1325         CoreObject *o = NULL;
1326         struct imc_sim_property *meta_info = NULL;
1327         GSList *tokens = NULL;
1328         enum tel_sim_access_result rt;
1329         const char *line = NULL;
1330         int sw1 = 0;
1331         int sw2 = 0;
1332
1333         dbg("Entry");
1334
1335         o = tcore_pending_ref_core_object(p);
1336         ur = tcore_pending_ref_user_request(p);
1337         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1338
1339         if (resp->success > 0) {
1340                 dbg("RESPONSE OK");
1341                 if (resp->lines) {
1342                         line = (const char *)resp->lines->data;
1343                         tokens = tcore_at_tok_new(line);
1344                         if (g_slist_length(tokens) < 2) {
1345                                 err("Invalid message");
1346                                 tcore_at_tok_free(tokens);
1347                                 return;
1348                         }
1349                 }
1350                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1351                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1352
1353                 /*1. SIM access success case*/
1354                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1355                         unsigned char tag_len = 0; /*   1 or 2 bytes ??? */
1356                         unsigned short record_len = 0;
1357                         char num_of_records = 0;
1358                         unsigned char file_id_len = 0;
1359                         unsigned short file_id = 0;
1360                         unsigned short file_size = 0;
1361                         unsigned short file_type = 0;
1362                         unsigned short arr_file_id = 0;
1363
1364                         /*      handling only last 3 bits */
1365                         unsigned char file_type_tag = 0x07;
1366                         unsigned char *ptr_data;
1367
1368                         char *hexData;
1369                         char *tmp;
1370                         char *recordData = NULL;
1371                         hexData = g_slist_nth_data(tokens, 2);
1372                         dbg("hexData: %s", hexData);
1373                         dbg("hexData: %s", hexData + 1);
1374
1375                         tmp = tcore_at_tok_extract(hexData);
1376                         recordData = util_hexStringToBytes(tmp);
1377                         if (!recordData) {
1378                                 err("util_hexStringToBytes Failed!!");
1379                                 tcore_at_tok_free(tokens);
1380                                 return;
1381                         }
1382                         tcore_util_hex_dump("   ", strlen(hexData) / 2, recordData);
1383                         g_free(tmp);
1384
1385                         ptr_data = (unsigned char *)recordData;
1386                         if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1387                                 /*
1388                                  ETSI TS 102 221 v7.9.0
1389                                  - Response Data
1390                                  '62'   FCP template tag
1391                                  - Response for an EF
1392                                  '82'   M       File Descriptor
1393                                  '83'   M       File Identifier
1394                                  'A5'   O       Proprietary information
1395                                  '8A'   M       Life Cycle Status Integer
1396                                  '8B', '8C' or 'AB'     C1      Security attributes
1397                                  '80'   M       File size
1398                                  '81'   O       Total file size
1399                                  '88'   O       Short File Identifier (SFI)
1400                                  */
1401
1402                                 /* rsim.res_len has complete data length received */
1403
1404                                 /* FCP template tag - File Control Parameters tag*/
1405                                 if (*ptr_data == 0x62) {
1406                                         /* parse complete FCP tag*/
1407                                         /* increment to next byte */
1408                                         ptr_data++;
1409                                         tag_len = *ptr_data++;
1410                                         dbg("tag_len: %02x", tag_len);
1411                                         /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1412                                         if (*ptr_data == 0x82) {
1413                                                 /* increment to next byte */
1414                                                 ptr_data++;
1415                                                 /* 2 or 5 value*/
1416                                                 ptr_data++;
1417                                                 /*      unsigned char file_desc_len = *ptr_data++;*/
1418                                                 /*      dbg("file descriptor length: [%d]", file_desc_len);*/
1419                                                 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1420                                                 /* consider only last 3 bits*/
1421                                                 dbg("file_type_tag: %02x", file_type_tag);
1422                                                 file_type_tag = file_type_tag & (*ptr_data);
1423                                                 dbg("file_type_tag: %02x", file_type_tag);
1424
1425                                                 switch (file_type_tag) {
1426                                                 /* increment to next byte */
1427                                                 case 0x1:
1428                                                         dbg("Getting FileType: [Transparent file type]");
1429                                                         file_type = SIM_FTYPE_TRANSPARENT;
1430
1431                                                         /* increment to next byte */
1432                                                         ptr_data++;
1433                                                         /* increment to next byte */
1434                                                         ptr_data++;
1435                                                         break;
1436
1437                                                 case 0x2:
1438                                                         dbg("Getting FileType: [Linear fixed file type]");
1439                                                         /* increment to next byte */
1440                                                         ptr_data++;
1441                                                         /*      data coding byte - value 21 */
1442                                                         ptr_data++;
1443                                                         /*      2bytes */
1444                                                         memcpy(&record_len, ptr_data, 2);
1445                                                         /* swap bytes */
1446                                                         SWAPBYTES16(record_len);
1447                                                         ptr_data = ptr_data + 2;
1448                                                         num_of_records = *ptr_data++;
1449                                                         /* Data lossy conversation from enum (int) to unsigned char */
1450                                                         file_type = SIM_FTYPE_LINEAR_FIXED;
1451                                                         break;
1452
1453                                                 case 0x6:
1454                                                         dbg("Cyclic fixed file type");
1455                                                         /* increment to next byte */
1456                                                         ptr_data++;
1457                                                         /*      data coding byte - value 21 */
1458                                                         ptr_data++;
1459                                                         /*      2bytes */
1460                                                         memcpy(&record_len, ptr_data, 2);
1461                                                         /* swap bytes */
1462                                                         SWAPBYTES16(record_len);
1463                                                         ptr_data = ptr_data + 2;
1464                                                         num_of_records = *ptr_data++;
1465                                                         file_type = SIM_FTYPE_CYCLIC;
1466                                                         break;
1467
1468                                                 default:
1469                                                         dbg("not handled file type [0x%x]", *ptr_data);
1470                                                         break;
1471                                                 }
1472                                         } else {
1473                                                 dbg("INVALID FCP received - DEbug!");
1474                                                 tcore_at_tok_free(tokens);
1475                                                 g_free(recordData);
1476                                                 return;
1477                                         }
1478
1479                                         /*
1480                                          * File identifier - file id??
1481                                          *
1482                                          * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1483                                          */
1484                                         if (*ptr_data == 0x83) {
1485                                                 /* increment to next byte */
1486                                                 ptr_data++;
1487                                                 file_id_len = *ptr_data++;
1488                                                 dbg("file_id_len: %02x", file_id_len);
1489
1490                                                 memcpy(&file_id, ptr_data, file_id_len);
1491                                                 dbg("file_id: %x", file_id);
1492
1493                                                 /* swap bytes    */
1494                                                 SWAPBYTES16(file_id);
1495                                                 dbg("file_id: %x", file_id);
1496
1497                                                 ptr_data = ptr_data + 2;
1498                                                 dbg("Getting FileID=[0x%x]", file_id);
1499                                         } else {
1500                                                 dbg("INVALID FCP received - DEbug!");
1501                                                 tcore_at_tok_free(tokens);
1502                                                 g_free(recordData);
1503                                                 return;
1504                                         }
1505
1506                                         /*      proprietary information */
1507                                         if (*ptr_data == 0xA5) {
1508                                                 unsigned short prop_len;
1509                                                 /* increment to next byte */
1510                                                 ptr_data++;
1511
1512                                                 /* length */
1513                                                 prop_len = *ptr_data;
1514                                                 dbg("prop_len: %02x", prop_len);
1515
1516                                                 /* skip data */
1517                                                 ptr_data = ptr_data + prop_len + 1;
1518                                         } else {
1519                                                 dbg("INVALID FCP received - DEbug!");
1520                                         }
1521
1522                                         /* life cycle status integer [8A][length:0x01][status]*/
1523                                         /*
1524                                          status info b8~b1
1525                                          00000000 : No information given
1526                                          00000001 : creation state
1527                                          00000011 : initialization state
1528                                          000001-1 : operation state -activated
1529                                          000001-0 : operation state -deactivated
1530                                          000011-- : Termination state
1531                                          b8~b5 !=0, b4~b1=X : Proprietary
1532                                          Any other value : RFU
1533                                          */
1534                                         if (*ptr_data == 0x8A) {
1535                                                 /* increment to next byte */
1536                                                 ptr_data++;
1537                                                 /* length - value 1 */
1538                                                 ptr_data++;
1539
1540                                                 switch (*ptr_data) {
1541                                                 case 0x04:
1542                                                 case 0x06:
1543                                                         dbg("<RX> operation state -deactivated");
1544                                                         ptr_data++;
1545                                                         break;
1546
1547                                                 case 0x05:
1548                                                 case 0x07:
1549                                                         dbg("<RX> operation state -activated");
1550                                                         ptr_data++;
1551                                                         break;
1552
1553                                                 default:
1554                                                         dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1555                                                         ptr_data++;
1556                                                         break;
1557                                                 }
1558                                         }
1559
1560                                         /* related to security attributes : currently not handled*/
1561                                         if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1562                                                 /* increment to next byte */
1563                                                 ptr_data++;
1564                                                 /* if tag length is 3 */
1565                                                 if (*ptr_data == 0x03) {
1566                                                         /* increment to next byte */
1567                                                         ptr_data++;
1568                                                         /* EFARR file id */
1569                                                         memcpy(&arr_file_id, ptr_data, 2);
1570                                                         /* swap byes */
1571                                                         SWAPBYTES16(arr_file_id);
1572                                                         ptr_data = ptr_data + 2;
1573                                                         ptr_data++;     /*arr_file_id_rec_num = *ptr_data++; */
1574                                                 } else {
1575                                                         /* if tag length is not 3 */
1576                                                         /* ignoring bytes       */
1577                                                         dbg("Useless security attributes, so jump to next tag");
1578                                                         ptr_data = ptr_data + (*ptr_data + 1);
1579                                                 }
1580                                         } else {
1581                                                 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1582                                                 tcore_at_tok_free(tokens);
1583                                                 g_free(recordData);
1584                                                 return;
1585                                         }
1586
1587                                         dbg("Current ptr_data value is [%x]", *ptr_data);
1588
1589                                         /* file size excluding structural info*/
1590                                         if (*ptr_data == 0x80) {
1591                                                 /* for EF file size is body of file and for Linear or cyclic it is
1592                                                  * number of recXsizeof(one record)
1593                                                  */
1594                                                 /* increment to next byte */
1595                                                 ptr_data++;
1596                                                 /* length is 1 byte - value is 2 bytes or more */
1597                                                 ptr_data++;
1598                                                 memcpy(&file_size, ptr_data, 2);
1599                                                 /* swap bytes */
1600                                                 SWAPBYTES16(file_size);
1601                                                 ptr_data = ptr_data + 2;
1602                                         } else {
1603                                                 dbg("INVALID FCP received - DEbug!");
1604                                                 tcore_at_tok_free(tokens);
1605                                                 g_free(recordData);
1606                                                 return;
1607                                         }
1608
1609                                         /* total file size including structural info*/
1610                                         if (*ptr_data == 0x81) {
1611                                                 /* int len; */
1612                                                 /* increment to next byte */
1613                                                 ptr_data++;
1614                                                 /* length */
1615                                                 /* len = *ptr_data; */
1616                                                 /* ignored bytes */
1617                                                 ptr_data = ptr_data + 3;
1618                                         } else {
1619                                                 dbg("INVALID FCP received - DEbug!");
1620                                                 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1621                                                 /* return -1; */
1622                                         }
1623                                         /*short file identifier ignored*/
1624                                         if (*ptr_data == 0x88) {
1625                                                 dbg("0x88: Do Nothing");
1626                                                 /*DO NOTHING*/
1627                                         }
1628                                 } else {
1629                                         dbg("INVALID FCP received - DEbug!");
1630                                         tcore_at_tok_free(tokens);
1631                                         g_free(recordData);
1632                                         return;
1633                                 }
1634                         } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1635                                 unsigned char gsm_specific_file_data_len = 0;
1636                                 /*      ignore RFU byte1 and byte2 */
1637                                 ptr_data++;
1638                                 ptr_data++;
1639                                 /*      file size */
1640                                 memcpy(&file_size, ptr_data, 2);
1641                                 /* swap bytes */
1642                                 SWAPBYTES16(file_size);
1643                                 /*      parsed file size */
1644                                 ptr_data = ptr_data + 2;
1645                                 /* file id */
1646                                 memcpy(&file_id, ptr_data, 2);
1647                                 SWAPBYTES16(file_id);
1648                                 dbg("FILE id --> [%x]", file_id);
1649                                 ptr_data = ptr_data + 2;
1650                                 /* save file type - transparent, linear fixed or cyclic */
1651                                 file_type_tag = (*(ptr_data + 7));
1652
1653                                 switch (*ptr_data) {
1654                                 case 0x0:
1655                                         /* RFU file type */
1656                                         dbg("RFU file type- not handled - Debug!");
1657                                         break;
1658
1659                                 case 0x1:
1660                                         /* MF file type */
1661                                         dbg("MF file type - not handled - Debug!");
1662                                         break;
1663
1664                                 case 0x2:
1665                                         /* DF file type */
1666                                         dbg("DF file type - not handled - Debug!");
1667                                         break;
1668
1669                                 case 0x4:
1670                                         /* EF file type */
1671                                         dbg("EF file type [%d] ", file_type_tag);
1672                                         /*      increment to next byte */
1673                                         ptr_data++;
1674
1675                                         if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1676                                                 /* increament to next byte as this byte is RFU */
1677                                                 ptr_data++;
1678                                                 file_type =
1679                                                         (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1680                                         } else {
1681                                                 /* increment to next byte */
1682                                                 ptr_data++;
1683                                                 /*      For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1684                                                 /* the INCREASE command is allowed on the selected cyclic file. */
1685                                                 file_type = SIM_FTYPE_CYCLIC;
1686                                         }
1687                                         /* bytes 9 to 11 give SIM file access conditions */
1688                                         ptr_data++;
1689                                         /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1690                                         ptr_data++;
1691                                         /* byte 11 is invalidate and rehabilate nibbles */
1692                                         ptr_data++;
1693                                         /* byte 12 - file status */
1694                                         ptr_data++;
1695                                         /* byte 13 - GSM specific data */
1696                                         gsm_specific_file_data_len = *ptr_data;
1697                                         dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1698                                         ptr_data++;
1699                                         /*      byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1700                                         ptr_data++;
1701                                         /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1702                                         record_len = *ptr_data;
1703                                         dbg("record length[%d], file size[%d]", record_len, file_size);
1704
1705                                         if (record_len != 0)
1706                                                 num_of_records = (file_size / record_len);
1707
1708                                         dbg("Number of records [%d]", num_of_records);
1709                                         break;
1710
1711                                 default:
1712                                         dbg("not handled file type");
1713                                         break;
1714                                 }
1715                         } else {
1716                                 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1717                         }
1718
1719                         dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1720                                 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1721
1722                         meta_info->file_type = file_type;
1723                         meta_info->data_size = file_size;
1724                         meta_info->rec_length = record_len;
1725                         meta_info->rec_count = num_of_records;
1726                         meta_info->current_index = 0; /* reset for new record type EF */
1727                         rt = SIM_ACCESS_SUCCESS;
1728                         g_free(recordData);
1729                 } else {
1730                         /*2. SIM access fail case*/
1731                         dbg("error to get ef[0x%x]", meta_info->file_id);
1732                         dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1733                         rt = _decode_status_word(sw1, sw2);
1734                 }
1735                 ur = tcore_user_request_ref(ur);
1736
1737                 dbg("Calling _next_from_get_file_info");
1738                 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1739                 tcore_at_tok_free(tokens);
1740         } else {
1741                 dbg("RESPONSE NOK");
1742                 dbg("error to get ef[0x%x]", meta_info->file_id);
1743                 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1744                 rt = SIM_ACCESS_FAILED;
1745
1746                 ur = tcore_user_request_ref(ur);
1747                 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1748         }
1749         dbg("Exit");
1750 }
1751
1752 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1753 {
1754         const TcoreATResponse *resp = data;
1755         UserRequest *ur = NULL;
1756         CoreObject *o = NULL;
1757         struct imc_sim_property *meta_info = NULL;
1758         GSList *tokens = NULL;
1759         enum tel_sim_access_result rt;
1760         gboolean dr = FALSE;
1761         const char *line = NULL;
1762         char *res = NULL;
1763         char *tmp = NULL;
1764         int res_len;
1765         int sw1 = 0;
1766         int sw2 = 0;
1767
1768         dbg("Entry");
1769
1770         o = tcore_pending_ref_core_object(p);
1771         ur = tcore_pending_ref_user_request(p);
1772         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1773
1774         if (resp->success > 0) {
1775                 dbg("RESPONSE OK");
1776                 if (resp->lines) {
1777                         line = (const char *)resp->lines->data;
1778                         tokens = tcore_at_tok_new(line);
1779                         if (g_slist_length(tokens) != 3) {
1780                                 msg("Invalid message");
1781                                 tcore_at_tok_free(tokens);
1782                                 return;
1783                         }
1784                 }
1785                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1786                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1787                 res = g_slist_nth_data(tokens, 2);
1788
1789                 tmp = tcore_at_tok_extract(res);
1790                 if (!tmp)
1791                         return;
1792                 res = util_hexStringToBytes(tmp);
1793                 res_len = strlen(tmp) / 2;
1794                 dbg("Response: [%s] Response length: [%d]", res, res_len);
1795
1796                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1797                         rt = SIM_ACCESS_SUCCESS;
1798                         meta_info->files.result = rt;
1799
1800                         dbg("File ID: [0x%x]", meta_info->file_id);
1801                         switch (meta_info->file_id) {
1802                         case SIM_EF_IMSI:
1803                         {
1804                                 struct tel_sim_imsi *imsi = NULL;
1805
1806                                 dbg("Data: [%s]", res);
1807                                 imsi = g_try_new0(struct tel_sim_imsi, 1);
1808                                 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1809                                 if (dr == FALSE) {
1810                                         err("IMSI decoding failed");
1811                                 } else {
1812                                         _sim_check_identity(o, imsi);
1813                                         tcore_sim_set_imsi(o, imsi);
1814                                 }
1815
1816                                 /* Free memory */
1817                                 g_free(imsi);
1818                         }
1819                         break;
1820
1821                         case SIM_EF_ICCID:
1822                                 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1823                         break;
1824
1825                         case SIM_EF_ELP:                        /* 2G EF - 2 bytes decoding */
1826                         case SIM_EF_USIM_LI:            /* 3G EF - 2 bytes decoding */
1827                         case SIM_EF_USIM_PL:            /* 3G EF - same as EFELP, so 2 byte decoding */
1828                         case SIM_EF_LP:                         /* 1 byte encoding */
1829                                 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1830                                                 && (meta_info->file_id == SIM_EF_LP)) {
1831                                         /*
1832                                          * 2G LP(0x6F05) has 1 byte for each language
1833                                          */
1834                                         dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1835                                                                 (unsigned char *)res, res_len);
1836                                 } else {
1837                                         /*
1838                                          * 3G LI(0x6F05)/PL(0x2F05),
1839                                          * 2G ELP(0x2F05) has 2 bytes for each language
1840                                          */
1841                                         dr = tcore_sim_decode_li(meta_info->file_id,
1842                                                                 &meta_info->files.data.language,
1843                                                                 (unsigned char *)res, res_len);
1844                                 }
1845                         break;
1846
1847                         case SIM_EF_SPN:
1848                                 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1849                                                                 (unsigned char *)res, res_len);
1850                         break;
1851
1852                         case SIM_EF_SPDI:
1853                                 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1854                                                                 (unsigned char *)res, res_len);
1855                         break;
1856
1857                         case SIM_EF_SST: /* EF UST has same address */
1858                         {
1859                                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1860                                         dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1861                                         if (dr == FALSE) {
1862                                                 dbg("SST decoding failed");
1863                                                 tcore_sim_set_service_table(o, NULL);
1864                                         } else {
1865                                                 int i = 0, size = sizeof(struct tel_sim_sst);
1866                                                 char *temp = NULL;
1867                                                 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1868                                                 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1869                                                         memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1870                                                         for (i = 0; i < size; i++) {
1871                                                                 if (temp[i] == 1)
1872                                                                         temp[i] = '1';
1873                                                                 else
1874                                                                         temp[i] = '0';
1875                                                         }
1876                                                         dbg("svct.table.sst=[%s]", temp);
1877                                                         g_free(temp);
1878                                                 }
1879                                                 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1880                                         }
1881                                 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1882                                         dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1883                                         if (dr == FALSE) {
1884                                                 dbg("SST decoding failed");
1885                                                 tcore_sim_set_service_table(o, NULL);
1886                                         } else {
1887                                                 int i = 0, size = sizeof(struct tel_sim_ust);
1888                                                 char *temp = NULL;
1889                                                 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1890                                                 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1891                                                         memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1892                                                         for (i = 0; i < size; i++) {
1893                                                                 if (temp[i] == 1)
1894                                                                         temp[i] = '1';
1895                                                                 else
1896                                                                         temp[i] = '0';
1897                                                         }
1898                                                         dbg("svct.table.ust=[%s]", temp);
1899                                                         g_free(temp);
1900                                                 }
1901                                                 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1902                                         }
1903                                 } else {
1904                                         dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(o));
1905                                 }
1906                         }
1907                         break;
1908
1909                         case SIM_EF_ECC:
1910                         {
1911                                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1912                                         dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1913                                 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1914                                         struct tel_sim_ecc *ecc = NULL;
1915
1916                                         ecc = g_try_new0(struct tel_sim_ecc, 1);
1917                                         dbg("Index [%d]", meta_info->current_index);
1918
1919                                         dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1920                                         if (dr == TRUE) {
1921                                                 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1922                                                 meta_info->files.data.ecc.ecc_count++;
1923                                         }
1924
1925                                         /* Free memory */
1926                                         g_free(ecc);
1927                                 } else {
1928                                         dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1929                                 }
1930                         }
1931                         break;
1932
1933                         case SIM_EF_MSISDN:
1934                         {
1935                                 struct tel_sim_msisdn *msisdn = NULL;
1936
1937                                 dbg("Index [%d]", meta_info->current_index);
1938                                 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1939                                 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1940                                 if (dr == TRUE) {
1941                                         memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1942                                                                 msisdn, sizeof(struct tel_sim_msisdn));
1943
1944                                         meta_info->files.data.msisdn_list.count++;
1945                                 }
1946
1947                                 /* Free memory */
1948                                 g_free(msisdn);
1949                         }
1950                         break;
1951
1952                         case SIM_EF_OPL:
1953                         {
1954                                 struct tel_sim_opl *opl = NULL;
1955
1956                                 dbg("decode w/ index [%d]", meta_info->current_index);
1957
1958                                 opl = g_try_new0(struct tel_sim_opl, 1);
1959                                 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1960                                 if (dr == TRUE) {
1961                                         memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1962                                                         opl, sizeof(struct tel_sim_opl));
1963                                         meta_info->files.data.opl.opl_count++;
1964                                 }
1965
1966                                 /* Free memory */
1967                                 g_free(opl);
1968                         }
1969                         break;
1970
1971                         case SIM_EF_PNN:
1972                         {
1973                                 struct tel_sim_pnn *pnn = NULL;
1974
1975                                 dbg("decode w/ index [%d]", meta_info->current_index);
1976
1977                                 pnn = g_try_new0(struct tel_sim_pnn, 1);
1978                                 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1979                                 if (dr == TRUE) {
1980                                         memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1981                                                                 pnn, sizeof(struct tel_sim_pnn));
1982
1983                                         meta_info->files.data.pnn.pnn_count++;
1984                                 }
1985
1986                                 /* Free memory */
1987                                 g_free(pnn);
1988                         }
1989                         break;
1990
1991                         case SIM_EF_OPLMN_ACT:
1992                                 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1993                                                                                 (unsigned char *)res, res_len);
1994                         break;
1995
1996                         case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1997                                 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1998                         break;
1999
2000                         case SIM_EF_USIM_MBI: /* linear type */
2001                         {
2002                                 struct tel_sim_mbi *mbi = NULL;
2003
2004                                 mbi = g_try_new0(struct tel_sim_mbi, 1);
2005                                 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
2006                                 if (dr == TRUE) {
2007                                         memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
2008                                                                                 mbi, sizeof(struct tel_sim_mbi));
2009                                         meta_info->mbi_list.profile_count++;
2010
2011                                         dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
2012                                         dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].voice_index);
2013                                         dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].fax_index);
2014                                         dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].email_index);
2015                                         dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].other_index);
2016                                         dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].video_index);
2017                                 }
2018
2019                                 /* Free memory */
2020                                 g_free(mbi);
2021                         }
2022                         break;
2023
2024                         case SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
2025                         case SIM_EF_MBDN: /* linear type */
2026                                 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
2027                                                                         (unsigned char *)res, res_len);
2028                                 meta_info->mb_count++;
2029                         break;
2030
2031                         case SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
2032                                 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
2033                                                                         (unsigned char *)res, res_len);
2034                         break;
2035
2036                         case SIM_EF_USIM_MWIS: /* linear type */
2037                         {
2038                                 struct tel_sim_mw *mw = NULL;
2039
2040                                 mw = g_try_new0(struct tel_sim_mw, 1);
2041
2042                                 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
2043                                 if (dr == TRUE) {
2044                                         memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
2045                                         meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
2046                                         meta_info->files.data.mw.mw_list.profile_count++;
2047                                 }
2048
2049                                 /* Free memory */
2050                                 g_free(mw);
2051                         }
2052                         break;
2053
2054                         case SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
2055                                 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2056                                                                         (unsigned char *)res, res_len);
2057                         break;
2058
2059                         case SIM_EF_USIM_CFIS: /* linear type */
2060                         {
2061                                 struct tel_sim_cfis *cf = NULL;
2062
2063                                 cf = g_try_new0(struct tel_sim_cfis, 1);
2064                                 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2065                                 if (dr == TRUE) {
2066                                         memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2067                                                                         cf, sizeof(struct tel_sim_cfis));
2068
2069                                         meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2070                                         meta_info->files.data.cf.cf_list.profile_count++;
2071                                 }
2072
2073                                 /* Free memory */
2074                                 g_free(cf);
2075                         }
2076                         break;
2077
2078                         case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2079                                 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2080                         break;
2081
2082                         case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2083                                 dr = tcore_sim_decode_ons((unsigned char *)&meta_info->files.data.cphs_net.full_name,
2084                                                                         (unsigned char *)res, res_len);
2085                                 dbg("meta_info->files.result[%d], meta_info->files.data.cphs_net.full_name[%s]",
2086                                                 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2087                         break;
2088
2089                         case SIM_EF_CPHS_DYNAMICFLAGS:
2090                                 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2091                                                                                 p_data->response, p_data->response_len);*/
2092                         break;
2093
2094                         case SIM_EF_CPHS_DYNAMIC2FLAG:
2095                                 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2096                                                                                 p_data->response_len);*/
2097                         break;
2098
2099                         case SIM_EF_CPHS_CPHS_INFO:
2100                                 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2101                                                                                 (unsigned char *)res, res_len);
2102                         break;
2103
2104                         case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2105                                 dr = tcore_sim_decode_short_ons((unsigned char *)&meta_info->files.data.cphs_net.short_name,
2106                                                                                 (unsigned char *)res, res_len);
2107                         break;
2108
2109                         case SIM_EF_CPHS_INFORMATION_NUMBERS:
2110                                 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2111                         break;
2112
2113                         default:
2114                                 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2115                                 dr = 0;
2116                         break;
2117                         }
2118                 } else {
2119                         rt = _decode_status_word(sw1, sw2);
2120                         meta_info->files.result = rt;
2121                 }
2122
2123                 /* Free memory */
2124                 g_free(tmp);
2125                 g_free(res);
2126
2127                 /* Free tokens */
2128                 tcore_at_tok_free(tokens);
2129         } else {
2130                 dbg("RESPONSE NOK");
2131                 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2132                 rt = SIM_ACCESS_FAILED;
2133         }
2134
2135         /* Reference User Request */
2136         ur = tcore_user_request_ref(ur);
2137
2138         /* Get File data */
2139         _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2140
2141         dbg("Exit");
2142 }
2143
2144 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2145 {
2146         const TcoreATResponse *resp = data;
2147         UserRequest *ur = NULL;
2148         CoreObject *o = NULL;
2149         struct imc_sim_property *sp = NULL;
2150         GSList *tokens = NULL;
2151         const char *line = NULL;
2152         int lock_type = 0;
2153         int attempts_left = 0;
2154         int time_penalty = 0;
2155
2156         dbg("Entry");
2157
2158         o = tcore_pending_ref_core_object(p);
2159         sp = tcore_sim_ref_userdata(o);
2160         if (!sp) {
2161                 err("user data is null");
2162                 return;
2163         }
2164         ur = tcore_pending_ref_user_request(p);
2165
2166         if (resp->success > 0) {
2167                 dbg("RESPONSE OK");
2168                 if (resp->lines) {
2169                         line = (const char *)resp->lines->data;
2170                         tokens = tcore_at_tok_new(line);
2171                         if (g_slist_length(tokens) < 3) {
2172                                 msg("Invalid message");
2173                                 tcore_at_tok_free(tokens);
2174                                 return;
2175                         }
2176                 }
2177                 lock_type = atoi(g_slist_nth_data(tokens, 0));
2178                 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2179                 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2180
2181                 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2182                         lock_type, attempts_left, time_penalty);
2183
2184                 switch (sp->current_sec_op) {
2185                 case SEC_PIN1_VERIFY:
2186                 case SEC_PIN2_VERIFY:
2187                 case SEC_SIM_VERIFY:
2188                 case SEC_ADM_VERIFY:
2189                 {
2190                         struct tresp_sim_verify_pins v_pin = {0, };
2191
2192                         v_pin.result = SIM_INCORRECT_PASSWORD;
2193                         v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2194                         v_pin.retry_count = attempts_left;
2195                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2196                                                                                          sizeof(struct tresp_sim_verify_pins), &v_pin);
2197                 }
2198                 break;
2199
2200                 case SEC_PUK1_VERIFY:
2201                 case SEC_PUK2_VERIFY:
2202                 {
2203                         struct tresp_sim_verify_puks v_puk = {0, };
2204
2205                         v_puk.result = SIM_INCORRECT_PASSWORD;
2206                         v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2207                         v_puk.retry_count = attempts_left;
2208                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2209                                                                                          sizeof(struct tresp_sim_verify_puks), &v_puk);
2210                 }
2211                 break;
2212
2213                 case SEC_PIN1_CHANGE:
2214                 case SEC_PIN2_CHANGE:
2215                 {
2216                         struct tresp_sim_change_pins change_pin = {0, };
2217
2218                         change_pin.result = SIM_INCORRECT_PASSWORD;
2219                         change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2220                         change_pin.retry_count = attempts_left;
2221                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2222                                                                                          sizeof(struct tresp_sim_change_pins), &change_pin);
2223                 }
2224                 break;
2225
2226                 case SEC_PIN1_DISABLE:
2227                 case SEC_PIN2_DISABLE:
2228                 case SEC_FDN_DISABLE:
2229                 case SEC_SIM_DISABLE:
2230                 case SEC_NET_DISABLE:
2231                 case SEC_NS_DISABLE:
2232                 case SEC_SP_DISABLE:
2233                 case SEC_CP_DISABLE:
2234                 {
2235                         struct tresp_sim_disable_facility dis_facility = {0, };
2236
2237                         dis_facility.result = SIM_INCORRECT_PASSWORD;
2238                         dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2239                         dis_facility.retry_count = attempts_left;
2240                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2241                                                                                          sizeof(struct tresp_sim_disable_facility), &dis_facility);
2242                 }
2243                 break;
2244
2245                 case SEC_PIN1_ENABLE:
2246                 case SEC_PIN2_ENABLE:
2247                 case SEC_FDN_ENABLE:
2248                 case SEC_SIM_ENABLE:
2249                 case SEC_NET_ENABLE:
2250                 case SEC_NS_ENABLE:
2251                 case SEC_SP_ENABLE:
2252                 case SEC_CP_ENABLE:
2253                 {
2254                         struct tresp_sim_enable_facility en_facility = {0, };
2255
2256                         en_facility.result = SIM_INCORRECT_PASSWORD;
2257                         en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2258                         en_facility.retry_count = attempts_left;
2259                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2260                                                                                          sizeof(struct tresp_sim_enable_facility), &en_facility);
2261                 }
2262                 break;
2263
2264                 default:
2265                         dbg("not handled sec op[%d]", sp->current_sec_op);
2266                 break;
2267                 }
2268
2269                 /* Free tokens */
2270                 tcore_at_tok_free(tokens);
2271         }
2272
2273         dbg("Exit");
2274 }
2275
2276 static gboolean _get_sim_type(CoreObject *o)
2277 {
2278         TcoreHal *hal = NULL;
2279         TcoreATRequest *req = NULL;
2280         TcorePending *pending = NULL;
2281         UserRequest *ur = NULL;
2282         char *cmd_str = NULL;
2283
2284         dbg("Entry");
2285
2286         hal = tcore_object_get_hal(o);
2287         pending = tcore_pending_new(o, 0);
2288         if (!pending) {
2289                 err("Pending is NULL");
2290                 return FALSE;
2291         }
2292         cmd_str = g_strdup_printf("AT+XUICC?");
2293         req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2294         if (req == NULL) {
2295                 tcore_pending_free(pending);
2296                 g_free(cmd_str);
2297                 return FALSE;
2298         }
2299         g_free(cmd_str);
2300
2301         dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2302                                 req->cmd, req->prefix, strlen(req->cmd));
2303
2304         tcore_pending_set_request_data(pending, 0, req);
2305         tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2306         tcore_pending_link_user_request(pending, ur);
2307         tcore_hal_send_request(hal, pending);
2308
2309         dbg("Exit");
2310         return TRUE;
2311 }
2312
2313 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2314 {
2315         TcoreHal *hal = NULL;
2316         TcorePending *pending = NULL;
2317         struct imc_sim_property meta_info = {0, };
2318         char *cmd_str = NULL;
2319         TReturn ret = TCORE_RETURN_FAILURE;
2320         int trt = 0;
2321
2322         dbg("Entry");
2323
2324         meta_info.file_id = ef;
2325         dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2326         hal = tcore_object_get_hal(o);
2327         dbg("hal: %x", hal);
2328
2329         trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2330         dbg("trt[%d]", trt);
2331         cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef);      /*command - 192 : GET RESPONSE*/
2332         dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2333
2334         pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2335         tcore_pending_link_user_request(pending, ur);
2336         ret = tcore_hal_send_request(hal, pending);
2337         if (TCORE_RETURN_SUCCESS != ret)
2338                 tcore_user_request_free(ur);
2339
2340         g_free(cmd_str);
2341         dbg("Exit");
2342         return TCORE_RETURN_SUCCESS;
2343 }
2344
2345 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2346 {
2347         TcoreHal *hal = NULL;
2348         TcoreATRequest *req = NULL;
2349         TcorePending *pending = NULL;
2350         char *cmd_str = NULL;
2351         int p1 = 0;
2352         int p2 = 0;
2353         int p3 = 0;
2354
2355         dbg("Entry");
2356         hal = tcore_object_get_hal(o);
2357         pending = tcore_pending_new(o, 0);
2358         if (!pending) {
2359                 err("Pending is NULL");
2360                 return FALSE;
2361         }
2362
2363         dbg("file_id: %x", ef);
2364
2365         p1 = (unsigned char) (offset & 0xFF00) >> 8;
2366         p2 = (unsigned char) offset & 0x00FF; /* offset low */
2367         p3 = (unsigned char) length;
2368
2369         cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3);     /*command - 176 : READ BINARY*/
2370
2371         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2372         if (req == NULL) {
2373                 tcore_pending_free(pending);
2374                 g_free(cmd_str);
2375                 return FALSE;
2376         }
2377         g_free(cmd_str);
2378
2379         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2380                                 req->cmd, req->prefix, strlen(req->cmd));
2381
2382         tcore_pending_set_request_data(pending, 0, req);
2383         tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2384         tcore_pending_link_user_request(pending, ur);
2385         tcore_hal_send_request(hal, pending);
2386
2387         dbg("Exit");
2388         return TRUE;
2389 }
2390
2391 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2392 {
2393         TcoreHal *hal = NULL;
2394         TcoreATRequest *req = NULL;
2395         TcorePending *pending = NULL;
2396         char *cmd_str = NULL;
2397         int p1 = 0;
2398         int p2 = 0;
2399         int p3 = 0;
2400
2401         dbg("Entry");
2402
2403         hal = tcore_object_get_hal(o);
2404         pending = tcore_pending_new(o, 0);
2405         if (!pending) {
2406                 err("Pending is NULL");
2407                 return FALSE;
2408         }
2409
2410         p1 = (unsigned char) index;
2411         p2 = (unsigned char) 0x04;    /* 0x4 for absolute mode */
2412         p3 = (unsigned char) length;
2413
2414         cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3);     /*command - 178 : READ RECORD*/
2415
2416         req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2417         if (req == NULL) {
2418                 tcore_pending_free(pending);
2419                 g_free(cmd_str);
2420                 return FALSE;
2421         }
2422         g_free(cmd_str);
2423
2424         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2425                                 req->cmd, req->prefix, strlen(req->cmd));
2426
2427         tcore_pending_set_request_data(pending, 0, req);
2428         tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2429         tcore_pending_link_user_request(pending, ur);
2430         tcore_hal_send_request(hal, pending);
2431
2432         dbg("Exit");
2433         return TRUE;
2434 }
2435
2436 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2437 {
2438         TcoreHal *hal = NULL;
2439         TcoreATRequest *req = NULL;
2440         TcorePending *pending = NULL;
2441         char *cmd_str = NULL;
2442         int lock_type = 0;
2443         struct imc_sim_property *sp = NULL;
2444
2445         dbg("Entry");
2446
2447         hal = tcore_object_get_hal(o);
2448         pending = tcore_pending_new(o, 0);
2449         if (!pending) {
2450                 err("Pending is NULL");
2451                 return TCORE_RETURN_FAILURE;
2452         }
2453         sp = tcore_sim_ref_userdata(o);
2454         if (!sp) {
2455                 err("user data is null");
2456                 tcore_pending_free(pending);
2457                 return TCORE_RETURN_FAILURE;
2458         }
2459
2460         switch (sp->current_sec_op) {
2461         case SEC_PIN1_VERIFY:
2462         case SEC_PIN1_CHANGE:
2463         case SEC_PIN1_ENABLE:
2464         case SEC_PIN1_DISABLE:
2465                 lock_type = 1;
2466                 break;
2467
2468         case SEC_PIN2_VERIFY:
2469         case SEC_PIN2_CHANGE:
2470         case SEC_PIN2_ENABLE:
2471         case SEC_PIN2_DISABLE:
2472         case SEC_FDN_ENABLE:
2473         case SEC_FDN_DISABLE:
2474                 lock_type = 2;
2475                 break;
2476
2477         case SEC_PUK1_VERIFY:
2478                 lock_type = 3;
2479                 break;
2480
2481         case SEC_PUK2_VERIFY:
2482                 lock_type = 4;
2483                 break;
2484
2485         case SEC_NET_ENABLE:
2486         case SEC_NET_DISABLE:
2487                 lock_type = 5;
2488                 break;
2489
2490         case SEC_NS_ENABLE:
2491         case SEC_NS_DISABLE:
2492                 lock_type = 6;
2493                 break;
2494
2495         case SEC_SP_ENABLE:
2496         case SEC_SP_DISABLE:
2497                 lock_type = 7;
2498                 break;
2499
2500         case SEC_CP_ENABLE:
2501         case SEC_CP_DISABLE:
2502                 lock_type = 8;
2503                 break;
2504
2505         case SEC_ADM_VERIFY:
2506                 lock_type = 9;
2507                 break;
2508
2509         default:
2510                 break;
2511         }
2512
2513         cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2514         req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2515         if (req == NULL) {
2516                 tcore_pending_free(pending);
2517                 g_free(cmd_str);
2518                 return TCORE_RETURN_FAILURE;
2519         }
2520         g_free(cmd_str);
2521
2522         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2523                                 req->cmd, req->prefix, strlen(req->cmd));
2524
2525         tcore_pending_set_request_data(pending, 0, req);
2526         tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2527         tcore_pending_link_user_request(pending, ur);
2528         tcore_hal_send_request(hal, pending);
2529
2530         dbg("Exit");
2531         return TCORE_RETURN_SUCCESS;
2532 }
2533
2534 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2535 {
2536         char *line = NULL;
2537         GSList *tokens = NULL;
2538         GSList *lines = NULL;
2539
2540         dbg("Function entry");
2541
2542         lines = (GSList *)event_info;
2543         if (1 != g_slist_length(lines)) {
2544                 dbg("unsolicited msg but multiple line");
2545                 goto OUT;
2546         }
2547         line = (char *)(lines->data);
2548         tokens = tcore_at_tok_new(line);
2549         if (g_slist_length(tokens) != 1) {
2550                 msg("Invalid message");
2551                 tcore_at_tok_free(tokens);
2552                 return TRUE;
2553         }
2554
2555 OUT:
2556         dbg("Exit");
2557         if (NULL != tokens)
2558                 tcore_at_tok_free(tokens);
2559         return TRUE;
2560 }
2561
2562 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2563                                 unsigned int sms_ready)
2564 {
2565         Server *server = tcore_plugin_ref_server(plugin);
2566         struct tnoti_sms_ready_status sms_ready_noti;
2567         CoreObject *co_sms;
2568
2569         dbg("Entry");
2570
2571         co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2572         if (co_sms == NULL) {
2573                 err("Can't find SMS core object");
2574                 return;
2575         }
2576
2577         if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2578                 return;
2579
2580         tcore_sms_set_ready_status(co_sms, sms_ready);
2581
2582         if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2583                 sms_ready_noti.status = sms_ready;
2584                 tcore_server_send_notification(server, co_sms,
2585                                                 TNOTI_SMS_DEVICE_READY,
2586                                                 sizeof(sms_ready_noti),
2587                                                 &sms_ready_noti);
2588         }
2589
2590         dbg("Exit");
2591 }
2592
2593 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2594 {
2595         TcorePlugin *plugin = tcore_object_ref_plugin(o);
2596         enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2597         GSList *tokens = NULL;
2598         GSList *lines;
2599         const char *line;
2600         int sim_state = 0;
2601         enum telephony_sms_ready_status sms_state = 0;
2602
2603         dbg("Entry");
2604
2605         lines = (GSList *)event_info;
2606         if (g_slist_length(lines) != 1) {
2607                 err("Unsolicited message BUT multiple lines");
2608                 goto out;
2609         }
2610
2611         line = lines->data;
2612
2613         /* Create 'tokens' */
2614         tokens = tcore_at_tok_new(line);
2615
2616         /* SIM State */
2617         if (g_slist_length(tokens) == 4) {
2618                 sim_state = atoi(g_slist_nth_data(tokens, 1));
2619                 sms_state = atoi(g_slist_nth_data(tokens, 3));
2620
2621                 notify_sms_state(plugin, o, sms_state);
2622         } else if (g_slist_length(tokens) == 1) {
2623                 sim_state = atoi(g_slist_nth_data(tokens, 0));
2624         } else {
2625                 err("Invalid message");
2626                 goto out;
2627         }
2628
2629         switch (sim_state) {
2630         case 0:
2631                 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2632                 dbg("NO SIM");
2633                 break;
2634
2635         case 1:
2636                 sim_status = SIM_STATUS_PIN_REQUIRED;
2637                 dbg("PIN REQUIRED");
2638                 break;
2639
2640         case 2:
2641                 sim_status = SIM_STATUS_INITIALIZING;
2642                 dbg("PIN DISABLED AT BOOT UP");
2643                 break;
2644
2645         case 3:
2646                 sim_status = SIM_STATUS_INITIALIZING;
2647                 dbg("PIN VERIFIED");
2648                 break;
2649
2650         case 4:
2651                 sim_status = SIM_STATUS_PUK_REQUIRED;
2652                 dbg("PUK REQUIRED");
2653                 break;
2654
2655         case 5:
2656                 sim_status = SIM_STATUS_CARD_BLOCKED;
2657                 dbg("CARD PERMANENTLY BLOCKED");
2658                 break;
2659
2660         case 6:
2661                 sim_status = SIM_STATUS_CARD_ERROR;
2662                 dbg("SIM CARD ERROR");
2663                 break;
2664
2665         case 7:
2666                 sim_status = SIM_STATUS_INIT_COMPLETED;
2667                 dbg("SIM INIT COMPLETED");
2668                 break;
2669
2670         case 8:
2671                 sim_status = SIM_STATUS_CARD_ERROR;
2672                 dbg("SIM CARD ERROR");
2673                 break;
2674
2675         case 9:
2676                 sim_status = SIM_STATUS_CARD_REMOVED;
2677                 dbg("SIM REMOVED");
2678                 break;
2679
2680         case 12:
2681                 dbg("SIM SMS Ready");
2682                 notify_sms_state(plugin, o, SMS_STATE_READY);
2683                 goto out;
2684
2685         case 99:
2686                 sim_status = SIM_STATUS_UNKNOWN;
2687                 dbg("SIM STATE UNKNOWN");
2688                 break;
2689
2690         default:
2691                 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2692                 goto out;
2693         }
2694
2695         switch (sim_status) {
2696         case SIM_STATUS_INIT_COMPLETED:
2697                 dbg("[SIM] SIM INIT COMPLETED");
2698                 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2699                         _get_sim_type(o);
2700                         goto out;
2701                 }
2702
2703                 break;
2704
2705         case SIM_STATUS_CARD_REMOVED:
2706                 dbg("[SIM] SIM CARD REMOVED");
2707                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2708                 break;
2709
2710         case SIM_STATUS_CARD_NOT_PRESENT:
2711                 dbg("[SIM] SIM CARD NOT PRESENT");
2712                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2713                 break;
2714
2715         case SIM_STATUS_CARD_ERROR:
2716                 dbg("[SIM] SIM CARD ERROR");
2717                 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2718                 break;
2719
2720         default:
2721                 dbg("SIM Status: [0x%02x]", sim_status);
2722                 break;
2723         }
2724
2725         _sim_status_update(o, sim_status);
2726
2727 out:
2728         tcore_at_tok_free(tokens);
2729
2730         dbg("Exit");
2731         return TRUE;
2732 }
2733
2734 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2735 {
2736         const TcoreATResponse *resp = data;
2737         CoreObject *o = NULL;
2738
2739         dbg("Entry");
2740
2741         o = tcore_pending_ref_core_object(p);
2742
2743         if (resp->success > 0) {
2744                 dbg("RESPONSE OK");
2745                 if (resp->lines)
2746                         on_event_pin_status(o, resp->lines, NULL);
2747         } else {
2748                 dbg("RESPONSE NOK");
2749         }
2750
2751         dbg("Exit");
2752 }
2753
2754 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2755                                                                                           unsigned int data_len, void *data, void *user_data)
2756 {
2757         TcorePlugin *plugin = tcore_object_ref_plugin(source);
2758         CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2759
2760         if (o == NULL)
2761                 return TCORE_HOOK_RETURN_CONTINUE;
2762
2763         dbg("Get SIM status");
2764
2765         sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2766
2767         return TCORE_HOOK_RETURN_CONTINUE;
2768 }
2769
2770 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2771 {
2772         const TcoreATResponse *resp = data;
2773         UserRequest *ur = NULL;
2774         CoreObject *co_sim = NULL;
2775         struct imc_sim_property *sp = NULL;
2776         GSList *tokens = NULL;
2777         struct tresp_sim_verify_pins res;
2778         const char *line;
2779         int err;
2780
2781         dbg("Entry");
2782
2783         co_sim = tcore_pending_ref_core_object(p);
2784         sp = tcore_sim_ref_userdata(co_sim);
2785         if (!sp) {
2786                 err("user data is null");
2787                 return;
2788         }
2789
2790         ur = tcore_pending_ref_user_request(p);
2791
2792         memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2793
2794         if (resp->success > 0) {
2795                 dbg("RESPONSE OK");
2796                 res.result = SIM_PIN_OPERATION_SUCCESS;
2797
2798                 /* Get PIN facility */
2799                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2800                 if ((res.pin_type == SIM_PTYPE_PIN1)
2801                                 || (res.pin_type == SIM_PTYPE_SIM)) {
2802                         if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2803                                 /* Update SIM Status */
2804                                 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2805                         }
2806                 }
2807
2808                 /* Send Response */
2809                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2810                                         sizeof(struct tresp_sim_verify_pins), &res);
2811         } else {
2812                 dbg("RESPONSE NOK");
2813                 line = (const char *)resp->final_response;
2814                 tokens = tcore_at_tok_new(line);
2815                 if (g_slist_length(tokens) < 1) {
2816                         dbg("Unkown Error OR String corrupted");
2817                         res.result = TCORE_RETURN_3GPP_ERROR;
2818
2819                         /* Send Response */
2820                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2821                                                                 sizeof(struct tresp_sim_verify_pins), &res);
2822                 } else {
2823                         err = atoi(g_slist_nth_data(tokens, 0));
2824                         dbg("Error: [%d]", err);
2825
2826                         ur = tcore_user_request_ref(ur);
2827
2828                         /* Get retry count */
2829                         _get_retry_count(co_sim, ur);
2830                 }
2831
2832                 /* Free tokens */
2833                 tcore_at_tok_free(tokens);
2834         }
2835
2836         dbg("Exit");
2837 }
2838
2839 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2840 {
2841         const TcoreATResponse *resp = data;
2842         UserRequest *ur = NULL;
2843         CoreObject *co_sim = NULL;
2844         struct imc_sim_property *sp = NULL;
2845         GSList *tokens = NULL;
2846         struct tresp_sim_verify_puks res;
2847         const char *line;
2848         int err;
2849
2850         dbg("Entry");
2851
2852         co_sim = tcore_pending_ref_core_object(p);
2853         sp = tcore_sim_ref_userdata(co_sim);
2854         if (!sp) {
2855                 err("user data is null");
2856                 return;
2857         }
2858
2859         ur = tcore_pending_ref_user_request(p);
2860
2861         memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2862
2863         if (resp->success > 0) {
2864                 dbg("RESPONSE OK");
2865                 res.result = SIM_PIN_OPERATION_SUCCESS;
2866                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2867
2868                 /* Send Response */
2869                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2870                                                         sizeof(struct tresp_sim_verify_pins), &res);
2871         } else {
2872                 dbg("RESPONSE NOK");
2873                 line = (const char *)resp->final_response;
2874                 tokens = tcore_at_tok_new(line);
2875
2876                 if (g_slist_length(tokens) < 1) {
2877                         dbg("Unkown Error OR String corrupted");
2878                         res.result = TCORE_RETURN_3GPP_ERROR;
2879
2880                         /* Send Response */
2881                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2882                                                         sizeof(struct tresp_sim_verify_pins), &res);
2883                 } else {
2884                         err = atoi(g_slist_nth_data(tokens, 0));
2885                         dbg("Error: [%d]", err);
2886                         ur = tcore_user_request_ref(ur);
2887                         _get_retry_count(co_sim, ur);
2888                 }
2889                 tcore_at_tok_free(tokens);
2890         }
2891         dbg("Exit");
2892 }
2893
2894 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2895 {
2896         const TcoreATResponse *resp = data;
2897         UserRequest *ur = NULL;
2898         CoreObject *co_sim = NULL;
2899         struct imc_sim_property *sp = NULL;
2900         GSList *tokens = NULL;
2901         struct tresp_sim_change_pins res;
2902         const char *line;
2903         int err;
2904
2905         dbg("Entry");
2906
2907         co_sim = tcore_pending_ref_core_object(p);
2908         sp = tcore_sim_ref_userdata(co_sim);
2909         if (!sp) {
2910                 err("user data is null");
2911                 return;
2912         }
2913
2914         ur = tcore_pending_ref_user_request(p);
2915
2916         memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2917
2918         if (resp->success > 0) {
2919                 dbg("RESPONSE OK");
2920                 res.result = SIM_PIN_OPERATION_SUCCESS;
2921                 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2922
2923                 /* Send Response */
2924                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2925                                                         sizeof(struct tresp_sim_change_pins), &res);
2926         } else {
2927                 dbg("RESPONSE NOK");
2928                 line = (const char *)resp->final_response;
2929                 tokens = tcore_at_tok_new(line);
2930
2931                 if (g_slist_length(tokens) < 1) {
2932                         dbg("Unkown Error OR String corrupted");
2933                         res.result = TCORE_RETURN_3GPP_ERROR;
2934
2935                         /* Send Response */
2936                         tcore_user_request_send_response(ur, _find_resp_command(ur),
2937                                                         sizeof(struct tresp_sim_change_pins), &res);
2938                 } else {
2939                         err = atoi(g_slist_nth_data(tokens, 0));
2940                         dbg("Error: [%d]", err);
2941                         ur = tcore_user_request_ref(ur);
2942                         _get_retry_count(co_sim, ur);
2943                 }
2944
2945                 /* Free tokens */
2946                 tcore_at_tok_free(tokens);
2947         }
2948         dbg("Exit");
2949 }
2950
2951 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2952 {
2953         const TcoreATResponse *resp = data;
2954         UserRequest *ur = NULL;
2955         GSList *tokens = NULL;
2956         struct tresp_sim_get_facility_status *res = user_data;
2957         const char *line;
2958
2959         dbg("Entry");
2960
2961         ur = tcore_pending_ref_user_request(p);
2962
2963         res->result = SIM_PIN_OPERATION_SUCCESS;
2964
2965         if (resp->success > 0) {
2966                 dbg("RESPONSE OK");
2967                 if (resp->lines) {
2968                         line = (const char *)resp->lines->data;
2969                         tokens = tcore_at_tok_new(line);
2970                         if (g_slist_length(tokens) != 1) {
2971                                 msg("Invalid message");
2972                                 tcore_at_tok_free(tokens);
2973                                 return;
2974                         }
2975                 }
2976                 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2977         } else {
2978                 dbg("RESPONSE NOK");
2979                 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2980         }
2981
2982         /* Send Response */
2983         if (ur) {
2984                 tcore_user_request_send_response(ur, _find_resp_command(ur),
2985                                                 sizeof(struct tresp_sim_get_facility_status), res);
2986         }
2987         tcore_at_tok_free(tokens);
2988         g_free(res);
2989         dbg("Exit");
2990 }
2991
2992 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2993 {
2994         const TcoreATResponse *resp = data;
2995         UserRequest *ur = NULL;
2996         CoreObject *co_sim = NULL;
2997         struct imc_sim_property *sp = NULL;
2998         GSList *tokens = NULL;
2999         struct tresp_sim_enable_facility res;
3000         const char *line;
3001
3002         dbg("Entry");
3003
3004         co_sim = tcore_pending_ref_core_object(p);
3005         sp = tcore_sim_ref_userdata(co_sim);
3006         if (!sp) {
3007                 err("user data is null");
3008                 return;
3009         }
3010
3011         ur = tcore_pending_ref_user_request(p);
3012
3013         memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
3014
3015         res.result = SIM_CARD_ERROR;
3016         res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3017
3018         if (resp->success > 0) {
3019                 dbg("RESPONSE OK");
3020                 if (resp->lines) {
3021                         line = (const char *)resp->lines->data;
3022                         tokens = tcore_at_tok_new(line);
3023                         if (g_slist_length(tokens) != 1) {
3024                                 msg("Invalid message");
3025
3026                                 /* Send Response */
3027                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3028                                                                          sizeof(struct tresp_sim_enable_facility), &res);
3029                                 tcore_at_tok_free(tokens);
3030                                 return;
3031                         }
3032                 }
3033
3034                 res.result = SIM_PIN_OPERATION_SUCCESS;
3035
3036                 /* Send Response */
3037                 if (ur) {
3038                         tcore_user_request_send_response(ur, _find_resp_command(ur),
3039                                                                  sizeof(struct tresp_sim_enable_facility), &res);
3040                 }
3041
3042                 /* Free tokens */
3043                 tcore_at_tok_free(tokens);
3044         } else {
3045                 dbg("RESPONSE NOK");
3046                 ur = tcore_user_request_ref(ur);
3047                 _get_retry_count(co_sim, ur);
3048         }
3049         dbg("Exit");
3050 }
3051
3052 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
3053 {
3054         const TcoreATResponse *resp = data;
3055         UserRequest *ur = NULL;
3056         CoreObject *co_sim = NULL;
3057         struct imc_sim_property *sp = NULL;
3058         GSList *tokens = NULL;
3059         struct tresp_sim_disable_facility res;
3060         const char *line;
3061
3062         dbg("Entry");
3063
3064         co_sim = tcore_pending_ref_core_object(p);
3065         sp = tcore_sim_ref_userdata(co_sim);
3066         if (!sp) {
3067                 err("user data is null");
3068                 return;
3069         }
3070
3071         ur = tcore_pending_ref_user_request(p);
3072
3073         memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
3074
3075         res.result = SIM_CARD_ERROR;
3076         res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3077
3078         if (resp->success > 0) {
3079                 dbg("RESPONSE OK");
3080                 if (resp->lines) {
3081                         line = (const char *)resp->lines->data;
3082                         tokens = tcore_at_tok_new(line);
3083                         if (g_slist_length(tokens) != 1) {
3084                                 msg("Invalid message");
3085
3086                                 /* Send Response */
3087                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3088                                                                                 sizeof(struct tresp_sim_disable_facility), &res);
3089                                 tcore_at_tok_free(tokens);
3090                                 return;
3091                         }
3092                 }
3093
3094                 res.result = SIM_PIN_OPERATION_SUCCESS;
3095                 /* Send Response */
3096                 if (ur)
3097                         tcore_user_request_send_response(ur, _find_resp_command(ur),
3098                                                                         sizeof(struct tresp_sim_disable_facility), &res);
3099
3100                 /* Free tokens */
3101                 tcore_at_tok_free(tokens);
3102         } else {
3103                 dbg("RESPONSE NOK");
3104                 ur = tcore_user_request_ref(ur);
3105                 _get_retry_count(co_sim, ur);
3106         }
3107         dbg("Exit");
3108 }
3109
3110 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
3111 {
3112         const TcoreATResponse *response = (TcoreATResponse *)data;
3113         UserRequest *ur = NULL;
3114         GSList *tokens = NULL;
3115         struct treq_sim_get_lock_info *req_data = NULL;
3116         struct tresp_sim_get_lock_info resp;
3117         const char *line;
3118         int pin1_attempts_left = 0;
3119         int puk1_attempts_left = 0;
3120         int pin2_attempts_left = 0;
3121         int puk2_attempts_left = 0;
3122         int length_tokens = 0;
3123
3124         dbg("Entry");
3125
3126         memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3127
3128         ur = tcore_pending_ref_user_request(p);
3129
3130         if (!ur || !response) {
3131                 err("NULL data : ur[%p], response[%p]", ur, response);
3132                 resp.result = SIM_CARD_ERROR;
3133                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3134                                                 sizeof(struct tresp_sim_get_lock_info), &resp);
3135                 return;
3136         }
3137
3138         req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3139
3140         resp.result = SIM_PIN_OPERATION_SUCCESS;
3141         resp.type = req_data->type;
3142
3143         if (response->success > 0) {
3144                 dbg("RESPONSE OK");
3145                 if (response->lines) {
3146                         line = (const char *)response->lines->data;
3147                         tokens = tcore_at_tok_new(line);
3148                         length_tokens = g_slist_length(tokens);
3149                         dbg("No of Tokens [%d]", length_tokens);
3150                         switch (length_tokens) {
3151                         case 4:
3152                                 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3153                         case 3:
3154                                 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3155                         case 2:
3156                                 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3157                         case 1:
3158                                 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3159                         break;
3160
3161                         default:
3162                                 err("Invalid response");
3163                                 tcore_at_tok_free(tokens);
3164                                 resp.result = SIM_CARD_ERROR;
3165                                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3166                                                                 sizeof(struct tresp_sim_get_lock_info), &resp);
3167                                 return;
3168                         }
3169
3170
3171                         dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3172                                                 pin1_attempts_left, puk1_attempts_left);
3173                         dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3174                                                 pin2_attempts_left, puk2_attempts_left);
3175
3176                         resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3177
3178                         switch (resp.type) {
3179                         case SIM_FACILITY_SC:
3180                                 resp.retry_count = pin1_attempts_left;
3181                                 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3182                                         resp.lock_status = SIM_LOCK_STATUS_PIN;
3183                                 } else if (pin1_attempts_left == 0) {
3184                                         if (puk1_attempts_left) {
3185                                                 resp.lock_status = SIM_LOCK_STATUS_PUK;
3186                                                 resp.retry_count = puk1_attempts_left;
3187                                         } else {
3188                                                 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3189                                         }
3190                                 }
3191                         break;
3192
3193                         case SIM_FACILITY_FD:
3194                                 resp.retry_count = pin2_attempts_left;
3195                                 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3196                                         resp.lock_status = SIM_LOCK_STATUS_PIN2;
3197                                 } else if (pin2_attempts_left == 0) {
3198                                         if (puk2_attempts_left) {
3199                                                 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3200                                                 resp.retry_count = puk2_attempts_left;
3201                                         } else {
3202                                                 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3203                                         }
3204                                 }
3205                         break;
3206
3207                         default:
3208                                 err("Unhandled facility type : [%d]", resp.type);
3209                         break;
3210                         }
3211                         dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3212                         tcore_at_tok_free(tokens);
3213                 }
3214         } else {
3215                 err("RESPONSE NOK");
3216                 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3217         }
3218
3219         /* Send Response */
3220         tcore_user_request_send_response(ur, _find_resp_command(ur),
3221                                         sizeof(struct tresp_sim_get_lock_info), &resp);
3222 }
3223
3224 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
3225 {
3226         UserRequest *ur = NULL;
3227         GSList *tokens = NULL;
3228         const char *line = NULL;
3229         const TcoreATResponse *response = (TcoreATResponse *)data;
3230         CoreObject *co_sim = NULL;
3231         struct imc_sim_property *meta_info = NULL;
3232         struct tresp_sim_set_data resp;
3233         int sw1 = 0;
3234         int sw2 = 0;
3235         gboolean cphs_sim = FALSE;
3236         enum tcore_request_command command;
3237         dbg("Entry");
3238
3239         memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3240
3241         ur = tcore_pending_ref_user_request(p);
3242         command = tcore_user_request_get_command(ur);
3243         co_sim = tcore_pending_ref_core_object(p);
3244         cphs_sim = tcore_sim_get_cphs_status(co_sim);
3245         meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3246
3247         if (!ur || !co_sim || !meta_info || !response) {
3248                 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3249                 resp.result = SIM_CARD_ERROR;
3250                 goto EXIT;
3251         } else {
3252                 if (response->success > 0) {
3253                         dbg("RESPONSE OK");
3254                         if (response->lines) {
3255                                 line = (const char *)response->lines->data;
3256                                 tokens = tcore_at_tok_new(line);
3257                                 if (g_slist_length(tokens) < 2) {
3258                                         err("Invalid response");
3259                                         resp.result = SIM_CARD_ERROR;
3260                                 } else {
3261                                         sw1 = atoi(g_slist_nth_data(tokens, 0));
3262                                         sw2 = atoi(g_slist_nth_data(tokens, 1));
3263
3264                                         if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
3265                                                 resp.result = SIM_ACCESS_SUCCESS;
3266                                         else
3267                                                 resp.result = _decode_status_word(sw1, sw2);
3268                                 }
3269                                 tcore_at_tok_free(tokens);
3270                         }
3271                 } else {
3272                         err("RESPONSE NOK");
3273                         resp.result = SIM_ACCESS_FAILED;
3274                 }
3275         }
3276
3277         if (cphs_sim == FALSE) {
3278                 switch (command) {
3279                 case TREQ_SIM_SET_MAILBOX:
3280                         if (meta_info->file_id == SIM_EF_USIM_MBI) {
3281                                 if (resp.result == SIM_ACCESS_SUCCESS) {
3282                                         ur = tcore_user_request_ref(ur);
3283                                         _get_file_info(co_sim, ur, SIM_EF_MBDN);
3284                                 } else {
3285                                         dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3286                                         memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3287                                         ur = tcore_user_request_ref(ur);
3288                                         _get_file_info(co_sim, ur, SIM_EF_MBDN);
3289                                 }
3290                                 return;
3291                         }
3292                         break;
3293                 default:
3294                         break;
3295                 }
3296         } else {
3297                 switch (command) {
3298                 case TREQ_SIM_SET_MAILBOX:
3299                         if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3300                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3301                                 return;
3302                         }
3303                 break;
3304
3305                 case TREQ_SIM_SET_CALLFORWARDING:
3306                         if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3307                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3308                                 return;
3309                         }
3310                 break;
3311
3312                 case TREQ_SIM_SET_MESSAGEWAITING:
3313                         if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3314                                 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3315                                 return;
3316                         }
3317                 break;
3318
3319                 default:
3320                 break;
3321                 }
3322         }
3323
3324 EXIT:
3325         /* Send Response */
3326         tcore_user_request_send_response(ur, _find_resp_command(ur),
3327                                         sizeof(struct tresp_sim_set_data), &resp);
3328 }
3329
3330 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3331 {
3332         const TcoreATResponse *resp = data;
3333         UserRequest *ur = NULL;
3334         struct tresp_sim_transmit_apdu res;
3335         const char *line;
3336
3337         dbg("Entry");
3338
3339         ur = tcore_pending_ref_user_request(p);
3340
3341         memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3342         res.result = SIM_ACCESS_FAILED;
3343
3344         if (resp->success > 0) {
3345                 dbg("RESPONSE OK");
3346                 if (resp->lines) {
3347                         GSList *tokens = NULL;
3348                         char *tmp = NULL;
3349                         char *decoded_data = NULL;
3350                         line = (const char *)resp->lines->data;
3351                         tokens = tcore_at_tok_new(line);
3352                         if (g_slist_length(tokens) != 2) {
3353                                 msg("Invalid message");
3354                                 tcore_at_tok_free(tokens);
3355                                 res.result = SIM_CARD_ERROR;
3356                                 goto OUT;
3357                         }
3358
3359                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3360                         if (tmp) {
3361                                 decoded_data = util_hexStringToBytes(tmp);
3362                                 if (decoded_data) {
3363                                         res.apdu_resp_length = strlen(tmp) / 2;
3364                                         res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3365                                         if (res.apdu_resp == NULL) {
3366                                                 err("Memory allocation failed!!");
3367                                                 tcore_at_tok_free(tokens);
3368                                                 g_free(tmp);
3369                                                 g_free(decoded_data);
3370                                                 goto OUT;
3371                                         }
3372                                         memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3373                                         g_free(tmp);
3374                                         g_free(decoded_data);
3375                                         res.result = SIM_ACCESS_SUCCESS;
3376                                         tcore_at_tok_free(tokens);
3377                                 } else {
3378                                         err("util_hexStringToBytes Failed!!");
3379                                         g_free(tmp);
3380                                 }
3381                         }
3382                 }
3383         } else {
3384                 dbg("RESPONSE NOK");
3385         }
3386
3387 OUT:
3388         /* Send Response */
3389         if (ur) {
3390                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3391                                                         sizeof(struct tresp_sim_transmit_apdu), &res);
3392         }
3393         dbg("Exit");
3394 }
3395
3396 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3397 {
3398         const TcoreATResponse *resp = data;
3399         UserRequest *ur = NULL;
3400         GSList *tokens = NULL;
3401         struct tresp_sim_get_atr res;
3402         const char *line;
3403
3404         dbg("Entry");
3405
3406         memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3407         ur = tcore_pending_ref_user_request(p);
3408
3409         res.result = SIM_ACCESS_FAILED;
3410         if (resp->success > 0) {
3411                 dbg("RESPONSE OK");
3412                 if (resp->lines) {
3413                         char *tmp = NULL;
3414                         char *decoded_data = NULL;
3415                         line = (const char *)resp->lines->data;
3416                         tokens = tcore_at_tok_new(line);
3417                         if (g_slist_length(tokens) < 1) {
3418                                 msg("Invalid message");
3419                                 goto OUT;
3420                         }
3421
3422                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3423                         if (tmp) {
3424                                 decoded_data = util_hexStringToBytes(tmp);
3425                                 if (!decoded_data) {
3426                                         err("util_hexStringToBytes Failed!!");
3427                                         goto OUT;
3428                                 }
3429
3430                                 res.atr_length = strlen(tmp) / 2;
3431                                 memcpy((char *)res.atr, decoded_data, res.atr_length);
3432                                 g_free(tmp);
3433                                 g_free(decoded_data);
3434                                 res.result = SIM_ACCESS_SUCCESS;
3435                         }
3436                 }
3437         } else {
3438                 dbg("RESPONSE NOK");
3439         }
3440
3441 OUT:
3442         /* Send Response */
3443         if (ur) {
3444                 tcore_user_request_send_response(ur, _find_resp_command(ur),
3445                                                         sizeof(struct tresp_sim_get_atr), &res);
3446         }
3447         tcore_at_tok_free(tokens);
3448         dbg("Exit");
3449 }
3450
3451 static void on_response_req_authentication(TcorePending *p, int data_len,
3452                                         const void *data, void *user_data)
3453 {
3454         const TcoreATResponse *at_resp = data;
3455         GSList *tokens = NULL;
3456         struct tresp_sim_req_authentication resp_auth;
3457         const struct treq_sim_req_authentication *req_data;
3458         UserRequest *ur = tcore_pending_ref_user_request(p);
3459
3460         dbg("Entry");
3461
3462         memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3463
3464         if (at_resp == NULL) {
3465                 err("at_resp is NULL");
3466                 resp_auth.result = SIM_ACCESS_FAILED;
3467                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3468                 goto out;
3469         }
3470
3471         req_data = tcore_user_request_ref_data(ur, NULL);
3472         if (req_data == NULL) {
3473                 err("req_data is NULL");
3474                 resp_auth.result = SIM_ACCESS_FAILED;
3475                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3476                 goto out;
3477         }
3478         resp_auth.auth_type = req_data->auth_type;
3479
3480         if (at_resp->success == TRUE) {
3481                 const char *line;
3482                 int status;
3483
3484                 dbg("RESPONSE OK");
3485                 if (at_resp->lines != NULL) {
3486                         line = at_resp->lines->data;
3487                         dbg("Received data: [%s]", line);
3488                 } else {
3489                         err("at_resp->lines is NULL");
3490                         resp_auth.result = SIM_ACCESS_FAILED;
3491                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3492                         goto out;
3493                 }
3494
3495                 tokens = tcore_at_tok_new(line);
3496                 if (tokens == NULL) {
3497                         err("tokens is NULL");
3498                         resp_auth.result = SIM_ACCESS_FAILED;
3499                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3500                         goto out;
3501                 }
3502
3503                 status = atoi(g_slist_nth_data(tokens, 0));
3504                 switch (status) {
3505                 case 0:
3506                         dbg("Authentications successful");
3507                         resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3508                         break;
3509                 case 1:
3510                         err("Synchronize fail");
3511                         resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3512                         goto out;
3513                 case 2:
3514                         err("MAC wrong");
3515                         resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3516                         goto out;
3517                 case 3:
3518                         err("Does not support security context");
3519                         resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3520                         goto out;
3521                 default:
3522                         err("Other failure");
3523                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3524                         goto out;
3525                 }
3526
3527                 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3528                         char *kc, *sres;
3529                         char *convert_kc, *convert_sres;
3530
3531                         kc = g_slist_nth_data(tokens, 1);
3532                         if (kc != NULL) {
3533                                 kc = tcore_at_tok_extract(kc);
3534                                 dbg("Kc: [%s]", kc);
3535                                 convert_kc = util_hexStringToBytes(kc);
3536                                 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3537                                         resp_auth.authentication_key_length = strlen(convert_kc);
3538                                         memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3539                                 } else {
3540                                         err("Invalid Kc");
3541                                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3542                                 }
3543                                 g_free(kc);
3544                                 g_free(convert_kc);
3545                         }
3546
3547                         sres = g_slist_nth_data(tokens, 2);
3548                         if (sres != NULL) {
3549                                 sres = tcore_at_tok_extract(sres);
3550                                 dbg("SRES: [%s]", sres);
3551                                 convert_sres = util_hexStringToBytes(sres);
3552                                 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3553                                         resp_auth.resp_length = strlen(convert_sres);
3554                                         memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3555                                 } else {
3556                                         err("Invalid SRES");
3557                                         resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3558                                 }
3559                                 g_free(sres);
3560                                 g_free(convert_sres);
3561                         }
3562                 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3563                                 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3564                         /* TODO */
3565                 }
3566         } else {
3567                 err("RESPONSE NOK");
3568                 resp_auth.result = SIM_ACCESS_FAILED;
3569                 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3570         }
3571
3572 out:
3573         tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3574                         sizeof(struct tresp_sim_req_authentication), &resp_auth);
3575
3576         tcore_at_tok_free(tokens);
3577 }
3578
3579 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3580 {
3581         TcoreHal *hal = NULL;
3582         TcoreATRequest *req = NULL;
3583         TcorePending *pending = NULL;
3584         char *cmd_str = NULL;
3585         const struct treq_sim_verify_pins *req_data = NULL;
3586         struct imc_sim_property *sp = NULL;
3587         TReturn ret = TCORE_RETURN_FAILURE;
3588
3589         dbg("Entry");
3590
3591         if ((o == NULL) || (ur == NULL))
3592                 return TCORE_RETURN_EINVAL;
3593
3594         hal = tcore_object_get_hal(o);
3595         if (FALSE == tcore_hal_get_power_state(hal)) {
3596                 err("CP NOT READY");
3597                 return TCORE_RETURN_ENOSYS;
3598         }
3599
3600         sp = tcore_sim_ref_userdata(o);
3601         if (!sp) {
3602                 err("user data is null");
3603                 return TCORE_RETURN_FAILURE;
3604         }
3605
3606         pending = tcore_pending_new(o, 0);
3607         if (!pending) {
3608                 err("Pending is NULL");
3609                 return TCORE_RETURN_FAILURE;
3610         }
3611
3612         req_data = tcore_user_request_ref_data(ur, NULL);
3613
3614         if (req_data->pin_type == SIM_PTYPE_PIN1) {
3615                 sp->current_sec_op = SEC_PIN1_VERIFY;
3616                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3617         } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3618                 sp->current_sec_op = SEC_PIN2_VERIFY;
3619                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3620         } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3621                 sp->current_sec_op = SEC_SIM_VERIFY;
3622                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3623         } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3624                 sp->current_sec_op = SEC_ADM_VERIFY;
3625                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3626         } else {
3627                 tcore_pending_free(pending);
3628                 return TCORE_RETURN_EINVAL;
3629         }
3630
3631         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3632         if (req == NULL) {
3633                 tcore_pending_free(pending);
3634                 g_free(cmd_str);
3635                 return TCORE_RETURN_FAILURE;
3636         }
3637         g_free(cmd_str);
3638
3639         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3640                                 req->cmd, req->prefix, strlen(req->cmd));
3641
3642         tcore_pending_set_request_data(pending, 0, req);
3643         tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3644         tcore_pending_link_user_request(pending, ur);
3645         ret = tcore_hal_send_request(hal, pending);
3646
3647         dbg("Exit");
3648         return ret;
3649 }
3650
3651 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3652 {
3653         TcoreHal *hal = NULL;
3654         TcoreATRequest *req = NULL;
3655         TcorePending *pending = NULL;
3656         char *cmd_str = NULL;
3657         const struct treq_sim_verify_puks *req_data;
3658         struct imc_sim_property *sp = NULL;
3659         TReturn ret = TCORE_RETURN_FAILURE;
3660
3661         dbg("Entry");
3662
3663         if ((o == NULL) || (ur == NULL))
3664                 return TCORE_RETURN_EINVAL;
3665
3666         hal = tcore_object_get_hal(o);
3667         if (FALSE == tcore_hal_get_power_state(hal)) {
3668                 err("CP NOT READY");
3669                 return TCORE_RETURN_ENOSYS;
3670         }
3671
3672         sp = tcore_sim_ref_userdata(o);
3673         if (!sp) {
3674                 err("user data is null");
3675                 return TCORE_RETURN_FAILURE;
3676         }
3677
3678         pending = tcore_pending_new(o, 0);
3679         if (!pending) {
3680                 err("Pending is NULL");
3681                 return TCORE_RETURN_FAILURE;
3682         }
3683
3684         req_data = tcore_user_request_ref_data(ur, NULL);
3685
3686         if (req_data->puk_type == SIM_PTYPE_PUK1) {
3687                 sp->current_sec_op = SEC_PUK1_VERIFY;
3688                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3689         } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3690                 sp->current_sec_op = SEC_PUK2_VERIFY;
3691                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3692         } else {
3693                 tcore_pending_free(pending);
3694                 return TCORE_RETURN_EINVAL;
3695         }
3696
3697         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3698         if (req == NULL) {
3699                 tcore_pending_free(pending);
3700                 g_free(cmd_str);
3701                 return TCORE_RETURN_FAILURE;
3702         }
3703         g_free(cmd_str);
3704
3705         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3706                                 req->cmd, req->prefix, strlen(req->cmd));
3707
3708         tcore_pending_set_request_data(pending, 0, req);
3709         tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3710         tcore_pending_link_user_request(pending, ur);
3711         ret = tcore_hal_send_request(hal, pending);
3712
3713         dbg("Exit");
3714         return ret;
3715 }
3716
3717 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3718 {
3719         TcoreHal *hal = NULL;
3720         TcoreATRequest *req = NULL;
3721         TcorePending *pending = NULL;
3722         char *cmd_str = NULL;
3723         const struct treq_sim_change_pins *req_data;
3724         struct imc_sim_property *sp = NULL;
3725         char *pin1 = "SC";
3726         char *pin2 = "P2";
3727         TReturn ret = TCORE_RETURN_FAILURE;
3728
3729         dbg("Entry");
3730
3731         if ((o == NULL) || (ur == NULL))
3732                 return TCORE_RETURN_EINVAL;
3733
3734         hal = tcore_object_get_hal(o);
3735         if (FALSE == tcore_hal_get_power_state(hal)) {
3736                 err("CP NOT READY");
3737                 return TCORE_RETURN_ENOSYS;
3738         }
3739
3740         sp = tcore_sim_ref_userdata(o);
3741         if (!sp) {
3742                 err("user data is null");
3743                 return TCORE_RETURN_FAILURE;
3744         }
3745
3746         pending = tcore_pending_new(o, 0);
3747         if (!pending) {
3748                 err("Pending is NULL");
3749                 return TCORE_RETURN_FAILURE;
3750         }
3751
3752         req_data = tcore_user_request_ref_data(ur, NULL);
3753
3754         if (req_data->type == SIM_PTYPE_PIN1) {
3755                 sp->current_sec_op = SEC_PIN1_CHANGE;
3756                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3757         } else if (req_data->type == SIM_PTYPE_PIN2) {
3758                 sp->current_sec_op = SEC_PIN2_CHANGE;
3759                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3760         } else {
3761                 tcore_pending_free(pending);
3762                 return TCORE_RETURN_EINVAL;
3763         }
3764         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3765         if (req == NULL) {
3766                 tcore_pending_free(pending);
3767                 g_free(cmd_str);
3768                 return TCORE_RETURN_FAILURE;
3769         }
3770         g_free(cmd_str);
3771
3772         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3773                                 req->cmd, req->prefix, strlen(req->cmd));
3774
3775         tcore_pending_set_request_data(pending, 0, req);
3776         tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3777         tcore_pending_link_user_request(pending, ur);
3778         ret = tcore_hal_send_request(hal, pending);
3779
3780         dbg("Exit");
3781         return ret;
3782 }
3783
3784 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3785 {
3786         TcoreHal *hal = NULL;
3787         TcoreATRequest *req = NULL;
3788         TcorePending *pending = NULL;
3789         char *cmd_str = NULL;
3790         const struct treq_sim_get_facility_status *req_data;
3791         struct tresp_sim_get_facility_status *res;
3792         char *fac = "SC";
3793         int mode = 2;    /* 0:unlock, 1:lock, 2:query*/
3794         TReturn ret = TCORE_RETURN_FAILURE;
3795
3796         dbg("Entry");
3797
3798         if ((o == NULL) || (ur == NULL))
3799                 return TCORE_RETURN_EINVAL;
3800
3801         hal = tcore_object_get_hal(o);
3802         if (FALSE == tcore_hal_get_power_state(hal)) {
3803                 err("CP NOT READY");
3804                 return TCORE_RETURN_ENOSYS;
3805         }
3806
3807         pending = tcore_pending_new(o, 0);
3808         if (!pending) {
3809                 err("Pending is NULL");
3810                 return TCORE_RETURN_FAILURE;
3811         }
3812
3813         req_data = tcore_user_request_ref_data(ur, NULL);
3814
3815         res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3816         if (!res) {
3817                 tcore_pending_free(pending);
3818                 return TCORE_RETURN_ENOMEM;
3819         }
3820
3821         res->type = req_data->type;
3822
3823         if (req_data->type == SIM_FACILITY_PS)
3824                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3825         else if (req_data->type == SIM_FACILITY_SC)
3826                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3827         else if (req_data->type == SIM_FACILITY_FD)
3828                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3829         else if (req_data->type == SIM_FACILITY_PN)
3830                 fac = "PN";               /*Network Personalization*/
3831         else if (req_data->type == SIM_FACILITY_PU)
3832                 fac = "PU";               /*network sUbset Personalization*/
3833         else if (req_data->type == SIM_FACILITY_PP)
3834                 fac = "PP";               /*service Provider Personalization*/
3835         else if (req_data->type == SIM_FACILITY_PC)
3836                 fac = "PC";               /*Corporate Personalization*/
3837         else
3838                 return TCORE_RETURN_EINVAL;
3839
3840         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3841         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3842         if (req == NULL) {
3843                 tcore_pending_free(pending);
3844                 g_free(cmd_str);
3845                 return TCORE_RETURN_FAILURE;
3846         }
3847         g_free(cmd_str);
3848
3849         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3850                                 req->cmd, req->prefix, strlen(req->cmd));
3851
3852         tcore_pending_set_request_data(pending, 0, req);
3853         tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3854         tcore_pending_link_user_request(pending, ur);
3855         ret = tcore_hal_send_request(hal, pending);
3856
3857         dbg("Exit");
3858         return ret;
3859 }
3860
3861 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3862 {
3863         TcoreHal *hal = NULL;
3864         TcoreATRequest *req = NULL;
3865         TcorePending *pending = NULL;
3866         char *cmd_str = NULL;
3867         const struct treq_sim_enable_facility *req_data;
3868         struct imc_sim_property *sp = NULL;
3869         char *fac = "SC";
3870         int mode = 1;    /* 0:unlock, 1:lock, 2:query*/
3871         TReturn ret = TCORE_RETURN_FAILURE;
3872
3873         dbg("Entry");
3874
3875         if ((o == NULL) || (ur == NULL))
3876                 return TCORE_RETURN_EINVAL;
3877
3878         hal = tcore_object_get_hal(o);
3879         if (FALSE == tcore_hal_get_power_state(hal)) {
3880                 err("CP NOT READY");
3881                 return TCORE_RETURN_ENOSYS;
3882         }
3883
3884         sp = tcore_sim_ref_userdata(o);
3885         if (!sp) {
3886                 err("user data is null");
3887                 return TCORE_RETURN_FAILURE;
3888         }
3889
3890         pending = tcore_pending_new(o, 0);
3891         if (!pending) {
3892                 err("Pending is NULL");
3893                 return TCORE_RETURN_FAILURE;
3894         }
3895
3896         req_data = tcore_user_request_ref_data(ur, NULL);
3897
3898         if (req_data->type == SIM_FACILITY_PS) {
3899                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3900                 sp->current_sec_op = SEC_SIM_ENABLE;
3901         } else if (req_data->type == SIM_FACILITY_SC) {
3902                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3903                 sp->current_sec_op = SEC_PIN1_ENABLE;
3904         } else if (req_data->type == SIM_FACILITY_FD) {
3905                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3906                 sp->current_sec_op = SEC_FDN_ENABLE;
3907         } else if (req_data->type == SIM_FACILITY_PN) {
3908                 fac = "PN";               /*Network Personalization*/
3909                 sp->current_sec_op = SEC_NET_ENABLE;
3910         } else if (req_data->type == SIM_FACILITY_PU) {
3911                 fac = "PU";               /*network sUbset Personalization*/
3912                 sp->current_sec_op = SEC_NS_ENABLE;
3913         } else if (req_data->type == SIM_FACILITY_PP) {
3914                 fac = "PP";               /*service Provider Personalization*/
3915                 sp->current_sec_op = SEC_SP_ENABLE;
3916         } else if (req_data->type == SIM_FACILITY_PC) {
3917                 fac = "PC";               /*Corporate Personalization*/
3918                 sp->current_sec_op = SEC_CP_ENABLE;
3919         } else {
3920                 return TCORE_RETURN_EINVAL;
3921         }
3922         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3923         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3924         if (req == NULL) {
3925                 tcore_pending_free(pending);
3926                 g_free(cmd_str);
3927                 return TCORE_RETURN_FAILURE;
3928         }
3929         g_free(cmd_str);
3930
3931         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3932                                 req->cmd, req->prefix, strlen(req->cmd));
3933
3934         tcore_pending_set_request_data(pending, 0, req);
3935         tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3936         tcore_pending_link_user_request(pending, ur);
3937         ret = tcore_hal_send_request(hal, pending);
3938
3939         dbg("Exit");
3940         return ret;
3941 }
3942
3943 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3944 {
3945         TcoreHal *hal;
3946         TcoreATRequest *req;
3947         TcorePending *pending = NULL;
3948         char *cmd_str = NULL;
3949         const struct treq_sim_enable_facility *req_data;
3950         struct imc_sim_property *sp = NULL;
3951         char *fac = "SC";
3952         int mode = 0;    /* 0:unlock, 1:lock, 2:query*/
3953         TReturn ret = TCORE_RETURN_FAILURE;
3954
3955         dbg("Entry");
3956
3957         if ((o == NULL) || (ur == NULL))
3958                 return TCORE_RETURN_EINVAL;
3959
3960         hal = tcore_object_get_hal(o);
3961         if (FALSE == tcore_hal_get_power_state(hal)) {
3962                 err("CP NOT READY");
3963                 return TCORE_RETURN_ENOSYS;
3964         }
3965
3966         sp = tcore_sim_ref_userdata(o);
3967         if (!sp) {
3968                 err("user data is null");
3969                 return TCORE_RETURN_FAILURE;
3970         }
3971
3972         pending = tcore_pending_new(o, 0);
3973         if (!pending) {
3974                 err("Pending is NULL");
3975                 return TCORE_RETURN_FAILURE;
3976         }
3977
3978         req_data = tcore_user_request_ref_data(ur, NULL);
3979
3980         if (req_data->type == SIM_FACILITY_PS) {
3981                 fac = "PS";               /*PH-SIM, Lock PHone to SIM/UICC card*/
3982                 sp->current_sec_op = SEC_SIM_DISABLE;
3983         } else if (req_data->type == SIM_FACILITY_SC) {
3984                 fac = "SC";               /*Lock SIM/UICC card, simply PIN1*/
3985                 sp->current_sec_op = SEC_PIN1_DISABLE;
3986         } else if (req_data->type == SIM_FACILITY_FD) {
3987                 fac = "FD";               /*Fixed Dialing Number feature, need PIN2*/
3988                 sp->current_sec_op = SEC_FDN_DISABLE;
3989         } else if (req_data->type == SIM_FACILITY_PN) {
3990                 fac = "PN";               /*Network Personalization*/
3991                 sp->current_sec_op = SEC_NET_DISABLE;
3992         } else if (req_data->type == SIM_FACILITY_PU) {
3993                 fac = "PU";               /*network sUbset Personalization*/
3994                 sp->current_sec_op = SEC_NS_DISABLE;
3995         } else if (req_data->type == SIM_FACILITY_PP) {
3996                 fac = "PP";               /*service Provider Personalization*/
3997                 sp->current_sec_op = SEC_SP_DISABLE;
3998         } else if (req_data->type == SIM_FACILITY_PC) {
3999                 fac = "PC";               /*Corporate Personalization*/
4000                 sp->current_sec_op = SEC_CP_DISABLE;
4001         } else {
4002                 return TCORE_RETURN_EINVAL;
4003         }
4004         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
4005         req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
4006         if (req == NULL) {
4007                 tcore_pending_free(pending);
4008                 g_free(cmd_str);
4009                 return TCORE_RETURN_FAILURE;
4010         }
4011         g_free(cmd_str);
4012
4013         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4014                                 req->cmd, req->prefix, strlen(req->cmd));
4015
4016         tcore_pending_set_request_data(pending, 0, req);
4017         tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
4018         tcore_pending_link_user_request(pending, ur);
4019         ret = tcore_hal_send_request(hal, pending);
4020
4021         dbg("Exit");
4022         return ret;
4023 }
4024
4025 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
4026 {
4027         TcoreHal *hal = NULL;
4028         TcoreATRequest *req = NULL;
4029         TcorePending *pending = NULL;
4030
4031         dbg("Entry");
4032
4033         hal = tcore_object_get_hal(o);
4034         pending = tcore_pending_new(o, 0);
4035         if (!pending) {
4036                 err("Pending is NULL");
4037                 return TCORE_RETURN_FAILURE;
4038         }
4039
4040         if ((o == NULL) || (ur == NULL)) {
4041                 tcore_pending_free(pending);
4042                 return TCORE_RETURN_EINVAL;
4043         }
4044         req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
4045
4046         if (req == NULL) {
4047                 tcore_pending_free(pending);
4048                 return TCORE_RETURN_FAILURE;
4049         }
4050
4051         dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4052                                 req->cmd, req->prefix, strlen(req->cmd));
4053
4054         tcore_pending_set_request_data(pending, 0, req);
4055         tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
4056         tcore_pending_link_user_request(pending, ur);
4057         tcore_hal_send_request(hal, pending);
4058
4059         dbg("Exit");
4060         return TCORE_RETURN_SUCCESS;
4061 }
4062
4063 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
4064 {
4065         TReturn api_ret = TCORE_RETURN_SUCCESS;
4066         enum tcore_request_command command;
4067
4068         dbg("Entry");
4069
4070         if ((o == NULL) || (ur == NULL))
4071                 return TCORE_RETURN_EINVAL;
4072
4073         command = tcore_user_request_get_command(ur);
4074         if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
4075                 err("CP NOT READY");
4076                 return TCORE_RETURN_ENOSYS;
4077         }
4078
4079         switch (command) {
4080         case TREQ_SIM_GET_ECC:
4081                 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
4082                 break;
4083
4084         case TREQ_SIM_GET_LANGUAGE:
4085                 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
4086                         api_ret = _get_file_info(o, ur, SIM_EF_ELP);
4087                 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
4088                         api_ret = _get_file_info(o, ur, SIM_EF_LP);
4089                 else
4090                         api_ret = TCORE_RETURN_ENOSYS;
4091                 break;
4092
4093         case TREQ_SIM_GET_ICCID:
4094                 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
4095                 break;
4096
4097         case TREQ_SIM_GET_MAILBOX:
4098                 if (tcore_sim_get_cphs_status(o))
4099                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4100                 else
4101                         api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
4102                 break;
4103
4104         case TREQ_SIM_GET_CALLFORWARDING:
4105                 if (tcore_sim_get_cphs_status(o))
4106                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4107                 else
4108                         api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
4109                 break;
4110
4111         case TREQ_SIM_GET_MESSAGEWAITING:
4112                 if (tcore_sim_get_cphs_status(o))
4113                         api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4114                 else
4115                         api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
4116                 break;
4117
4118         case TREQ_SIM_GET_CPHS_INFO:
4119                 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
4120                 break;
4121
4122         case TREQ_SIM_GET_MSISDN:
4123                 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
4124                 break;
4125
4126         case TREQ_SIM_GET_SPN:
4127                 dbg("enter case SPN");
4128                 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
4129                 break;
4130
4131         case TREQ_SIM_GET_SPDI:
4132                 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
4133                 break;
4134
4135         case TREQ_SIM_GET_OPL:
4136                 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
4137                 break;
4138
4139         case TREQ_SIM_GET_PNN:
4140                 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
4141                 break;
4142
4143         case TREQ_SIM_GET_CPHS_NETNAME:
4144                 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
4145                 break;
4146
4147         case TREQ_SIM_GET_OPLMNWACT:
4148                 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
4149                 break;
4150
4151         case TREQ_SIM_GET_SERVICE_TABLE:
4152                 api_ret = _get_file_info(o, ur, SIM_EF_SST);
4153                 break;
4154
4155         default:
4156                 dbg("error - not handled read treq command[%d]", command);
4157                 api_ret = TCORE_RETURN_EINVAL;
4158                 break;
4159         }
4160         dbg("Exit");
4161         return api_ret;
4162 }
4163
4164
4165 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
4166 {
4167         TReturn ret_code = TCORE_RETURN_SUCCESS;
4168         enum tcore_request_command command;
4169         enum tel_sim_file_id ef = SIM_EF_INVALID;
4170         struct imc_sim_property meta_info = {0, };
4171         enum tel_sim_type sim_type;
4172         gboolean cphs_sim = FALSE;
4173         dbg("Entry");
4174
4175         command = tcore_user_request_get_command(ur);
4176         cphs_sim = tcore_sim_get_cphs_status(co_sim);
4177         sim_type = tcore_sim_get_type(co_sim);
4178
4179         if ((co_sim == NULL) || (ur == NULL))
4180                 return TCORE_RETURN_EINVAL;
4181
4182         switch (command) {
4183         case TREQ_SIM_SET_LANGUAGE:
4184                 if (sim_type == SIM_TYPE_GSM)
4185                         ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
4186                 else if (sim_type == SIM_TYPE_USIM)
4187                         ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
4188                 else
4189                         ret_code = TCORE_RETURN_ENOSYS;
4190         break;
4191
4192         case TREQ_SIM_SET_MAILBOX:
4193                 if (cphs_sim) {
4194                         struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4195
4196                         if (!svct)
4197                                 break;
4198                         if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MBDN]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MBDN])) {
4199                                 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4200                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4201                         } else {
4202                                 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
4203                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4204                         }
4205                         free(svct);
4206                 } else {
4207                         ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4208                 }
4209         break;
4210
4211         case TREQ_SIM_SET_CALLFORWARDING:
4212         {
4213                 const struct treq_sim_set_callforwarding *cf = NULL;
4214                 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
4215
4216                 if (cf) {
4217                         if (cphs_sim) {
4218                                 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4219                                 if (!svct)
4220                                         break;
4221                                 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_CFIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_CFIS])) {
4222                                         if (cf->b_cphs == FALSE)
4223                                                 ef = SIM_EF_USIM_CFIS;
4224                                         else
4225                                                 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4226
4227                                         tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4228                                         ret_code = _get_file_info(co_sim, ur, ef);
4229                                 } else {
4230                                         dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4231                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4232                                 }
4233                                 free(svct);
4234                         } else {
4235                                 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4236                         }
4237                 } else {
4238                         ret_code = TCORE_RETURN_EINVAL;
4239                 }
4240         }
4241         break;
4242
4243         case TREQ_SIM_SET_MESSAGEWAITING:
4244         {
4245                 const struct treq_sim_set_messagewaiting *mw = NULL;
4246                 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4247                 if (mw) {
4248                         if (cphs_sim) {
4249                                 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4250                                 if (!svct)
4251                                         break;
4252                                 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MWIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MWIS])) {
4253                                         if (mw->b_cphs == FALSE)
4254                                                 ef = SIM_EF_USIM_MWIS;
4255                                         else
4256                                                 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4257
4258                                         tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4259                                         ret_code = _get_file_info(co_sim, ur, ef);
4260                                 } else {
4261                                         dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4262                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4263                                 }
4264                                 free(svct);
4265                                 } else {
4266                                         ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4267                         }
4268                 } else{
4269                         ret_code = TCORE_RETURN_EINVAL;
4270                 }
4271         }
4272         break;
4273
4274         default:
4275                 err("Unhandled UPDATE command[%d]", command);
4276                 return TCORE_RETURN_EINVAL;
4277         }
4278
4279         return ret_code;
4280 }
4281
4282 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4283 {
4284         const struct treq_sim_transmit_apdu *req_data;
4285         TcoreHal *hal = NULL;
4286         char *cmd_str = NULL;
4287         char *apdu = NULL;
4288         int result = 0;
4289         TReturn ret = TCORE_RETURN_FAILURE;
4290
4291         dbg("Entry");
4292
4293         if ((o == NULL) || (ur == NULL))
4294                 return TCORE_RETURN_EINVAL;
4295
4296         hal = tcore_object_get_hal(o);
4297         if (FALSE == tcore_hal_get_power_state(hal)) {
4298                 err("CP NOT READY");
4299                 return TCORE_RETURN_ENOSYS;
4300         }
4301
4302         req_data = tcore_user_request_ref_data(ur, NULL);
4303
4304         apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4305         if (apdu == NULL) {
4306                 err("Memory allocation failed!!");
4307                 return TCORE_RETURN_ENOMEM;
4308         }
4309         result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4310         dbg("result %d", result);
4311
4312         cmd_str = g_strdup_printf("AT+CSIM=%d, \"%s\"", (unsigned int)strlen(apdu), apdu);
4313
4314         ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4315                                                                 TCORE_AT_SINGLELINE, ur,
4316                                                                 on_response_transmit_apdu, hal,
4317                                                                 NULL, NULL, 0, NULL, NULL);
4318         g_free(cmd_str);
4319         g_free(apdu);
4320
4321         dbg("Exit");
4322         return ret;
4323 }
4324
4325 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4326 {
4327         TcoreHal *hal = NULL;
4328
4329         dbg("Entry");
4330
4331         if ((o == NULL) || (ur == NULL)) {
4332                 err("Invalid parameters");
4333                 return TCORE_RETURN_EINVAL;
4334         }
4335
4336         hal = tcore_object_get_hal(o);
4337         if (FALSE == tcore_hal_get_power_state(hal)) {
4338                 err("CP NOT READY");
4339                 return TCORE_RETURN_ENOSYS;
4340         }
4341
4342         return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4343                                                                 TCORE_AT_SINGLELINE, ur,
4344                                                                 on_response_get_atr, hal,
4345                                                                 NULL, NULL, 0, NULL, NULL);
4346 }
4347
4348 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4349 {
4350         const struct treq_sim_req_authentication *req_data;
4351         char *cmd_str = NULL;
4352         enum tel_sim_type sim_type;
4353         int session_id;
4354         int context_type;
4355         TReturn ret = TCORE_RETURN_FAILURE;
4356         char *convert_rand = NULL;
4357         char *convert_autn = NULL;
4358
4359         dbg("Entry");
4360
4361         req_data = tcore_user_request_ref_data(ur, NULL);
4362         if (req_data == NULL) {
4363                 err("req_data is NULL");
4364                 return ret;
4365         }
4366
4367         convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
4368         dbg("Convert RAND hex to string: [%s]", convert_rand);
4369
4370         sim_type = tcore_sim_get_type(co);
4371         switch (sim_type) {
4372         case SIM_TYPE_GSM:
4373         case SIM_TYPE_USIM:
4374                 session_id = 0;
4375                 break;
4376         default:
4377                 err("Not supported");
4378                 ret = TCORE_RETURN_ENOSYS;
4379                 goto out;
4380         }
4381
4382         switch (req_data->auth_type) {
4383         case SIM_AUTH_TYPE_GSM:
4384                 context_type = 2;
4385                 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\"", session_id,
4386                                                 context_type, convert_rand);
4387                 break;
4388         case SIM_AUTH_TYPE_3G:
4389                 context_type = 1;
4390                 convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
4391                 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4392
4393                 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\", \"%s\"",
4394                                                 session_id, context_type,
4395                                                 convert_rand, convert_autn);
4396                 break;
4397         default:
4398                 err("Not supported");
4399                 ret = TCORE_RETURN_ENOSYS;
4400                 goto out;
4401         }
4402
4403         ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4404                         TCORE_AT_SINGLELINE, ur,
4405                         on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4406
4407 out:
4408         g_free(cmd_str);
4409         g_free(convert_rand);
4410         g_free(convert_autn);
4411
4412         return ret;
4413 }
4414
4415 /* SIM Operations */
4416 static struct tcore_sim_operations sim_ops = {
4417         .verify_pins = imc_verify_pins,
4418         .verify_puks = imc_verify_puks,
4419         .change_pins = imc_change_pins,
4420         .get_facility_status = imc_get_facility_status,
4421         .enable_facility = imc_enable_facility,
4422         .disable_facility = imc_disable_facility,
4423         .get_lock_info = imc_get_lock_info,
4424         .read_file = imc_read_file,
4425         .update_file = imc_update_file,
4426         .transmit_apdu = imc_transmit_apdu,
4427         .get_atr = imc_get_atr,
4428         .req_authentication = imc_req_authentication,
4429         .set_powerstate = NULL,
4430 };
4431
4432 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4433 {
4434         struct imc_sim_property *meta_info;
4435
4436         dbg("Entry");
4437
4438         /* Set operations */
4439         tcore_sim_set_ops(co_sim, &sim_ops, TCORE_OPS_TYPE_CP);
4440
4441         meta_info = g_try_new0(struct imc_sim_property, 1);
4442         if (meta_info == NULL)
4443                 return FALSE;
4444
4445         tcore_sim_link_userdata(co_sim, meta_info);
4446
4447         tcore_object_add_callback(co_sim, "+XLOCK:",
4448                                                         on_event_facility_lock_status, NULL);
4449         tcore_object_add_callback(co_sim, "+XSIM:",
4450                                                         on_event_pin_status, NULL);
4451
4452         tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4453                                                         TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4454
4455         dbg("Exit");
4456
4457         return TRUE;
4458 }
4459
4460 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4461 {
4462         struct imc_sim_property *meta_info;
4463
4464         meta_info = tcore_sim_ref_userdata(co_sim);
4465         g_free(meta_info);
4466
4467         dbg("Exit");
4468 }