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