fix SPN display issue
[platform/core/telephony/tel-plugin-imc.git] / src / imc_sim.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <glib.h>
24
25 #include <tcore.h>
26 #include <server.h>
27 #include <plugin.h>
28 #include <core_object.h>
29 #include <hal.h>
30 #include <queue.h>
31 #include <storage.h>
32 #include <at.h>
33 #include <vconf.h>
34
35 #include <co_sim.h>
36 #include <co_sms.h>
37
38 #include "imc_sim.h"
39 #include "imc_common.h"
40
41 #define ENABLE_FLAG 1
42 #define DISABLE_FLAG 2
43
44 #define IMC_SIM_ACCESS_READ_BINARY              176
45 #define IMC_SIM_ACCESS_READ_RECORD              178
46 #define IMC_SIM_ACCESS_GET_RESPONSE             192
47 #define IMC_SIM_ACCESS_UPDATE_BINARY            214
48 #define IMC_SIM_ACCESS_UPDATE_RECORD            220
49
50 #define IMC_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \
51 { \
52         ImcSimMetaInfo file_meta = {0, }; \
53         ImcRespCbData *resp_cb_data = NULL; \
54         \
55         file_meta.file_id = fileId; \
56         file_meta.file_result = TEL_SIM_RESULT_FAILURE; \
57         \
58         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo)); \
59         \
60         ret =  __imc_sim_get_response(co, resp_cb_data); \
61         dbg("Request reading '%s' - [%s]", #fileId, (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAILURE")); \
62 }
63
64 typedef enum {
65         IMC_SIM_FILE_TYPE_DEDICATED = 0x00,     /**< Dedicated */
66         IMC_SIM_FILE_TYPE_TRANSPARENT = 0x01,   /**< Transparent -binary type*/
67         IMC_SIM_FILE_TYPE_LINEAR_FIXED = 0x02,  /**< Linear fixed - record type*/
68         IMC_SIM_FILE_TYPE_CYCLIC = 0x04,        /**< Cyclic - record type*/
69         IMC_SIM_FILE_TYPE_INVALID_TYPE = 0xFF   /**< Invalid type */
70 } ImcSimFileType;
71
72 typedef enum {
73         IMC_SIM_CURR_SEC_OP_PIN1_VERIFY,
74         IMC_SIM_CURR_SEC_OP_PIN2_VERIFY,
75         IMC_SIM_CURR_SEC_OP_PUK1_VERIFY,
76         IMC_SIM_CURR_SEC_OP_PUK2_VERIFY,
77         IMC_SIM_CURR_SEC_OP_SIM_VERIFY,
78         IMC_SIM_CURR_SEC_OP_ADM_VERIFY,
79         IMC_SIM_CURR_SEC_OP_PIN1_CHANGE,
80         IMC_SIM_CURR_SEC_OP_PIN2_CHANGE,
81         IMC_SIM_CURR_SEC_OP_PIN1_ENABLE,
82         IMC_SIM_CURR_SEC_OP_PIN1_DISABLE,
83         IMC_SIM_CURR_SEC_OP_PIN2_ENABLE,
84         IMC_SIM_CURR_SEC_OP_PIN2_DISABLE, // 10
85         IMC_SIM_CURR_SEC_OP_SIM_ENABLE,
86         IMC_SIM_CURR_SEC_OP_SIM_DISABLE,
87         IMC_SIM_CURR_SEC_OP_NET_ENABLE,
88         IMC_SIM_CURR_SEC_OP_NET_DISABLE,
89         IMC_SIM_CURR_SEC_OP_NS_ENABLE,
90         IMC_SIM_CURR_SEC_OP_NS_DISABLE,
91         IMC_SIM_CURR_SEC_OP_SP_ENABLE,
92         IMC_SIM_CURR_SEC_OP_SP_DISABLE,
93         IMC_SIM_CURR_SEC_OP_CP_ENABLE,
94         IMC_SIM_CURR_SEC_OP_CP_DISABLE, // 20
95         IMC_SIM_CURR_SEC_OP_FDN_ENABLE,
96         IMC_SIM_CURR_SEC_OP_FDN_DISABLE,
97         IMC_SIM_CURR_SEC_OP_PIN1_STATUS,
98         IMC_SIM_CURR_SEC_OP_PIN2_STATUS,
99         IMC_SIM_CURR_SEC_OP_FDN_STATUS,
100         IMC_SIM_CURR_SEC_OP_NET_STATUS,
101         IMC_SIM_CURR_SEC_OP_NS_STATUS,
102         IMC_SIM_CURR_SEC_OP_SP_STATUS,
103         IMC_SIM_CURR_SEC_OP_CP_STATUS,
104         IMC_SIM_CURR_SEC_OP_SIM_STATUS,
105         IMC_SIM_CURR_SEC_OP_SIM_UNKNOWN = 0xff
106 } ImcSimCurrSecOp;
107
108 typedef struct {
109         guint smsp_count;                                       /**< SMSP record count */
110         guint smsp_rec_len;                                     /**< SMSP record length */
111 } ImcSimPrivateInfo;
112
113 typedef struct {
114         gboolean b_valid;                                       /**< Valid or not */
115         guint rec_length;                                       /**< Length of one record in file */
116         guint rec_count;                                        /**< Number of records in file */
117         guint data_size;                                        /**< File size */
118         guint current_index;                                    /**< Current index to read */
119         ImcSimFileType file_type;                               /**< File type and structure */
120         ImcSimCurrSecOp sec_op;                                 /**< Current index to read */
121         TelSimMailboxList mbi_list;                             /**< Mailbox List */
122         TelSimMailBoxNumber mb_list[TEL_SIM_MSP_CNT_MAX*5];     /**< Mailbox number */
123         TelSimFileId file_id;                                   /**< Current file id */
124         TelSimResult file_result;                               /**< File access result */
125         TelSimFileResult files;                                 /**< File read data */
126         TcoreCommand req_command;                               /**< Request command Id */
127         TelSimImsiInfo imsi;                                    /**< Stored locally as of now,
128                                                                           Need to store in secure storage*/
129 } ImcSimMetaInfo;
130
131 /* Utility Function Declaration */
132 static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2);
133 static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status);
134 static void __imc_sim_notify_sms_state(CoreObject *co, gboolean sms_ready);
135 static TelReturn __imc_sim_start_to_cache(CoreObject *co);
136 static gboolean __imc_sim_get_sim_type(CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data);
137 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret);
138 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result);
139 static TelReturn __imc_sim_update_file(CoreObject *co, ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
140                                                 int p1, int p2, int p3, char *encoded_data);
141 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data);
142 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data);
143 static TelReturn __imc_sim_get_response (CoreObject *co, ImcRespCbData *resp_cb_data);
144 static TelReturn __imc_sim_get_retry_count(CoreObject *co, ImcRespCbData *resp_cb_data);
145 static TelSimLockType __imc_sim_lock_type(int lock_type);
146 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type, ImcSimCurrSecOp *sec_op, int flag);
147 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op);
148
149 /* Internal Response Functions*/
150 static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co, gint result, const void *response, void *user_data);
151 static void __on_response_imc_sim_get_sim_type(TcorePending *p, guint data_len, const void *data, void *user_data);
152 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len, const void *data, void *user_data);
153 static void __on_response_imc_sim_get_response(TcorePending *p, guint data_len, const void *data, void *user_data);
154 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len, const void *data, void *user_data);
155 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data);
156
157 /* GET SMSP info for SMS module */
158 gboolean imc_sim_get_smsp_info(TcorePlugin *plugin, int *rec_count, int *rec_len)
159 {
160         CoreObject *co = NULL;
161         ImcSimPrivateInfo *priv_info = NULL;
162
163         dbg("Entry");
164
165         co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
166         priv_info = tcore_sim_ref_userdata(co);
167         if(!priv_info)
168                 return FALSE;
169
170         *rec_count = priv_info->smsp_count;
171         *rec_len = priv_info->smsp_rec_len;
172
173         dbg("smsp_count:[%d], smsp_rec_len:[%d]", priv_info->smsp_count, priv_info->smsp_rec_len);
174         return TRUE;
175 }
176
177 static void __imc_sim_set_identity(CoreObject *co, TelSimImsiInfo *imsi)
178 {
179         gchar new_imsi[15 + 1] = {0, };
180         gchar *old_imsi;
181
182         memcpy(&new_imsi, imsi->mcc, strlen(imsi->mcc));
183         memcpy(&new_imsi[strlen(imsi->mcc)], imsi->mnc, strlen(imsi->mnc));
184         memcpy(&new_imsi[strlen(imsi->mcc) + strlen(imsi->mnc)], imsi->msin, strlen(imsi->msin));
185
186         /* TODO: This is temporary code, we should use secure storage instead of vconf */
187         old_imsi = vconf_get_str("db/telephony/imsi");
188         if (old_imsi) {
189                 if (g_strcmp0(old_imsi, new_imsi) != 0) {
190                         dbg("New SIM");
191                         vconf_set_str("db/telephony/imsi", new_imsi);
192                         tcore_sim_set_identification(co, TRUE);
193                 } else {
194                         dbg("Same SIM");
195                         tcore_sim_set_identification(co, FALSE);
196                 }
197         } else {
198                 dbg("Old IMSI value is NULL, set IMSI");
199                 vconf_set_str("db/telephony/imsi", new_imsi);
200                 tcore_sim_set_identification(co, TRUE);
201         }
202 }
203
204 /* Utility Functions */
205 static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2)
206 {
207         TelSimResult rst = TEL_SIM_RESULT_FAILURE;
208
209         if (status_word1 == 0x93 && status_word2 == 0x00) {
210                 /*Failed SIM request command*/
211                 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
212         } else if (status_word1 == 0x94 && status_word2 == 0x00) {
213                 /*Failed SIM request command*/
214                 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
215         } else if (status_word1 == 0x94 && status_word2 == 0x02) {
216                 /*Failed SIM request command*/
217                 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
218                         status_word1, status_word2);
219         } else if (status_word1 == 0x94 && status_word2 == 0x04) {
220                 /*Failed SIM request command*/
221                 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
222         } else if (status_word1 == 0x94 && status_word2 == 0x08) {
223                 /*Failed SIM request command*/
224                 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
225                         status_word1, status_word2);
226         } else if (status_word1 == 0x98 && status_word2 == 0x02) {
227                 /*Failed SIM request command*/
228                 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
229         } else if (status_word1 == 0x98 && status_word2 == 0x04) {
230                 /*Failed SIM request command*/
231                 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
232                 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
233                         status_word1, status_word2);
234                 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
235                         status_word1, status_word2);
236                 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
237         } else if (status_word1 == 0x98 && status_word2 == 0x08) {
238                 /*Failed SIM request command*/
239                 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
240         } else if (status_word1 == 0x98 && status_word2 == 0x10) {
241                 /*Failed SIM request command*/
242                 dbg("error - Contradiction with invalidation status [%x][%x]",
243                         status_word1, status_word2);
244         } else if (status_word1 == 0x98 && status_word2 == 0x40) {
245                 /*Failed SIM request command*/
246                 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
247                         status_word1, status_word2);
248                 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
249                         status_word1, status_word2);
250                 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
251         } else if (status_word1 == 0x67 && status_word2 == 0x00) {
252                 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
253         } else if (status_word1 == 0x6B && status_word2 == 0x00) {
254                 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
255         } else if (status_word1 == 0x6D && status_word2 == 0x00) {
256                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
257         } else if (status_word1 == 0x6E && status_word2 == 0x00) {
258                 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
259         } else if (status_word1 == 0x69 && status_word2 == 0x82) {
260                 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
261         } else if (status_word1 == 0x6A && status_word2 == 0x87) {
262                 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
263         } else if (status_word1 == 0x6A && status_word2 == 0x82) {
264                 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
265         } else if (status_word1 == 0x6A && status_word2 == 0x83) {
266                 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
267         } else {
268                 rst = TEL_SIM_RESULT_CARD_ERROR;
269                 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
270         }
271         return rst;
272 }
273
274 static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status)
275 {
276         TelSimCardStatus curr_sim_status;
277
278         /*
279          * Send SIM Init status, if not sent already
280          */
281         (void)tcore_sim_get_status(co, &curr_sim_status);
282         if (sim_status != curr_sim_status) {
283                 TelSimCardStatusInfo sim_status_noti = {0, };
284
285                 dbg("Change in SIM State - Old State: [0x%02x] --> New State: [0x%02x]",
286                                 curr_sim_status, sim_status);
287
288                 /* Update SIM Status */
289                 tcore_sim_set_status(co, sim_status);
290                 sim_status_noti.status = sim_status;
291                 tcore_sim_get_identification(co, &sim_status_noti.change_status);
292
293                 /* Send notification: SIM Status */
294                 tcore_object_send_notification(co,
295                         TCORE_NOTIFICATION_SIM_STATUS,
296                         sizeof(sim_status_noti), &sim_status_noti);
297         }
298 }
299
300 static void __imc_sim_notify_sms_state(CoreObject *co,
301                                                 gboolean sms_ready)
302 {
303         TcorePlugin *plugin;
304         CoreObject *co_sms;
305         gboolean sms_status = FALSE;
306
307         dbg("Entry");
308
309         plugin = tcore_object_ref_plugin(co);
310         co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
311         tcore_check_return_assert(co_sms != NULL);
312
313         (void)tcore_sms_get_ready_status(co_sms, &sms_status);
314         if (sms_status == sms_ready) {
315                 dbg("No change in SMS Status: [%s]",
316                         (sms_status ? "INITIALIZED" : "UNINITIALIZED"));
317         } else {
318                 TelSimCardStatus sim_status;
319
320                 /* Update SMS State */
321                 tcore_sms_set_ready_status(co_sms, sms_ready);
322
323                 dbg("SMS Status - Changed [%s] --> [%s]",
324                         (sms_status ? "INITIALIZED" : "UNINITIALIZED"),
325                         (sms_ready ? "INITIALIZED" : "UNINITIALIZED"));
326
327                 /*
328                  * Send SMS device ready notification, if SIM is initialiazed.
329                  */
330                 (void)tcore_sim_get_status(co, &sim_status);
331                 if (sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
332                         /* Send notification: SMS Device ready */
333                         tcore_object_send_notification(co_sms,
334                                 TCORE_NOTIFICATION_SMS_DEVICE_READY,
335                                 sizeof(sms_ready), &sms_ready);
336                 }
337         }
338 }
339
340 TelReturn __imc_sim_start_to_cache(CoreObject *co)
341 {
342         TelReturn ret;
343         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_IMSI, ret);
344         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_CPHS_CPHS_INFO, ret);
345         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ICCID, ret);
346         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SPN, ret);
347         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SST, ret);
348         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ECC, ret);
349         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_MSISDN, ret);
350         IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SMSP, ret);
351
352         return ret;
353 }
354
355 static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co,
356         gint result, const void *response, void *user_data)
357 {
358         dbg("SIM Response - SIM Type (internal): [+XUICC]");
359
360         if (result == TEL_SIM_RESULT_SUCCESS) {
361                 TelSimCardType *sim_type = (TelSimCardType *)response;
362                 dbg("SIM Type: [%d]", *sim_type);
363
364                 /* Update SIM type */
365                 tcore_sim_set_type(co, *sim_type);
366                 if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) {
367                         TelReturn ret;
368
369                         /* Start Caching SIM files */
370                         ret = __imc_sim_start_to_cache(co);
371
372                         /* Send SIM Type notification */
373                         tcore_object_send_notification(co,
374                                 TCORE_NOTIFICATION_SIM_TYPE,
375                                 sizeof(TelSimCardType), sim_type);
376                 }
377         }
378 }
379
380 static void __on_response_imc_sim_get_sim_type(TcorePending *p,
381         guint data_len, const void *data, void *user_data)
382 {
383         const TcoreAtResponse *at_resp = data;
384         CoreObject *co = tcore_pending_ref_core_object(p);
385         ImcRespCbData *resp_cb_data = user_data;
386         TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN;
387
388         TelSimResult result = TEL_SIM_RESULT_FAILURE;
389
390         dbg("SIM Response - SIM Type: [+XUICC]");
391
392         tcore_check_return_assert(co != NULL);
393         tcore_check_return_assert(resp_cb_data != NULL);
394
395         if (at_resp && at_resp->success) {
396                 if (at_resp->lines) {
397                         const gchar *line;
398                         GSList *tokens;
399
400                         line = (const gchar *)at_resp->lines->data;
401
402                         /*
403                          * Tokenize
404                          *
405                          *      +XUICC: <state>
406                          */
407                         tokens = tcore_at_tok_new(line);
408
409                         /* <state> */
410                         if (g_slist_length(tokens) == 1) {
411                                 guint state = atoi(g_slist_nth_data(tokens, 0));
412
413                                 if (state == 0) /* 0 - 2G SIM */
414                                         sim_type = TEL_SIM_CARD_TYPE_GSM;
415                                 else if (state == 1)    /* 1 - 3G SIM */
416                                         sim_type = TEL_SIM_CARD_TYPE_USIM;
417
418                                 result = TEL_SIM_RESULT_SUCCESS;
419                         }
420                         else {
421                                 err("Invalid message");
422                         }
423
424                         tcore_at_tok_free(tokens);
425                 }
426         }
427
428         /* Invoke callback */
429         if (resp_cb_data->cb)
430                 resp_cb_data->cb(co, (gint)result, &sim_type, resp_cb_data->cb_data);
431
432         /* Free callback data */
433         imc_destroy_resp_cb_data(resp_cb_data);
434 }
435
436 /*
437  * Operation - get_sim_type
438  *
439  * Request -
440  * AT-Command: AT+XUICC?
441  *
442  * Response - sim_type (TelSimCardType)
443  * Success: (Single line) -
444  *      + XUICC: <state>
445  *      OK
446  * Failure:
447  *      +CME ERROR: <error>
448  */
449 gboolean __imc_sim_get_sim_type(CoreObject *co,
450         TcoreObjectResponseCallback cb, void *cb_data)
451 {
452         ImcRespCbData *resp_cb_data;
453         TelReturn ret;
454
455         /* Response callback data */
456         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
457                                 NULL, 0);
458
459         /* Send Request to modem */
460         ret = tcore_at_prepare_and_send_request(co,
461                 "AT+XUICC?", "+XUICC:",
462                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
463                 TCORE_PENDING_PRIORITY_DEFAULT,
464                 NULL,
465                 __on_response_imc_sim_get_sim_type, resp_cb_data,
466                 on_send_imc_request, NULL,
467                 0, NULL, NULL);
468         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
469
470         return ret;
471 }
472
473 static void __imc_sim_process_sim_status(CoreObject *co, guint sim_state)
474 {
475         TelSimCardStatus sim_card_status;
476
477         switch (sim_state) {
478         case 0:
479                 sim_card_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
480                 dbg("NO SIM");
481         break;
482
483         case 1:
484                 sim_card_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
485                 dbg("PIN REQUIRED");
486         break;
487
488         case 2:
489                 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
490                 dbg("PIN DISABLED AT BOOT UP");
491         break;
492
493         case 3:
494                 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
495                 dbg("PIN VERIFIED");
496         break;
497
498         case 4:
499                 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
500                 dbg("PUK REQUIRED");
501         break;
502
503         case 5:
504                 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
505                 dbg("CARD PERMANENTLY BLOCKED");
506         break;
507
508         case 6:
509                 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
510                 dbg("SIM CARD ERROR");
511         break;
512
513         case 7:
514                 sim_card_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
515                 dbg("SIM INIT COMPLETED");
516         break;
517
518         case 8:
519                 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
520                 dbg("SIM CARD ERROR");
521         break;
522
523         case 9:
524                 sim_card_status = TEL_SIM_STATUS_CARD_REMOVED;
525                 dbg("SIM REMOVED");
526         break;
527
528         case 12:
529                 dbg("SIM SMS Ready");
530
531                 /* Notify SMS status */
532                 return __imc_sim_notify_sms_state(co, TRUE);
533
534         case 99:
535                 sim_card_status = TEL_SIM_STATUS_UNKNOWN;
536                 dbg("SIM STATE UNKNOWN");
537         break;
538
539         default:
540                 err("Unknown/Unsupported SIM state: [%d]", sim_state);
541                 return;
542         }
543
544         switch (sim_card_status) {
545         case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
546                 TelSimCardType sim_type;
547
548                 dbg("SIM INIT COMPLETED");
549
550                 (void)tcore_sim_get_type(co, &sim_type);
551                 if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) {
552                         /*
553                          * SIM is initialized for first time, need to
554                          * fetch SIM type
555                          */
556                         (void)__imc_sim_get_sim_type(co,
557                                 __on_response_imc_sim_get_sim_type_internal, NULL);
558
559                         return;
560                 }
561         }
562         break;
563
564         case TEL_SIM_STATUS_CARD_REMOVED:
565                 dbg("SIM CARD REMOVED");
566                 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
567         break;
568
569         case TEL_SIM_STATUS_CARD_NOT_PRESENT:
570                 dbg("SIM CARD NOT PRESENT");
571                 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
572         break;
573
574         case TEL_SIM_STATUS_CARD_ERROR:
575                 dbg("SIM CARD ERROR");
576                 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
577         break;
578
579         default:
580                 err("SIM Status: [0x%02x]", sim_card_status);
581         break;
582         }
583
584         /* Update SIM Status */
585         return __imc_sim_update_sim_status(co, sim_card_status);
586 }
587
588 static void __on_response_imc_sim_get_sim_status(TcorePending *p,
589         guint data_len, const void *data, void *user_data)
590 {
591         const TcoreAtResponse *at_resp = data;
592         CoreObject *co = tcore_pending_ref_core_object(p);
593         ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
594         dbg("Enter");
595
596         dbg("SIM Response - SIM status: [+XSIMSTATE]");
597
598         tcore_check_return_assert(co != NULL);
599         tcore_check_return_assert(resp_cb_data != NULL);
600
601         if (at_resp && at_resp->success) {
602                 if (at_resp->lines) {
603                         const gchar *line = NULL;
604
605                         /* Process +XSIMSTATE response */
606                         line = (const gchar *) (at_resp->lines->data);
607                         if (line != NULL) {
608                                 GSList *tokens;
609                                 guint sim_state, sms_state;
610
611                                 /*
612                                  * Tokenize
613                                  *
614                                  * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
615                                  */
616                                 tokens = tcore_at_tok_new(line);
617
618                                 if (g_slist_length(tokens) == 4) {
619                                         /* <SIM state> */
620                                         sim_state = atoi(g_slist_nth_data(tokens, 1));
621
622                                         /* Process SIM Status */
623                                         __imc_sim_process_sim_status(co, sim_state);
624
625                                         /* <SMS Ready> */
626                                         sms_state = atoi(g_slist_nth_data(tokens, 3));
627
628                                         /* Notify SMS status */
629                                         __imc_sim_notify_sms_state(co, (sms_state > 0));
630
631                                 } else {
632                                         err("Invalid message");
633                                 }
634
635                                 tcore_at_tok_free(tokens);
636                         }
637                 }
638         }
639
640         /* Free callback data */
641         imc_destroy_resp_cb_data(resp_cb_data);
642 }
643
644 /*
645  * Operation - get_sim_status
646  *
647  * Request -
648  * AT-Command: AT+XSIMSTATE?
649  *
650  * Response - sim_status
651  * Success: (Single line) -
652  *      +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
653  *      OK
654  * Failure:
655  *      +CME ERROR: <error>
656  */
657 static gboolean __imc_sim_get_sim_status(CoreObject *co,
658         TcoreObjectResponseCallback cb, void *cb_data)
659 {
660         ImcRespCbData *resp_cb_data;
661         TelReturn ret;
662
663         /* Response callback data */
664         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
665                                 NULL, 0);
666
667         /* Send Request to modem */
668         ret = tcore_at_prepare_and_send_request(co,
669                 "AT+XSIMSTATE?", "+XSIMSTATE:",
670                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
671                 TCORE_PENDING_PRIORITY_DEFAULT,
672                 NULL,
673                 __on_response_imc_sim_get_sim_status, resp_cb_data,
674                 on_send_imc_request, NULL,
675                 0, NULL, NULL);
676         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Status");
677
678         return TRUE;
679 }
680
681 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
682 {
683         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
684         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
685
686         dbg("Entry");
687
688         dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", file_meta->file_id, sim_result, decode_ret);
689         switch (file_meta->file_id) {
690         case TEL_SIM_EF_ELP:
691         case TEL_SIM_EF_USIM_PL:
692         case TEL_SIM_EF_LP:
693         case TEL_SIM_EF_USIM_LI:
694                 if (decode_ret == TRUE) {
695                         if (resp_cb_data->cb)
696                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
697                 } else {
698                         tcore_sim_get_type(co, &card_type);
699                         /* 2G */
700                         /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
701                          -      EFELP is not available;
702                          -      EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
703                          -      the ME does not support any of the languages in EFELP.
704                          */
705                         /* 3G */
706                         /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
707                          -      if the EFLI has the value 'FFFF' in its highest priority position
708                          -      if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
709                          */
710                         if (TEL_SIM_CARD_TYPE_GSM == card_type) {
711                                 if (file_meta->file_id == TEL_SIM_EF_LP) {
712                                         if (resp_cb_data->cb)
713                                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
714                                 } else {
715                                         file_meta->file_id = TEL_SIM_EF_LP;
716                                         __imc_sim_get_response(co, resp_cb_data);
717                                 }
718                         } else if (TEL_SIM_CARD_TYPE_USIM) {
719                                 if (file_meta->file_id == TEL_SIM_EF_LP || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
720                                         file_meta->file_id = TEL_SIM_EF_ELP;
721                                         __imc_sim_get_response(co, resp_cb_data);
722                                 } else {
723                                         if (resp_cb_data->cb)
724                                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
725                                 }
726                         }
727                 }
728         break;
729
730         case TEL_SIM_EF_ECC:
731                 tcore_sim_get_type(co, &card_type);
732                 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
733                         if (file_meta->current_index == file_meta->rec_count) {
734                                 if (resp_cb_data->cb)
735                                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
736                         } else {
737                                 file_meta->current_index++;
738                                 __imc_sim_read_record(co, resp_cb_data);
739                         }
740                 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
741                         if (resp_cb_data->cb)
742                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
743                 } else {
744                         dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", card_type);
745                 }
746         break;
747
748         case TEL_SIM_EF_IMSI:
749                 if (resp_cb_data->cb) {
750                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->imsi, resp_cb_data->cb_data);
751                 } else {
752                         file_meta->file_id = TEL_SIM_EF_CPHS_CPHS_INFO;
753                         file_meta->file_result = TEL_SIM_RESULT_FAILURE;
754                         __imc_sim_get_response(co, resp_cb_data);
755                 }
756                 /* Update SIM INIT status - INIT COMPLETE */
757                 __imc_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
758         break;
759
760         case TEL_SIM_EF_MSISDN:
761                 if (file_meta->current_index == file_meta->rec_count) {
762                         guint i;
763                         dbg("rec_count [%d], msisdn_count[%d]", file_meta->rec_count,
764                                 file_meta->files.data.msisdn_list.count);
765                         if (resp_cb_data->cb) {
766                                 resp_cb_data->cb(co, (gint)sim_result,
767                                         &file_meta->files.data.msisdn_list, resp_cb_data->cb_data);
768                         }
769
770                         /* Free resources */
771                         for (i = 0; i < file_meta->files.data.msisdn_list.count; i++) {
772                                 tcore_free(file_meta->files.data.msisdn_list.list[i].alpha_id);
773                                 tcore_free(file_meta->files.data.msisdn_list.list[i].num);
774                         }
775                         tcore_free(file_meta->files.data.msisdn_list.list);
776                 } else {
777                         file_meta->current_index++;
778                         __imc_sim_read_record(co, resp_cb_data);
779                 }
780         break;
781
782         case TEL_SIM_EF_OPL:
783                 if (file_meta->current_index == file_meta->rec_count) {
784                         if (resp_cb_data->cb)
785                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
786
787                 } else {
788                         file_meta->current_index++;
789                         __imc_sim_read_record(co, resp_cb_data);
790                 }
791         break;
792
793         case TEL_SIM_EF_PNN:
794                 if (file_meta->current_index == file_meta->rec_count) {
795                         if (resp_cb_data->cb)
796                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
797                 } else {
798                         file_meta->current_index++;
799                         __imc_sim_read_record(co, resp_cb_data);
800                 }
801         break;
802
803         case TEL_SIM_EF_USIM_CFIS:
804         case TEL_SIM_EF_USIM_MWIS:
805         case TEL_SIM_EF_USIM_MBI:
806         case TEL_SIM_EF_MBDN:
807         case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
808         case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
809                 if (file_meta->current_index == file_meta->rec_count) {
810                         if (resp_cb_data->cb)
811                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
812                 } else {
813                         file_meta->current_index++;
814                         __imc_sim_read_record(co, resp_cb_data);
815                 }
816         break;
817
818         case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
819         {
820                 ImcSimMetaInfo *file_meta_new = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
821
822                 file_meta->files.result = sim_result;
823                 if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
824                         file_meta_new->files.data.cphs_net.full_name = file_meta->files.data.cphs_net.full_name;
825                         dbg("file_meta_new->files.data.cphs_net.full_name[%s]", file_meta_new->files.data.cphs_net.full_name);
826                 }
827
828                 file_meta_new->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
829                 file_meta_new->file_result = TEL_SIM_RESULT_FAILURE;
830
831                 __imc_sim_get_response(co, resp_cb_data);
832         }
833         break;
834
835         case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
836                 if (resp_cb_data->cb)
837                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.cphs_net, resp_cb_data->cb_data);
838
839                 tcore_free(file_meta->files.data.cphs_net.full_name);
840                 tcore_free(file_meta->files.data.cphs_net.short_name);
841                 file_meta->files.data.cphs_net.full_name = NULL;
842                 file_meta->files.data.cphs_net.short_name = NULL;
843         break;
844
845         case TEL_SIM_EF_ICCID:
846                 if (resp_cb_data->cb)
847                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.iccid, resp_cb_data->cb_data);
848         break;
849
850         case TEL_SIM_EF_SPDI: {
851                 guint i;
852                 dbg("spdi count[%d]", file_meta->files.data.spdi.count);
853
854                 if (resp_cb_data->cb)
855                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
856
857                 /* Free resources */
858                 for (i = 0; i < file_meta->files.data.spdi.count; i++)
859                         tcore_free(file_meta->files.data.spdi.list[i].plmn);
860
861                 tcore_free(file_meta->files.data.spdi.list);
862         }
863         break;
864
865         case TEL_SIM_EF_SST:
866         case TEL_SIM_EF_SPN:
867         case TEL_SIM_EF_OPLMN_ACT:
868         case TEL_SIM_EF_CPHS_CPHS_INFO:
869         case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
870         case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
871         case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
872         case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
873         case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
874         case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
875                 if (resp_cb_data->cb)
876                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
877         break;
878
879         default:
880                 err("File id not handled [0x%x]", file_meta->file_id);
881         break;
882         }
883 }
884
885 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result)
886 {
887         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
888         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
889
890         dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
891
892         file_meta->files.result = sim_result;
893         if (file_meta->file_id != TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING)
894                 memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
895
896         if ((file_meta->file_id != TEL_SIM_EF_ELP && file_meta->file_id != TEL_SIM_EF_LP &&
897                 file_meta->file_id != TEL_SIM_EF_USIM_PL && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
898                 && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
899                 if (resp_cb_data->cb)
900                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
901                 return;
902         }
903
904         switch (file_meta->file_id) {
905         case TEL_SIM_EF_ELP:
906                 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
907                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
908                         __imc_sim_read_binary(co, resp_cb_data);
909                 } else {
910                         tcore_sim_get_type(co, &card_type);
911                         if (TEL_SIM_CARD_TYPE_GSM == card_type) {
912                                 ImcSimMetaInfo file_meta_new = {0,};
913
914                                 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
915                                 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
916                                 file_meta_new.file_id = TEL_SIM_EF_LP;
917                                 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
918                                 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
919
920                                 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
921
922                                 __imc_sim_get_response(co, resp_cb_data);
923                         } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
924                                 dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))");
925                                 if (resp_cb_data->cb)
926                                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
927                                 return;
928                         }
929                 }
930                 break;
931
932         case TEL_SIM_EF_LP:
933                 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
934                         dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
935                         __imc_sim_read_binary(co, resp_cb_data);
936                 } else {
937                         tcore_sim_get_type(co, &card_type);
938                         dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
939                         if (TEL_SIM_CARD_TYPE_GSM == card_type) {
940                                 if (resp_cb_data->cb)
941                                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
942                                 return;
943                         }
944                         /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level      */
945                         else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
946                                 ImcSimMetaInfo file_meta_new = {0,};
947
948                                 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
949                                 file_meta_new.file_id = TEL_SIM_EF_ELP;
950                                 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
951                                 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
952
953                                 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
954
955                                 __imc_sim_get_response(co, resp_cb_data);
956                         }
957                 }
958                 break;
959
960         case TEL_SIM_EF_USIM_PL:
961                 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
962                         dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
963                         __imc_sim_read_binary(co, resp_cb_data);
964                 } else {
965                         /* EFELIand EFPL not present, so set language count as zero and select ECC */
966                         dbg(
967                                 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
968                         if (resp_cb_data->cb)
969                                         resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
970                         return;
971                 }
972                 break;
973
974         case TEL_SIM_EF_ECC:
975                 tcore_sim_get_type(co, &card_type);
976                 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
977                         __imc_sim_read_binary(co, resp_cb_data);
978                 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
979                         if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) {
980                                 file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
981                         }
982                         file_meta->current_index++;
983                         __imc_sim_read_record(co, resp_cb_data);
984                 }
985                 break;
986
987         case TEL_SIM_EF_ICCID:
988         case TEL_SIM_EF_IMSI:
989         case TEL_SIM_EF_SST:
990         case TEL_SIM_EF_SPN:
991         case TEL_SIM_EF_SPDI:
992         case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
993         case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
994         case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
995         case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
996         case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
997         case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
998         case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
999         case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1000                 __imc_sim_read_binary(co, resp_cb_data);
1001                 break;
1002
1003         case TEL_SIM_EF_CPHS_CPHS_INFO:
1004                 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1005                         tcore_sim_set_cphs_status(co, TRUE);
1006                         __imc_sim_read_binary(co, resp_cb_data);
1007                 } else {
1008                         tcore_sim_set_cphs_status(co, FALSE);
1009                         if (resp_cb_data->cb)
1010                                 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1011                 }
1012                 break;
1013
1014
1015         case TEL_SIM_EF_USIM_CFIS:
1016                 if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) {
1017                         file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
1018                 }
1019                 file_meta->current_index++;
1020                 __imc_sim_read_record(co, resp_cb_data);
1021                 break;
1022
1023         case TEL_SIM_EF_MSISDN:
1024                 file_meta->files.data.msisdn_list.list =
1025                         tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
1026
1027         case TEL_SIM_EF_OPL:
1028         case TEL_SIM_EF_PNN:
1029         case TEL_SIM_EF_USIM_MWIS:
1030         case TEL_SIM_EF_USIM_MBI:
1031         case TEL_SIM_EF_MBDN:
1032         case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
1033         case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1034                 file_meta->current_index++;
1035                 __imc_sim_read_record(co, resp_cb_data);
1036                 break;
1037
1038         case TEL_SIM_EF_SMSP:
1039         {
1040                 ImcSimPrivateInfo *priv_info = NULL;
1041
1042                 priv_info = tcore_sim_ref_userdata(co);
1043
1044                 dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",file_meta->rec_count, file_meta->rec_length);
1045                 priv_info->smsp_count = file_meta->rec_count;
1046                 priv_info->smsp_rec_len = file_meta->rec_length;
1047                 break;
1048         }
1049
1050         default:
1051                 dbg("error - File id for get file info [0x%x]", file_meta->file_id);
1052                 break;
1053         }
1054         return;
1055 }
1056
1057 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data)
1058 {
1059         const TcoreAtResponse *resp = data;
1060         CoreObject *co_sim = NULL;
1061         GSList *tokens = NULL;
1062         TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
1063         const char *line;
1064         ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1065         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1066
1067         dbg("Entry");
1068
1069         co_sim = tcore_pending_ref_core_object(p);
1070
1071         dbg("file_id:[0x%x]", file_meta->file_id);
1072
1073         if (resp->success > 0) {
1074                 int sw1 = 0;
1075                 int sw2 = 0;
1076                 dbg("RESPONSE OK");
1077                 if (resp->lines) {
1078                         line = (const char *)resp->lines->data;
1079                         tokens = tcore_at_tok_new(line);
1080                         if (g_slist_length(tokens) != 2) {
1081                                 err("Invalid message");
1082                                 goto OUT;
1083                         }
1084                         sw1 = atoi(g_slist_nth_data(tokens, 0));
1085                         sw2 = atoi(g_slist_nth_data(tokens, 1));
1086                 }
1087
1088                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1089                         sim_result = TEL_SIM_RESULT_SUCCESS;
1090                 } else {
1091                         sim_result = __imc_sim_decode_status_word(sw1, sw2);
1092                 }
1093         } else {
1094                 err("RESPONSE NOK");
1095                 sim_result = TEL_SIM_RESULT_FAILURE;
1096         }
1097 OUT:
1098         /* Send Response */
1099         if (resp_cb_data->cb)
1100                 resp_cb_data->cb(co_sim, (gint)sim_result, NULL, resp_cb_data->cb_data);
1101
1102         tcore_at_tok_free(tokens);
1103         dbg("Exit");
1104 }
1105
1106 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len,
1107                                                         const void *data, void *user_data)
1108 {
1109         const TcoreAtResponse *resp = data;
1110         CoreObject *co = NULL;
1111         GSList *tokens = NULL;
1112         TelSimResult sim_result;
1113         gboolean dr = FALSE;
1114         const char *line = NULL;
1115         char *res = NULL;
1116         char *tmp = NULL;
1117         int res_len;
1118         int sw1 = 0;
1119         int sw2 = 0;
1120         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1121         ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1122         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1123
1124         dbg("Entry");
1125
1126         co = tcore_pending_ref_core_object(p);
1127
1128         if (resp->success > 0) {
1129                 dbg("RESPONSE OK");
1130                 if (resp->lines) {
1131                         line = (const char *)resp->lines->data;
1132                         tokens = tcore_at_tok_new(line);
1133                         if (g_slist_length(tokens) != 3) {
1134                                 err("Invalid message");
1135                                 tcore_at_tok_free(tokens);
1136                                 return;
1137                         }
1138                 }
1139                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1140                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1141                 res = g_slist_nth_data(tokens, 2);
1142
1143                 tmp = tcore_at_tok_extract(res);
1144                 tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
1145                 dbg("Response: [%s] Response length: [%d]", res, res_len);
1146
1147                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1148                         sim_result = TEL_SIM_RESULT_SUCCESS;
1149                         file_meta->files.result = sim_result;
1150
1151                         dbg("File ID: [0x%x]", file_meta->file_id);
1152                         switch (file_meta->file_id) {
1153                         case TEL_SIM_EF_IMSI: {
1154                                 dbg("Data: [%s]", res);
1155                                 dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
1156                                 if (dr == FALSE) {
1157                                         err("IMSI decoding failed");
1158                                 } else {
1159                                         __imc_sim_set_identity(co, &file_meta->imsi);
1160
1161                                         /* Update IMSI */
1162                                         tcore_sim_set_imsi(co, &file_meta->imsi);
1163                                 }
1164                         }
1165                         break;
1166
1167                         case TEL_SIM_EF_ICCID: {
1168                                 dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
1169                                                 file_meta->files.data.iccid);
1170                         }
1171                         break;
1172
1173                         case TEL_SIM_EF_ELP:            /* 2G EF - 2 bytes decoding */
1174                         case TEL_SIM_EF_USIM_LI:                /* 3G EF - 2 bytes decoding */
1175                         case TEL_SIM_EF_USIM_PL:                /* 3G EF - same as EFELP, so 2 byte decoding */
1176                         case TEL_SIM_EF_LP:             /* 1 byte encoding */
1177                         {
1178                                 tcore_sim_get_type(co, &card_type);
1179                                 if ((TEL_SIM_CARD_TYPE_GSM == card_type)
1180                                                 && (file_meta->file_id == TEL_SIM_EF_LP)) {
1181                                         /*
1182                                          * 2G LP(0x6F05) has 1 byte for each language
1183                                          */
1184                                         dr = tcore_sim_decode_lp((unsigned char *)res, res_len, &file_meta->files.data.language);
1185                                 } else {
1186                                         /*
1187                                          * 3G LI(0x6F05)/PL(0x2F05),
1188                                          * 2G ELP(0x2F05) has 2 bytes for each language
1189                                          */
1190                                         dr = tcore_sim_decode_li((unsigned char *)res, res_len,
1191                                                 file_meta->file_id, &file_meta->files.data.language);
1192                                 }
1193                         }
1194                         break;
1195
1196                         case TEL_SIM_EF_SPN:
1197                                 dr = tcore_sim_decode_spn((unsigned char *)res, res_len, &file_meta->files.data.spn);
1198                         break;
1199
1200                         case TEL_SIM_EF_SPDI:
1201                                 dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, &file_meta->files.data.spdi);
1202                         break;
1203
1204                         case TEL_SIM_EF_SST:
1205                         {
1206                                 TelSimServiceTable *svct = NULL;
1207
1208                                 svct = g_try_new0(TelSimServiceTable, 1);
1209                                 tcore_sim_get_type(co, &card_type);
1210                                 svct->sim_type = card_type;
1211                                 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1212                                         dr = tcore_sim_decode_sst((unsigned char *)res, res_len, svct->table.sst_service);
1213                                 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1214                                         dr = tcore_sim_decode_ust((unsigned char *)res, res_len, svct->table.ust_service);
1215                                 } else {
1216                                         err("Not handled card_type[%d]", card_type);
1217                                 }
1218
1219                                 if (dr == FALSE) {
1220                                         err("SST/UST decoding failed");
1221                                 } else {
1222                                         tcore_sim_set_service_table(co, svct);
1223                                 }
1224
1225                                 /* Free memory */
1226                                 g_free(svct);
1227                         }
1228                         break;
1229
1230                         case TEL_SIM_EF_ECC:
1231                         {
1232                                 tcore_sim_get_type(co, &card_type);
1233                                 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1234                                         dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, &file_meta->files.data.ecc);
1235                                 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1236                                         TelSimEcc *ecc = NULL;
1237
1238                                         ecc = g_try_new0(TelSimEcc, 1);
1239                                         dbg("Index [%d]", file_meta->current_index);
1240
1241                                         dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
1242                                         if (dr == TRUE) {
1243                                                 memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], ecc, sizeof(TelSimEcc));
1244                                                 file_meta->files.data.ecc.count++;
1245                                         }
1246
1247                                         /* Free memory */
1248                                         g_free(ecc);
1249                                 } else {
1250                                         dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
1251                                 }
1252                         }
1253                         break;
1254
1255                         case TEL_SIM_EF_MSISDN:
1256                         {
1257                                 TelSimSubscriberInfo *msisdn = NULL;
1258
1259                                 dbg("Index [%d]", file_meta->current_index);
1260                                 msisdn = tcore_malloc0(sizeof(TelSimSubscriberInfo));
1261                                 dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
1262                                 if (dr == TRUE) {
1263                                         memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
1264                                                                 msisdn, sizeof(TelSimSubscriberInfo));
1265
1266                                         file_meta->files.data.msisdn_list.count++;
1267                                 }
1268
1269                                 /* Free memory */
1270                                 dbg("Freeing resources");
1271                                 tcore_free(msisdn);
1272                         }
1273                         break;
1274
1275                         case TEL_SIM_EF_OPL:
1276                         {
1277                                 TelSimOpl *opl = NULL;
1278
1279                                 dbg("decode w/ index [%d]", file_meta->current_index);
1280                                 opl = g_try_new0(TelSimOpl, 1);
1281
1282                                 dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
1283                                 if (dr == TRUE) {
1284                                         memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
1285                                                         opl, sizeof(TelSimOpl));
1286
1287                                         file_meta->files.data.opl.opl_count++;
1288                                 }
1289
1290                                 /* Free memory */
1291                                 g_free(opl);
1292                         }
1293                         break;
1294
1295                         case TEL_SIM_EF_PNN:
1296                         {
1297                                 TelSimPnn *pnn = NULL;
1298
1299                                 dbg("decode w/ index [%d]", file_meta->current_index);
1300                                 pnn = g_try_new0(TelSimPnn, 1);
1301
1302                                 dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
1303                                 if (dr == TRUE) {
1304                                         memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
1305                                                                 pnn, sizeof(TelSimPnn));
1306
1307                                         file_meta->files.data.pnn.pnn_count++;
1308                                 }
1309
1310                                 /* Free memory */
1311                                 g_free(pnn);
1312                         }
1313                         break;
1314
1315                         case TEL_SIM_EF_OPLMN_ACT:
1316                                 /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1317                                                 (unsigned char *)res, res_len);*/
1318                         break;
1319
1320                         case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1321                                 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1322                                         p_data->response, p_data->response_len);*/
1323                         break;
1324
1325                         case TEL_SIM_EF_USIM_MBI:                       /* linear type */
1326                         {
1327                                 TelSimMbi *mbi = NULL;
1328
1329                                 mbi = g_try_new0(TelSimMbi, 1);
1330                                 dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
1331                                 if (dr == TRUE) {
1332                                         memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
1333                                                                                 mbi, sizeof(TelSimMbi));
1334                                         file_meta->mbi_list.count++;
1335
1336                                         dbg("mbi count[%d]", file_meta->mbi_list.count);
1337                                 }
1338
1339                                 /* Free memory */
1340                                 g_free(mbi);
1341                         }
1342                         break;
1343
1344                         case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:           /* linear type */
1345                         case TEL_SIM_EF_MBDN:                           /* linear type */
1346                                 dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
1347                                                                                 file_meta->mb_list[file_meta->current_index-1].alpha_id,
1348                                                                                 file_meta->mb_list[file_meta->current_index-1].number);
1349                                 file_meta->mb_list[file_meta->current_index-1].alpha_id_len = strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
1350                                 file_meta->mb_list[file_meta->current_index-1].profile_id = file_meta->current_index;
1351                         break;
1352
1353                         case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:         /* transparent type */
1354                                 dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1355                         break;
1356
1357                         case TEL_SIM_EF_USIM_MWIS: {                    /* linear type */
1358                                 TelSimMwis *mw = NULL;
1359
1360                                 mw = g_try_new0(TelSimMwis, 1);
1361
1362                                 dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
1363                                 if (dr == TRUE) {
1364                                         guint count = file_meta->files.data.mw.profile_count;
1365
1366                                         memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
1367
1368                                         /**
1369                                          * The Profile Identity shall be between 1 and 4 as defined
1370                                          * in TS 23.097 for MSP
1371                                          */
1372                                         file_meta->files.data.mw.mw[count].profile_id = count+1;
1373
1374                                         file_meta->files.data.mw.profile_count++;
1375                                 }
1376
1377                                 /* Free memory */
1378                                 g_free(mw);
1379                         }
1380                         break;
1381
1382                         case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:        /* transparent type */
1383                                 dr = tcore_sim_decode_cff((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1384                         break;
1385
1386                         case TEL_SIM_EF_USIM_CFIS:                      /* linear type */
1387                         {
1388                                 TelSimCfis *cf = NULL;
1389
1390                                 cf = g_try_new0(TelSimCfis, 1);
1391                                 dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
1392                                 if (dr == TRUE) {
1393                                         memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
1394                                                                         cf, sizeof(TelSimCfis));
1395                                         file_meta->files.data.cf.profile_count++;
1396                                 }
1397
1398                                 /* Free memory */
1399                                 g_free(cf);
1400                         }
1401                         break;
1402
1403                         case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
1404                                 dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1405                         break;
1406
1407                         case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1408                                 file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1409                                 dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
1410                                                                                 (unsigned char*)file_meta->files.data.cphs_net.full_name);
1411                                 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1412                                                 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1413                         break;
1414
1415                         case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1416                                 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1417                                                         p_data->response, p_data->response_len);*/
1418                         break;
1419
1420                         case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1421                                 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1422                                                         p_data->response_len);*/
1423                         break;
1424
1425                         case TEL_SIM_EF_CPHS_CPHS_INFO:
1426                                 /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1427                                                         (unsigned char *)res, res_len);*/
1428                         break;
1429
1430                         case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1431                                 file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
1432                                 dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
1433                                                                                 (unsigned char*)file_meta->files.data.cphs_net.short_name);
1434                                 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
1435                                                 file_meta->files.result, file_meta->files.data.cphs_net.short_name);
1436                         break;
1437
1438                         case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1439                                 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1440                         break;
1441
1442                         default:
1443                                 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1444                                 dr = 0;
1445                         break;
1446                         }
1447                 } else {
1448                         sim_result = __imc_sim_decode_status_word(sw1, sw2);
1449                         file_meta->files.result = sim_result;
1450                 }
1451
1452                 /* Free memory */
1453                 g_free(tmp);
1454                 g_free(res);
1455
1456                 /* Free tokens */
1457                 tcore_at_tok_free(tokens);
1458         } else {
1459                 err("RESPONSE NOK");
1460                 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1461                 sim_result = TEL_SIM_RESULT_FAILURE;
1462         }
1463
1464         /* Get File data */
1465         __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
1466
1467         dbg("Exit");
1468 }
1469
1470 static void __on_response_imc_sim_get_response(TcorePending *p,
1471         guint data_len, const void *data, void *user_data)
1472 {
1473         const TcoreAtResponse *resp = data;
1474         CoreObject *co = NULL;
1475         TelSimResult sim_result;
1476         GSList *tokens = NULL;
1477         const char *line = NULL;
1478         int sw1 = 0;
1479         int sw2 = 0;
1480         ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
1481         ImcSimMetaInfo *file_meta =
1482                 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1483
1484         dbg("SIM Response - SIM File info: [+CRSM]");
1485
1486         co = tcore_pending_ref_core_object(p);
1487
1488         if (resp->success > 0) {
1489                 dbg("RESPONSE OK");
1490                 if (resp->lines) {
1491                         line = (const char *)resp->lines->data;
1492                         tokens = tcore_at_tok_new(line);
1493                         if (g_slist_length(tokens) < 2) {
1494                                 err("Invalid message");
1495                                 tcore_at_tok_free(tokens);
1496                                 return;
1497                         }
1498                 }
1499                 sw1 = atoi(g_slist_nth_data(tokens, 0));
1500                 sw2 = atoi(g_slist_nth_data(tokens, 1));
1501
1502                 /*1. SIM access success case*/
1503                 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1504                         unsigned char tag_len = 0;
1505                         unsigned short record_len = 0;
1506                         char num_of_records = 0;
1507                         unsigned char file_id_len = 0;
1508                         unsigned short file_id = 0;
1509                         unsigned short file_size = 0;
1510                         unsigned short file_type = 0;
1511                         unsigned short arr_file_id = 0;
1512                         int arr_file_id_rec_num = 0;
1513                         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1514
1515                         /* handling only last 3 bits */
1516                         unsigned char file_type_tag = 0x07;
1517                         unsigned char *ptr_data;
1518
1519                         char *hexData;
1520                         char *tmp;
1521                         char *record_data = NULL;
1522                         guint record_data_len;
1523                         hexData = g_slist_nth_data(tokens, 2);
1524                         dbg("hexData: %s", hexData);
1525                         dbg("hexData: %s", hexData + 1);
1526
1527                         tmp = tcore_at_tok_extract(hexData);
1528                         tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
1529                         tcore_util_hex_dump("   ", record_data_len, record_data);
1530                         g_free(tmp);
1531
1532                         ptr_data = (unsigned char *)record_data;
1533                         tcore_sim_get_type(co, &card_type);
1534                         if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1535                                 /*
1536                                  ETSI TS 102 221 v7.9.0
1537                                  - Response Data
1538                                  '62'   FCP template tag
1539                                  - Response for an EF
1540                                  '82'   M       File Descriptor
1541                                  '83'   M       File Identifier
1542                                  'A5'   O       Proprietary information
1543                                  '8A'   M       Life Cycle Status Integer
1544                                  '8B', '8C' or 'AB' C1  Security attributes
1545                                  '80'   M       File size
1546                                  '81'   O       Total file size
1547                                  '88'   O       Short File Identifier (SFI)
1548                                  */
1549
1550                                 /* rsim.res_len has complete data length received */
1551
1552                                 /* FCP template tag - File Control Parameters tag*/
1553                                 if (*ptr_data == 0x62) {
1554                                         /* parse complete FCP tag*/
1555                                         /* increment to next byte */
1556                                         ptr_data++;
1557                                         tag_len = *ptr_data++;
1558                                         dbg("tag_len: %02x", tag_len);
1559                                         /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1560                                         if (*ptr_data == 0x82) {
1561                                                 /* increment to next byte */
1562                                                 ptr_data++;
1563                                                 /* 2 or 5 value*/
1564                                                 ptr_data++;
1565                                                 /* consider only last 3 bits*/
1566                                                 dbg("file_type_tag: %02x", file_type_tag);
1567                                                 file_type_tag = file_type_tag & (*ptr_data);
1568                                                 dbg("file_type_tag: %02x", file_type_tag);
1569
1570                                                 switch (file_type_tag) {
1571                                                 /* increment to next byte */
1572                                                 // ptr_data++;
1573                                                 case 0x1:
1574                                                         dbg("Getting FileType: [Transparent file type]");
1575                                                         file_type = IMC_SIM_FILE_TYPE_TRANSPARENT;
1576
1577                                                         /* increment to next byte */
1578                                                         ptr_data++;
1579                                                         /* increment to next byte */
1580                                                         ptr_data++;
1581                                                         break;
1582
1583                                                 case 0x2:
1584                                                         dbg("Getting FileType: [Linear fixed file type]");
1585                                                         /* increment to next byte */
1586                                                         ptr_data++;
1587                                                         /* data coding byte - value 21 */
1588                                                         ptr_data++;
1589                                                         /* 2bytes */
1590                                                         memcpy(&record_len, ptr_data, 2);
1591                                                         /* swap bytes */
1592                                                         IMC_SWAP_BYTES_16(record_len);
1593                                                         ptr_data = ptr_data + 2;
1594                                                         num_of_records = *ptr_data++;
1595                                                         /* Data lossy conversation from enum (int) to unsigned char */
1596                                                         file_type = IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1597                                                         break;
1598
1599                                                 case 0x6:
1600                                                         dbg("Cyclic fixed file type");
1601                                                         /* increment to next byte */
1602                                                         ptr_data++;
1603                                                         /* data coding byte - value 21 */
1604                                                         ptr_data++;
1605                                                         /* 2bytes */
1606                                                         memcpy(&record_len, ptr_data, 2);
1607                                                         /* swap bytes */
1608                                                         IMC_SWAP_BYTES_16(record_len);
1609                                                         ptr_data = ptr_data + 2;
1610                                                         num_of_records = *ptr_data++;
1611                                                         file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1612                                                         break;
1613
1614                                                 default:
1615                                                         dbg("not handled file type [0x%x]", *ptr_data);
1616                                                         break;
1617                                                 }
1618                                         } else {
1619                                                 dbg("INVALID FCP received - DEbug!");
1620                                                 tcore_at_tok_free(tokens);
1621                                                 g_free(record_data);
1622                                                 return;
1623                                         }
1624
1625                                         /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
1626                                         if (*ptr_data == 0x83) {
1627                                                 /* increment to next byte */
1628                                                 ptr_data++;
1629                                                 file_id_len = *ptr_data++;
1630                                                 dbg("file_id_len: %02x", file_id_len);
1631
1632                                                 memcpy(&file_id, ptr_data, file_id_len);
1633                                                 dbg("file_id: %x", file_id);
1634
1635                                                 /* swap bytes    */
1636                                                 IMC_SWAP_BYTES_16(file_id);
1637                                                 dbg("file_id: %x", file_id);
1638
1639                                                 ptr_data = ptr_data + 2;
1640                                                 dbg("Getting FileID=[0x%x]", file_id);
1641                                         } else {
1642                                                 dbg("INVALID FCP received - DEbug!");
1643                                                 tcore_at_tok_free(tokens);
1644                                                 g_free(record_data);
1645                                                 return;
1646                                         }
1647
1648                                         /* proprietary information */
1649                                         if (*ptr_data == 0xA5) {
1650                                                 unsigned short prop_len;
1651                                                 /* increment to next byte */
1652                                                 ptr_data++;
1653
1654                                                 /* length */
1655                                                 prop_len = *ptr_data;
1656                                                 dbg("prop_len: %02x", prop_len);
1657
1658                                                 /* skip data */
1659                                                 ptr_data = ptr_data + prop_len + 1;
1660                                         } else {
1661                                                 dbg("INVALID FCP received - DEbug!");
1662                                         }
1663
1664                                         /* life cycle status integer [8A][length:0x01][status]*/
1665                                         /*
1666                                          status info b8~b1
1667                                          00000000 : No information given
1668                                          00000001 : creation state
1669                                          00000011 : initialization state
1670                                          000001-1 : operation state -activated
1671                                          000001-0 : operation state -deactivated
1672                                          000011-- : Termination state
1673                                          b8~b5 !=0, b4~b1=X : Proprietary
1674                                          Any other value : RFU
1675                                          */
1676                                         if (*ptr_data == 0x8A) {
1677                                                 /* increment to next byte */
1678                                                 ptr_data++;
1679                                                 /* length - value 1 */
1680                                                 ptr_data++;
1681
1682                                                 switch (*ptr_data) {
1683                                                 case 0x04:
1684                                                 case 0x06:
1685                                                         dbg("<RX> operation state -deactivated");
1686                                                         ptr_data++;
1687                                                         break;
1688
1689                                                 case 0x05:
1690                                                 case 0x07:
1691                                                         dbg("<RX> operation state -activated");
1692                                                         ptr_data++;
1693                                                         break;
1694
1695                                                 default:
1696                                                         dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1697                                                         ptr_data++;
1698                                                         break;
1699                                                 }
1700                                         }
1701
1702                                         /* related to security attributes : currently not handled*/
1703                                         if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1704                                                 /* increment to next byte */
1705                                                 ptr_data++;
1706                                                 /* if tag length is 3 */
1707                                                 if (*ptr_data == 0x03) {
1708                                                         /* increment to next byte */
1709                                                         ptr_data++;
1710                                                         /* EFARR file id */
1711                                                         memcpy(&arr_file_id, ptr_data, 2);
1712                                                         /* swap byes */
1713                                                         IMC_SWAP_BYTES_16(arr_file_id);
1714                                                         ptr_data = ptr_data + 2;
1715                                                         arr_file_id_rec_num = *ptr_data++;
1716                                                         dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
1717                                                 } else {
1718                                                         /* if tag length is not 3 */
1719                                                         /* ignoring bytes       */
1720                                                         // ptr_data = ptr_data + 4;
1721                                                         dbg("Useless security attributes, so jump to next tag");
1722                                                         ptr_data = ptr_data + (*ptr_data + 1);
1723                                                 }
1724                                         } else {
1725                                                 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1726                                                 tcore_at_tok_free(tokens);
1727                                                 g_free(record_data);
1728                                                 return;
1729                                         }
1730
1731                                         dbg("Current ptr_data value is [%x]", *ptr_data);
1732
1733                                         /* file size excluding structural info*/
1734                                         if (*ptr_data == 0x80) {
1735                                                 /* for EF file size is body of file and for Linear or cyclic it is
1736                                                  * number of recXsizeof(one record)
1737                                                  */
1738                                                 /* increment to next byte */
1739                                                 ptr_data++;
1740                                                 /* length is 1 byte - value is 2 bytes or more */
1741                                                 ptr_data++;
1742                                                 memcpy(&file_size, ptr_data, 2);
1743                                                 /* swap bytes */
1744                                                 IMC_SWAP_BYTES_16(file_size);
1745                                                 ptr_data = ptr_data + 2;
1746                                         } else {
1747                                                 dbg("INVALID FCP received - DEbug!");
1748                                                 tcore_at_tok_free(tokens);
1749                                                 g_free(record_data);
1750                                                 return;
1751                                         }
1752
1753                                         /* total file size including structural info*/
1754                                         if (*ptr_data == 0x81) {
1755                                                 int len;
1756                                                 /* increment to next byte */
1757                                                 ptr_data++;
1758                                                 /* length */
1759                                                 len = *ptr_data;
1760                                                 dbg("len:[%d]", len);
1761                                                 /* ignored bytes */
1762                                                 ptr_data = ptr_data + 3;
1763                                         } else {
1764                                                 dbg("INVALID FCP received - DEbug!");
1765                                                 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1766                                         }
1767                                         /*short file identifier ignored*/
1768                                         if (*ptr_data == 0x88) {
1769                                                 dbg("0x88: Do Nothing");
1770                                                 /*DO NOTHING*/
1771                                         }
1772                                 } else {
1773                                         dbg("INVALID FCP received - DEbug!");
1774                                         tcore_at_tok_free(tokens);
1775                                         g_free(record_data);
1776                                         return;
1777                                 }
1778                         } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1779                                 unsigned char gsm_specific_file_data_len = 0;
1780                                 /* ignore RFU byte1 and byte2 */
1781                                 ptr_data++;
1782                                 ptr_data++;
1783                                 /* file size */
1784                                 // file_size = p_info->response_len;
1785                                 memcpy(&file_size, ptr_data, 2);
1786                                 /* swap bytes */
1787                                 IMC_SWAP_BYTES_16(file_size);
1788                                 /* parsed file size */
1789                                 ptr_data = ptr_data + 2;
1790                                 /* file id */
1791                                 memcpy(&file_id, ptr_data, 2);
1792                                 IMC_SWAP_BYTES_16(file_id);
1793                                 dbg("FILE id --> [%x]", file_id);
1794                                 ptr_data = ptr_data + 2;
1795                                 /* save file type - transparent, linear fixed or cyclic */
1796                                 file_type_tag = (*(ptr_data + 7));
1797
1798                                 switch (*ptr_data) {
1799                                 case 0x0:
1800                                         /* RFU file type */
1801                                         dbg("RFU file type- not handled - Debug!");
1802                                         break;
1803
1804                                 case 0x1:
1805                                         /* MF file type */
1806                                         dbg("MF file type - not handled - Debug!");
1807                                         break;
1808
1809                                 case 0x2:
1810                                         /* DF file type */
1811                                         dbg("DF file type - not handled - Debug!");
1812                                         break;
1813
1814                                 case 0x4:
1815                                         /* EF file type */
1816                                         dbg("EF file type [%d] ", file_type_tag);
1817                                         /*      increment to next byte */
1818                                         ptr_data++;
1819
1820                                         if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1821                                                 /* increament to next byte as this byte is RFU */
1822                                                 ptr_data++;
1823                                                 file_type =
1824                                                         (file_type_tag == 0x00) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1825                                         } else {
1826                                                 /* increment to next byte */
1827                                                 ptr_data++;
1828                                                 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1829                                                 /* the INCREASE command is allowed on the selected cyclic file. */
1830                                                 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1831                                         }
1832                                         /* bytes 9 to 11 give SIM file access conditions */
1833                                         ptr_data++;
1834                                         /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1835                                         ptr_data++;
1836                                         /* byte 11 is invalidate and rehabilate nibbles */
1837                                         ptr_data++;
1838                                         /* byte 12 - file status */
1839                                         ptr_data++;
1840                                         /* byte 13 - GSM specific data */
1841                                         gsm_specific_file_data_len = *ptr_data;
1842                                         dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
1843                                         ptr_data++;
1844                                         /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1845                                         ptr_data++;
1846                                         /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1847                                         record_len = *ptr_data;
1848                                         dbg("record length[%d], file size[%d]", record_len, file_size);
1849                                         if (record_len != 0)
1850                                                 num_of_records = (file_size / record_len);
1851
1852                                         dbg("Number of records [%d]", num_of_records);
1853                                         break;
1854
1855                                 default:
1856                                         dbg("not handled file type");
1857                                         break;
1858                                 }
1859                         } else {
1860                                 err("Unknown Card Type - [%d]", card_type);
1861                         }
1862
1863                         dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1864                                 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1865
1866                         file_meta->file_type = file_type;
1867                         file_meta->data_size = file_size;
1868                         file_meta->rec_length = record_len;
1869                         file_meta->rec_count = num_of_records;
1870                         file_meta->current_index = 0;           /* reset for new record type EF */
1871                         sim_result = TEL_SIM_RESULT_SUCCESS;
1872                         g_free(record_data);
1873                 } else {
1874                         /*2. SIM access fail case*/
1875                         err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1876                         sim_result = __imc_sim_decode_status_word(sw1, sw2);
1877                 }
1878
1879                 tcore_at_tok_free(tokens);
1880         } else {
1881                 err("RESPONSE NOK");
1882                 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1883                 sim_result = TEL_SIM_RESULT_FAILURE;
1884         }
1885
1886         dbg("Calling __imc_sim_next_from_get_response");
1887         __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
1888         dbg("Exit");
1889 }
1890
1891 static TelReturn __imc_sim_update_file(CoreObject *co, ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
1892                                         int p1, int p2, int p3, char *encoded_data)
1893 {
1894         char *cmd_str = NULL;
1895         TelReturn ret = TEL_RETURN_FAILURE;
1896         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1897
1898         dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1899
1900         cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
1901
1902         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CRSM:",
1903                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1904                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1905                                                 __on_response_imc_sim_update_file, resp_cb_data,
1906                                                 on_send_imc_request, NULL, 0, NULL, NULL);
1907
1908         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
1909
1910         tcore_free(encoded_data);
1911         g_free(cmd_str);
1912
1913         dbg("Exit");
1914         return ret;
1915 }
1916 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
1917 {
1918         gchar *at_cmd = NULL;
1919         int p1 = 0;
1920         int p2 = 0;
1921         int p3 = 0;
1922         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1923         TelReturn ret = TEL_RETURN_FAILURE;
1924
1925         dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1926
1927         /* According to TS 102 221, values of p1, p2, p3 can be as below:
1928          * 11.1.5 READ RECORD
1929          * P1: Record number
1930          * P2: Mode, see table 11.11
1931          * Lc: Not present
1932          * Data: Not present
1933          * Le: Number of bytes to be read (P3)
1934          */
1935
1936         p1 = (unsigned char) file_meta->current_index;
1937         p2 = (unsigned char) 0x04;                      /* 0x4 for absolute mode */
1938         p3 = (unsigned char) file_meta->rec_length;
1939
1940         at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1941                                 IMC_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
1942
1943         ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
1944                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1945                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1946                                                 __on_response_imc_sim_read_data, resp_cb_data,
1947                                                 on_send_imc_request, NULL, 0, NULL, NULL);
1948
1949         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
1950
1951         dbg("ret:[%d]", ret);
1952         g_free(at_cmd);
1953
1954         dbg("Exit");
1955 }
1956
1957 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
1958 {
1959         gchar *at_cmd = NULL;
1960         int p1 = 0;
1961         int p2 = 0;
1962         int p3 = 0;
1963         int offset = 0;
1964         ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1965         TelReturn ret = TEL_RETURN_FAILURE;
1966
1967         dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1968
1969         /* According to TS 102 221, values of P1, P2, P3 can be as below:
1970          * 11.1.3 READ BINARY
1971          * P1: See table 11.10
1972          * P2: Offset low
1973          * Lc: Not present
1974          * Data: Not present
1975          * Le: Number of bytes to be read (P3)
1976          */
1977
1978         p1 = (unsigned char) (offset & 0xFF00) >> 8;
1979         p2 = (unsigned char) offset & 0x00FF;                   /* offset low */
1980         p3 = (unsigned char) file_meta->data_size;
1981
1982         at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1983                                 IMC_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
1984
1985         ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
1986                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1987                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1988                                                 __on_response_imc_sim_read_data, resp_cb_data,
1989                                                 on_send_imc_request, NULL, 0, NULL, NULL);
1990
1991         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
1992
1993         dbg("ret:[%d]", ret);
1994         g_free(at_cmd);
1995
1996         dbg("Exit");
1997 }
1998
1999 static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
2000 {
2001         gchar *at_cmd = NULL;
2002         ImcSimMetaInfo *file_meta =
2003                 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2004         TelReturn ret = TEL_RETURN_FAILURE;
2005
2006         dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2007
2008         at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
2009                 IMC_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
2010
2011         ret = tcore_at_prepare_and_send_request(co,
2012                                 at_cmd, "+CRSM:",
2013                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2014                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
2015                                 __on_response_imc_sim_get_response, resp_cb_data,
2016                                 on_send_imc_request, NULL,
2017                                 0, NULL, NULL);
2018         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
2019
2020         g_free(at_cmd);
2021         dbg("Exit");
2022         return ret;
2023 }
2024
2025 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
2026                         const void *data, void *user_data)
2027 {
2028         TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
2029         const TcoreAtResponse *at_resp = data;
2030         ImcRespCbData *resp_cb_data = user_data;
2031         CoreObject *co = tcore_pending_ref_core_object(p);
2032         ImcSimCurrSecOp *sec_op = NULL;
2033         GSList *tokens = NULL;
2034         const char *line = NULL;
2035         int lock_type = 0;
2036         int attempts_left = 0;
2037         int time_penalty = 0;
2038
2039         dbg("Entry");
2040
2041         tcore_check_return_assert(co != NULL);
2042         tcore_check_return_assert(resp_cb_data != NULL);
2043
2044         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2045
2046         if (at_resp && at_resp->success) {
2047                 dbg("Sim Get Retry Count [OK]");
2048
2049                 if (at_resp->lines) {
2050                         line = (const char *)at_resp->lines->data;
2051                         tokens = tcore_at_tok_new(line);
2052                         if (g_slist_length(tokens) < 3) {
2053                                 err("Invalid message");
2054                                 goto Failure;
2055                         }
2056                 }
2057                 lock_type = atoi(g_slist_nth_data(tokens, 0));
2058                 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2059                 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2060
2061                 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2062                         lock_type, attempts_left, time_penalty);
2063
2064                 switch (*sec_op) {
2065                         case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2066                         case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2067                         {
2068                                 TelSimSecPinResult verify_pin = {0, };
2069
2070                                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
2071                                         verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2072                                 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
2073                                         verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2074
2075                                 verify_pin.retry_count = attempts_left;
2076
2077                                 if(resp_cb_data->cb)
2078                                         resp_cb_data->cb(co, (gint)result,
2079                                                 &verify_pin, resp_cb_data->cb_data);
2080                                 break;
2081                         }
2082                         case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2083                         case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2084                         {
2085                                 TelSimSecPukResult verify_puk = {0, };
2086
2087                                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
2088                                         verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2089                                 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
2090                                         verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2091
2092                                 verify_puk.retry_count = attempts_left;
2093
2094                                 if(resp_cb_data->cb)
2095                                         resp_cb_data->cb(co, (gint)result,
2096                                                 &verify_puk, resp_cb_data->cb_data);
2097                                 break;
2098                         }
2099                         case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2100                         case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2101                         {
2102                                 TelSimSecPinResult change_pin = {0, };
2103
2104                                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
2105                                         change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2106                                 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
2107                                         change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2108
2109                                 change_pin.retry_count = attempts_left;
2110
2111                                 if(resp_cb_data->cb)
2112                                         resp_cb_data->cb(co, (gint)result,
2113                                                 &change_pin, resp_cb_data->cb_data);
2114                                 break;
2115                         }
2116                         case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2117                         case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2118                         case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2119                         case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
2120                         case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2121                         case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2122                         case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2123                         case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2124                         {
2125                                 TelSimFacilityResult disable_facility = {0, };
2126                                 int lock_type;
2127
2128                                 lock_type = __imc_sim_get_lock_type(*sec_op);
2129                                 if (lock_type == -1)
2130                                         goto Failure;
2131
2132                                 disable_facility.type = lock_type;
2133                                 disable_facility.retry_count = attempts_left;
2134
2135                                 if(resp_cb_data->cb)
2136                                         resp_cb_data->cb(co, (gint)result,
2137                                                 &disable_facility, resp_cb_data->cb_data);
2138                                 break;
2139                         }
2140                         case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2141                         case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2142                         case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2143                         case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
2144                         case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2145                         case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2146                         case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2147                         case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2148                         {
2149                                 TelSimFacilityResult enable_facility = {0, };
2150                                 int lock_type;
2151
2152                                 lock_type = __imc_sim_get_lock_type(*sec_op);
2153                                 if (lock_type == -1)
2154                                         goto Failure;
2155
2156                                 enable_facility.type = lock_type;
2157                                 enable_facility.retry_count = attempts_left;
2158
2159                                 if(resp_cb_data->cb)
2160                                         resp_cb_data->cb(co, (gint)result,
2161                                                 &enable_facility, resp_cb_data->cb_data);
2162                                 break;
2163                         }
2164                         default:
2165                                 err("Unhandled sec op [%d]", *sec_op);
2166                         break;
2167                 }
2168
2169                 tcore_at_tok_free(tokens);
2170                 imc_destroy_resp_cb_data(resp_cb_data);
2171                 return;
2172         }
2173         err("Sim Get Retry Count [NOK]");
2174 Failure :
2175         /*TODO - send response for verify pin, puk etc.,
2176         * when get_retry_count fails
2177         */
2178         tcore_at_tok_free(tokens);
2179         imc_destroy_resp_cb_data(resp_cb_data);
2180 }
2181
2182 static TelReturn __imc_sim_get_retry_count(CoreObject *co,
2183                         ImcRespCbData *resp_cb_data)
2184 {
2185         TelReturn ret = TEL_RETURN_FAILURE;
2186         ImcSimCurrSecOp *sec_op = (
2187                 ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2188         int lock_type = 0;
2189         gchar *cmd_str = NULL;
2190
2191         dbg("Entry");
2192
2193         switch (*sec_op) {
2194                 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2195                 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2196                 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2197                 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2198                         lock_type = 1;
2199                         break;
2200                 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2201                 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2202                 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2203                 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2204                 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2205                 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2206                         lock_type = 2;
2207                         break;
2208                 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2209                         lock_type = 3;
2210                         break;
2211                 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2212                         lock_type = 4;
2213                         break;
2214                 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2215                 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2216                         lock_type = 5;
2217                         break;
2218                 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2219                 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2220                         lock_type = 6;
2221                         break;
2222                 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2223                 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2224                         lock_type = 7;
2225                         break;
2226                 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2227                 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2228                         lock_type = 8;
2229                         break;
2230                 case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
2231                         lock_type = 9;
2232                         break;
2233                 default:
2234                         break;
2235                 }
2236         cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2237
2238         ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
2239                                         TCORE_AT_COMMAND_TYPE_SINGLELINE,
2240                                         TCORE_PENDING_PRIORITY_DEFAULT,
2241                                         NULL,
2242                                         __on_response_imc_sim_get_retry_count,
2243                                         resp_cb_data,
2244                                         on_send_imc_request,
2245                                         NULL, 0, NULL, NULL);
2246
2247         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
2248         g_free(cmd_str);
2249         return ret;
2250 }
2251
2252 static TelSimLockType __imc_sim_lock_type(int lock_type)
2253 {
2254         switch(lock_type) {
2255                 case 1 :
2256                         return TEL_SIM_LOCK_SC;
2257                 case 2 :
2258                         return TEL_SIM_LOCK_FD;
2259                 case 5 :
2260                         return TEL_SIM_LOCK_PN;
2261                 case 6 :
2262                         return TEL_SIM_LOCK_PU;
2263                 case 7 :
2264                         return TEL_SIM_LOCK_PP;
2265                 case 8 :
2266                         return TEL_SIM_LOCK_PC ;
2267                 case 9 :
2268                         return TEL_SIM_LOCK_PS ;
2269                 default :
2270                         err("Invalid lock_type [%d]", lock_type);
2271                         return -1;
2272         }
2273 }
2274
2275 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
2276                 ImcSimCurrSecOp *sec_op, int flag)
2277 {
2278         char *fac = NULL;
2279         switch(lock_type) {
2280                 case TEL_SIM_LOCK_PS :
2281                         fac = "PS";
2282                         if (flag == ENABLE_FLAG)
2283                                 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
2284                         else if (flag == DISABLE_FLAG)
2285                                 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
2286                         else
2287                                 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
2288                         break;
2289                 case TEL_SIM_LOCK_SC :
2290                         fac = "SC";
2291                         if (flag == ENABLE_FLAG)
2292                                 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
2293                         else if (flag == DISABLE_FLAG)
2294                                 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
2295                         else
2296                                 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
2297                         break;
2298                 case TEL_SIM_LOCK_FD :
2299                         fac = "FD";
2300                         if (flag == ENABLE_FLAG)
2301                                 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
2302                         else if (flag == DISABLE_FLAG)
2303                                 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
2304                         else
2305                                 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
2306                         break;
2307                 case TEL_SIM_LOCK_PN :
2308                         fac = "PN";
2309                         if (flag == ENABLE_FLAG)
2310                                 *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
2311                         else if (flag == DISABLE_FLAG)
2312                                 *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
2313                         else
2314                                 *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
2315                         break;
2316                 case TEL_SIM_LOCK_PU :
2317                         fac = "PU";
2318                         if (flag == ENABLE_FLAG)
2319                                 *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
2320                         else if (flag == DISABLE_FLAG)
2321                                 *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
2322                         else
2323                                 *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
2324                         break;
2325                 case TEL_SIM_LOCK_PP :
2326                         fac = "PP";
2327                         if (flag == ENABLE_FLAG)
2328                                 *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
2329                         else if (flag == DISABLE_FLAG)
2330                                 *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
2331                         else
2332                                 *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
2333                         break;
2334                 case TEL_SIM_LOCK_PC :
2335                         fac = "PC";
2336                         if (flag == ENABLE_FLAG)
2337                                 *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
2338                         else if (flag == DISABLE_FLAG)
2339                                 *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
2340                         else
2341                                 *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
2342                         break;
2343                 default :
2344                         err("Unhandled sim lock type [%d]", lock_type);
2345         }
2346         return fac;
2347 }
2348
2349 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
2350 {
2351         switch(sec_op) {
2352                 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
2353                 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
2354                 case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
2355                         return TEL_SIM_LOCK_PS;
2356                 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
2357                 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
2358                 case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
2359                         return TEL_SIM_LOCK_SC;
2360                 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
2361                 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
2362                 case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
2363                         return TEL_SIM_LOCK_FD;
2364                 case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
2365                 case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
2366                 case IMC_SIM_CURR_SEC_OP_NET_STATUS :
2367                         return TEL_SIM_LOCK_PN;
2368                 case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
2369                 case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
2370                 case IMC_SIM_CURR_SEC_OP_NS_STATUS :
2371                         return TEL_SIM_LOCK_PU;
2372                 case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
2373                 case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
2374                 case IMC_SIM_CURR_SEC_OP_SP_STATUS :
2375                         return TEL_SIM_LOCK_PP;
2376                 case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
2377                 case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
2378                 case IMC_SIM_CURR_SEC_OP_CP_STATUS :
2379                         return TEL_SIM_LOCK_PC ;
2380                 default :
2381                         err("Invalid sec op [%d]", sec_op);
2382                         return -1;
2383         }
2384 }
2385
2386 /* Notifications */
2387 /*
2388  * Notification: +XSIM: <SIM state>
2389  *
2390  * Possible values of <SIM state> can be
2391  * 0    SIM not present
2392  * 1    PIN verification needed
2393  * 2    PIN verification not needed - Ready
2394  * 3    PIN verified - Ready
2395  * 4    PUK verification needed
2396  * 5    SIM permanently blocked
2397  * 6    SIM Error
2398  * 7    ready for attach (+COPS)
2399  * 8    SIM Technical Problem
2400  * 9    SIM Removed
2401  * 10   SIM Reactivating
2402  * 11   SIM Reactivated
2403  * 12   SIM SMS Caching Completed. (Sent only when SMS caching enabled)
2404  * 99   SIM State Unknown
2405  */
2406 static gboolean on_notification_imc_sim_status(CoreObject *co,
2407         const void *event_info, void *user_data)
2408 {
2409         GSList *lines = (GSList *)event_info;
2410         const gchar *line;
2411
2412         dbg("SIM notification - SIM status: [+XSIM]");
2413
2414         if (g_slist_length(lines) != 1) {
2415                 err("+XSIM unsolicited message expected to be "
2416                         "Single line but received multiple lines");
2417                 return TRUE;
2418         }
2419
2420         line = (const gchar *) (lines->data);
2421         if (line != NULL) {
2422                 GSList *tokens;
2423                 guint sim_state;
2424
2425                 /*
2426                  * Tokenize
2427                  *
2428                  * +XSIM: <SIM state>
2429                  */
2430                 tokens = tcore_at_tok_new(line);
2431                 if (g_slist_length(tokens) == 1) {
2432                         /* <SIM state> */
2433                         sim_state = atoi(g_slist_nth_data(tokens, 0));
2434
2435                         /* Process SIM Status */
2436                         __imc_sim_process_sim_status(co, sim_state);
2437                 } else {
2438                         err("Invalid message");
2439                 }
2440
2441                 tcore_at_tok_free(tokens);
2442         }
2443
2444         return TRUE;
2445 }
2446
2447 /* Hooks */
2448 static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
2449         TcoreNotification command, guint data_len, void *data, void *user_data)
2450 {
2451         CoreObject *co = (CoreObject *)user_data;
2452
2453         tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
2454
2455         dbg("Get SIM status");
2456         (void)__imc_sim_get_sim_status(co, NULL, NULL);
2457
2458         return TCORE_HOOK_RETURN_CONTINUE;
2459 }
2460
2461 /* Response Functions */
2462 static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
2463                         const void *data, void *user_data)
2464 {
2465         const TcoreAtResponse *at_resp = data;
2466         GSList *tokens = NULL;
2467         CoreObject *co = tcore_pending_ref_core_object(p);
2468         TelSimAuthenticationResponse auth_resp = {0, };
2469         TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
2470         ImcRespCbData *resp_cb_data = user_data;
2471         TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2472
2473         dbg("Entry");
2474
2475         if (NULL == at_resp) {
2476                 err("at_resp is NULL");
2477                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2478                 goto out;
2479         }
2480
2481         auth_resp.auth_type = *auth_type;
2482
2483         if (at_resp->success == TRUE) {
2484                 const char *line;
2485                 int status;
2486
2487                 dbg("RESPONSE OK");
2488                 if (at_resp->lines != NULL) {
2489                         line = at_resp->lines->data;
2490                         dbg("Received data: [%s]", line);
2491                 } else {
2492                         err("at_resp->lines is NULL");
2493                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2494                         goto out;
2495                 }
2496
2497                 tokens = tcore_at_tok_new(line);
2498                 if (tokens == NULL) {
2499                         err("tokens is NULL");
2500                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2501                         goto out;
2502                 }
2503
2504                 status = atoi(g_slist_nth_data(tokens, 0));
2505                 switch (status) {
2506                 case 0:
2507                         dbg("Authentications successful");
2508                         auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
2509                         break;
2510                 case 1:
2511                         err("Synchronize fail");
2512                         auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
2513                         goto out;
2514                 case 2:
2515                         err("MAC wrong");
2516                         auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
2517                         goto out;
2518                 case 3:
2519                         err("Does not support security context");
2520                         auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
2521                         goto out;
2522                 default:
2523                         err("Other failure");
2524                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2525                         goto out;
2526                 }
2527
2528                 if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
2529                         char *kc, *sres;
2530                         char *convert_kc, *convert_sres;
2531
2532                         kc = g_slist_nth_data(tokens, 1);
2533                         if (kc != NULL) {
2534                                 guint convert_kc_len = 0;
2535                                 kc = tcore_at_tok_extract(kc);
2536                                 dbg("Kc: [%s]", kc);
2537
2538                                 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2539                                 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2540                                         auth_resp.authentication_key_length = convert_kc_len;
2541                                         memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2542                                 } else {
2543                                         err("Invalid Kc");
2544                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2545                                 }
2546                                 g_free(kc);
2547                                 g_free(convert_kc);
2548                         } else {
2549                                 err("Invalid Kc");
2550                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2551                                 goto out;
2552                         }
2553
2554                         sres = g_slist_nth_data(tokens, 2);
2555                         if (sres != NULL) {
2556                                 guint convert_sres_len = 0;
2557                                 sres = tcore_at_tok_extract(sres);
2558                                 dbg("SRES: [%s]", sres);
2559
2560                                 tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
2561                                 if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2562                                         auth_resp.resp_length = convert_sres_len;
2563                                         memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
2564                                 } else {
2565                                         err("Invalid SRES");
2566                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2567                                 }
2568                                 g_free(sres);
2569                                 g_free(convert_sres);
2570                         } else {
2571                                 err("Invalid SRES");
2572                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2573                                 goto out;
2574                         }
2575                 } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
2576                         char *res, *ck, *ik, *kc;
2577                         char *convert_res, *convert_ck;
2578                         char *convert_ik, *convert_kc;
2579
2580                         res = g_slist_nth_data(tokens, 1);
2581                         if (res != NULL) {
2582                                 guint convert_res_len = 0;
2583                                 res = tcore_at_tok_extract(res);
2584                                 dbg("RES/AUTS: [%s]", res);
2585
2586                                 tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
2587                                 if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2588                                         auth_resp.resp_length = convert_res_len;
2589                                         memcpy(auth_resp.resp_data, convert_res, convert_res_len);
2590                                 } else {
2591                                         err("Invalid RES/AUTS");
2592                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2593                                 }
2594                                 g_free(res);
2595                                 g_free(convert_res);
2596                         } else {
2597                                 err("Invalid RES/AUTS");
2598                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2599                                 goto out;
2600                         }
2601
2602                         ck = g_slist_nth_data(tokens, 2);
2603                         if (ck != NULL) {
2604                                 guint convert_ck_len = 0;
2605                                 ck = tcore_at_tok_extract(ck);
2606                                 dbg("CK: [%s]", ck);
2607
2608                                 tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
2609                                 if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2610                                         auth_resp.cipher_length = convert_ck_len;
2611                                         memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
2612                                 } else {
2613                                         err("Invalid CK");
2614                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2615                                 }
2616                                 g_free(ck);
2617                                 g_free(convert_ck);
2618                         } else {
2619                                 err("Invalid CK");
2620                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2621                                 goto out;
2622                         }
2623
2624                         ik = g_slist_nth_data(tokens, 3);
2625                         if (ik != NULL) {
2626                                 guint convert_ik_len = 0;
2627                                 ik = tcore_at_tok_extract(ik);
2628                                 dbg("IK: [%s]", ik);
2629
2630                                 tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
2631                                 if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2632                                         auth_resp.integrity_length = convert_ik_len;
2633                                         memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
2634                                 } else {
2635                                         err("Invalid IK");
2636                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2637                                 }
2638                                 g_free(ik);
2639                                 g_free(convert_ik);
2640                         } else {
2641                                 err("Invalid IK");
2642                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2643                                 goto out;
2644                         }
2645
2646                         kc = g_slist_nth_data(tokens, 4);
2647                         if (kc != NULL) {
2648                                 guint convert_kc_len = 0;
2649                                 kc = tcore_at_tok_extract(kc);
2650                                 dbg("Kc: [%s]", kc);
2651
2652                                 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2653                                 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2654                                         auth_resp.authentication_key_length = convert_kc_len;
2655                                         memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2656                                 } else {
2657                                         err("Invalid Kc");
2658                                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2659                                 }
2660                                 g_free(kc);
2661                                 g_free(convert_kc);
2662                         } else {
2663                                 err("Invalid Kc");
2664                                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2665                                 goto out;
2666                         }
2667                 } else {
2668                         err("Not supported");
2669                         auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2670                         goto out;
2671                 }
2672                 sim_result = TEL_SIM_RESULT_SUCCESS;
2673         } else {
2674                 err("RESPONSE NOK");
2675                 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2676         }
2677
2678 out:
2679         if(resp_cb_data->cb)
2680                 resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
2681
2682         tcore_at_tok_free(tokens);
2683 }
2684
2685 static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
2686                 const void *data, void *user_data)
2687 {
2688         const TcoreAtResponse *at_resp = data;
2689         ImcRespCbData *resp_cb_data = user_data;
2690         CoreObject *co = tcore_pending_ref_core_object(p);
2691         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2692         ImcSimCurrSecOp *sec_op = NULL;
2693         TelSimSecPinResult verify_pin_resp = {0, };
2694
2695         dbg("Entry");
2696
2697         tcore_check_return_assert(co != NULL);
2698         tcore_check_return_assert(resp_cb_data != NULL);
2699
2700         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2701
2702         if (at_resp && at_resp->success) {
2703                 dbg("Sim Verify Pin Response- [OK]");
2704
2705                 result = TEL_SIM_RESULT_SUCCESS;
2706
2707                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
2708                         TelSimCardStatus status;
2709
2710                         verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2711
2712                         tcore_sim_get_status(co, &status);
2713                         if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
2714                                 /*Update sim status*/
2715                                 __imc_sim_update_sim_status(co,
2716                                         TEL_SIM_STATUS_SIM_INITIALIZING);
2717                         }
2718                 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
2719                         verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2720                 }
2721
2722                 /*Invoke callback*/
2723                 if(resp_cb_data->cb)
2724                         resp_cb_data->cb(co, (gint)result,
2725                                         &verify_pin_resp,
2726                                         resp_cb_data->cb_data);
2727                 imc_destroy_resp_cb_data(resp_cb_data);
2728         } else {
2729                 err("Sim Verify Pin Response- [NOK]");
2730                 /* Get retry count */
2731                 __imc_sim_get_retry_count(co, resp_cb_data);
2732         }
2733 }
2734
2735 static void on_response_imc_sim_verify_puks(TcorePending *p, guint data_len,
2736                 const void *data, void *user_data)
2737 {
2738         const TcoreAtResponse *at_resp = data;
2739         ImcRespCbData *resp_cb_data = user_data;
2740         CoreObject *co = tcore_pending_ref_core_object(p);
2741         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2742         ImcSimCurrSecOp *sec_op = NULL;
2743         TelSimSecPukResult verify_puk_resp = {0, };
2744
2745         dbg("Entry");
2746
2747         tcore_check_return_assert(co != NULL);
2748         tcore_check_return_assert(resp_cb_data != NULL);
2749
2750         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2751
2752         if (at_resp && at_resp->success) {
2753                 dbg("Sim Verify Puk Response- [OK]");
2754
2755                 result = TEL_SIM_RESULT_SUCCESS;
2756
2757                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
2758                         verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2759                 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
2760                         verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2761                 }
2762                 /*Invoke callback*/
2763                 if(resp_cb_data->cb)
2764                         resp_cb_data->cb(co, (gint)result,
2765                                         &verify_puk_resp,
2766                                         resp_cb_data->cb_data);
2767                 imc_destroy_resp_cb_data(resp_cb_data);
2768         } else {
2769                 err("Sim Verify Puk Response- [NOK]");
2770                 /* Get retry count */
2771                 __imc_sim_get_retry_count(co, resp_cb_data);
2772         }
2773 }
2774
2775 static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
2776                 const void *data, void *user_data)
2777 {
2778         const TcoreAtResponse *at_resp = data;
2779         ImcRespCbData *resp_cb_data = user_data;
2780         CoreObject *co = tcore_pending_ref_core_object(p);
2781         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2782         ImcSimCurrSecOp *sec_op = NULL;
2783         TelSimSecPinResult change_pin_resp = {0, };
2784
2785         dbg("Entry");
2786
2787         tcore_check_return_assert(co != NULL);
2788         tcore_check_return_assert(resp_cb_data != NULL);
2789
2790         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2791
2792         if (at_resp && at_resp->success) {
2793                 dbg("Sim Change Pin Response- [OK]");
2794
2795                 result = TEL_SIM_RESULT_SUCCESS;
2796
2797                 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
2798                         change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2799                 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE) {
2800                         change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2801                 }
2802                 /*Invoke callback*/
2803                 if(resp_cb_data->cb)
2804                         resp_cb_data->cb(co, (gint)result,
2805                                         &change_pin_resp,
2806                                         resp_cb_data->cb_data);
2807                 imc_destroy_resp_cb_data(resp_cb_data);
2808         } else {
2809                 err("Sim Change Pin Response- [NOK]");
2810                 /* Get retry count */
2811                 __imc_sim_get_retry_count(co, resp_cb_data);
2812         }
2813 }
2814
2815 static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
2816                 const void *data, void *user_data)
2817 {
2818         const TcoreAtResponse *at_resp = data;
2819         ImcRespCbData *resp_cb_data = user_data;
2820         CoreObject *co = tcore_pending_ref_core_object(p);
2821         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2822         ImcSimCurrSecOp *sec_op = NULL;
2823         TelSimFacilityResult disable_facility_resp = {0, };
2824
2825         dbg("Entry");
2826
2827         tcore_check_return_assert(co != NULL);
2828         tcore_check_return_assert(resp_cb_data != NULL);
2829
2830         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2831
2832         if (at_resp && at_resp->success) {
2833                 int lock_type;
2834                 dbg("Sim Disable Facility Response- [OK]");
2835
2836                 lock_type = __imc_sim_get_lock_type(*sec_op);
2837                 if (lock_type == -1) {
2838                         result = TEL_SIM_RESULT_INVALID_PARAMETER;
2839
2840                         /*Invoke callback*/
2841                         if(resp_cb_data->cb)
2842                                 resp_cb_data->cb(co, (gint)result,
2843                                                 NULL,
2844                                                 resp_cb_data->cb_data);
2845                         imc_destroy_resp_cb_data(resp_cb_data);
2846                         return;
2847                 }
2848
2849                 disable_facility_resp.type = lock_type;
2850                 result = TEL_SIM_RESULT_SUCCESS;
2851
2852                 /*Invoke callback*/
2853                 if(resp_cb_data->cb)
2854                         resp_cb_data->cb(co, (gint)result,
2855                                         &disable_facility_resp,
2856                                         resp_cb_data->cb_data);
2857                 imc_destroy_resp_cb_data(resp_cb_data);
2858         } else {
2859                 err("Sim Disable Facility Response- [NOK]");
2860                 /* Get retry count */
2861                 __imc_sim_get_retry_count(co, resp_cb_data);
2862         }
2863 }
2864
2865 static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
2866                 const void *data, void *user_data)
2867 {
2868         const TcoreAtResponse *at_resp = data;
2869         ImcRespCbData *resp_cb_data = user_data;
2870         CoreObject *co = tcore_pending_ref_core_object(p);
2871         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2872         ImcSimCurrSecOp *sec_op = NULL;
2873         TelSimFacilityResult enable_facility_resp = {0, };
2874
2875         dbg("Entry");
2876
2877         tcore_check_return_assert(co != NULL);
2878         tcore_check_return_assert(resp_cb_data != NULL);
2879
2880         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2881
2882         if (at_resp && at_resp->success) {
2883                 int lock_type;
2884                 dbg("Sim Enable Facility Response- [OK]");
2885
2886                 lock_type = __imc_sim_get_lock_type(*sec_op);
2887                 if (lock_type == -1) {
2888                         result = TEL_SIM_RESULT_INVALID_PARAMETER;
2889
2890                         /*Invoke callback*/
2891                         if(resp_cb_data->cb)
2892                                 resp_cb_data->cb(co, (gint)result,
2893                                                 NULL,
2894                                                 resp_cb_data->cb_data);
2895                         imc_destroy_resp_cb_data(resp_cb_data);
2896                         return;
2897                 }
2898
2899                 enable_facility_resp.type = lock_type;
2900                 result = TEL_SIM_RESULT_SUCCESS;
2901
2902                 /*Invoke callback*/
2903                 if(resp_cb_data->cb)
2904                         resp_cb_data->cb(co, (gint)result,
2905                                         &enable_facility_resp,
2906                                         resp_cb_data->cb_data);
2907                 imc_destroy_resp_cb_data(resp_cb_data);
2908         } else {
2909                 err("Sim Enable Facility Response- [NOK]");
2910                 /* Get retry count */
2911                 __imc_sim_get_retry_count(co, resp_cb_data);
2912         }
2913 }
2914
2915 static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
2916                 const void *data, void *user_data)
2917 {
2918         const TcoreAtResponse *at_resp = data;
2919         ImcRespCbData *resp_cb_data = user_data;
2920         CoreObject *co = tcore_pending_ref_core_object(p);
2921         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2922         ImcSimCurrSecOp *sec_op = NULL;
2923         TelSimFacilityInfo get_facility_resp = {0, };
2924
2925         dbg("Entry");
2926
2927         tcore_check_return_assert(co != NULL);
2928         tcore_check_return_assert(resp_cb_data != NULL);
2929
2930         sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2931
2932         if (at_resp && at_resp->success) {
2933                 GSList *tokens = NULL;
2934                 const char *line;
2935                 int lock_type;
2936
2937                 dbg("Sim Get Facility Response- [OK]");
2938
2939                 lock_type = __imc_sim_get_lock_type(*sec_op);
2940                 if (lock_type == -1) {
2941                         result = TEL_SIM_RESULT_INVALID_PARAMETER;
2942                         goto EXIT;
2943                 }
2944                 if (at_resp->lines) {
2945                         line = (const char *)at_resp->lines->data;
2946                         tokens = tcore_at_tok_new(line);
2947                         if (g_slist_length(tokens) != 1) {
2948                                 err("Invalid message");
2949                                 tcore_at_tok_free(tokens);
2950                                 goto EXIT;
2951                         }
2952                         get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
2953                         get_facility_resp.type = lock_type;
2954                         result = TEL_SIM_RESULT_SUCCESS;
2955                 }
2956
2957                 tcore_at_tok_free(tokens);
2958         } else {
2959                 err("Sim Get Facility Response- [NOK]");
2960         }
2961 EXIT:
2962         /* Invoke callback */
2963         if(resp_cb_data->cb)
2964                 resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
2965         imc_destroy_resp_cb_data(resp_cb_data);
2966 }
2967
2968 static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
2969                 const void *data, void *user_data)
2970 {
2971         const TcoreAtResponse *at_resp = data;
2972         ImcRespCbData *resp_cb_data = user_data;
2973         CoreObject *co = tcore_pending_ref_core_object(p);
2974         TelSimResult result = TEL_SIM_RESULT_FAILURE;
2975         TelSimLockInfo get_lock_info_resp = {0, };
2976
2977         dbg("Entry");
2978
2979         tcore_check_return_assert(co != NULL);
2980         tcore_check_return_assert(resp_cb_data != NULL);
2981
2982         if(at_resp && at_resp->success) {
2983                 GSList *tokens = NULL;
2984                 const char *line;
2985                 int lock_type = 0;
2986                 int attempts_left = 0;
2987                 int time_penalty = 0;
2988
2989                 dbg("Sim Get Lock Info Response- [OK]");
2990
2991                 if (at_resp->lines) {
2992                         line = (const char *)at_resp->lines->data;
2993                         tokens = tcore_at_tok_new(line);
2994                         if (g_slist_length(tokens) < 3) {
2995                                 err("Invalid message");
2996                                 tcore_at_tok_free(tokens);
2997                                 goto EXIT;
2998                         }
2999
3000                         lock_type = atoi(g_slist_nth_data(tokens, 0));
3001                         attempts_left = atoi(g_slist_nth_data(tokens, 1));
3002                         time_penalty = atoi(g_slist_nth_data(tokens, 2));
3003
3004                         dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
3005                                 lock_type, attempts_left, time_penalty);
3006
3007                         get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
3008                         get_lock_info_resp.retry_count = attempts_left;
3009                         result = TEL_SIM_RESULT_SUCCESS;
3010                 }
3011                 tcore_at_tok_free(tokens);
3012         } else {
3013                 err("Sim Get Lock Info Response- [NOK]");
3014         }
3015 EXIT:
3016         /* Invoke callback */
3017         if(resp_cb_data->cb)
3018                 resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
3019         imc_destroy_resp_cb_data(resp_cb_data);
3020 }
3021
3022 static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
3023 {
3024         const TcoreAtResponse *resp = data;
3025         CoreObject *co = NULL;
3026         TelSimApduResp apdu_resp = {0,};
3027         TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3028         GSList *tokens = NULL;
3029         const char *line;
3030         ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3031
3032         dbg("Entry");
3033
3034         co = tcore_pending_ref_core_object(p);
3035
3036         if (resp->success > 0) {
3037                 dbg("RESPONSE OK");
3038                 if (resp->lines) {
3039                         char *tmp = NULL;
3040                         char *decoded_data = NULL;
3041                         guint decoded_data_len = 0;
3042                         line = (const char *)resp->lines->data;
3043                         tokens = tcore_at_tok_new(line);
3044                         if (g_slist_length(tokens) != 2) {
3045                                 err("Invalid message");
3046                                 goto OUT;
3047                         }
3048
3049                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3050                         tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3051
3052                         apdu_resp.apdu_resp_len = decoded_data_len;
3053                         memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
3054                         g_free(tmp);
3055                         g_free(decoded_data);
3056                         sim_result = TEL_SIM_RESULT_SUCCESS;
3057                 }
3058         } else {
3059                 err("RESPONSE NOK");
3060         }
3061
3062 OUT:
3063         /* Send Response */
3064         if (resp_cb_data->cb)
3065                 resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
3066         tcore_at_tok_free(tokens);
3067         dbg("Exit");
3068 }
3069
3070 static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
3071 {
3072         const TcoreAtResponse *resp = data;
3073         CoreObject *co = NULL;
3074         TelSimAtr atr_res = {0,};
3075         TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3076         GSList *tokens = NULL;
3077         const char *line;
3078         ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3079
3080         dbg("Entry");
3081
3082         co = tcore_pending_ref_core_object(p);
3083
3084         if (resp->success > 0) {
3085                 dbg("RESPONSE OK");
3086                 if (resp->lines) {
3087                         char *tmp = NULL;
3088                         char *decoded_data = NULL;
3089                         guint decoded_data_len = 0;
3090                         line = (const char *)resp->lines->data;
3091                         tokens = tcore_at_tok_new(line);
3092                         if (g_slist_length(tokens) < 1) {
3093                                 err("Invalid message");
3094                                 goto OUT;
3095                         }
3096
3097                         tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3098                         tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3099
3100                         atr_res.atr_len = decoded_data_len;
3101                         memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
3102                         g_free(tmp);
3103                         g_free(decoded_data);
3104                         sim_result = TEL_SIM_RESULT_SUCCESS;
3105                 }
3106         } else {
3107                 err("RESPONSE NOK");
3108         }
3109
3110 OUT:
3111         /* Send Response */
3112         if (resp_cb_data->cb)
3113                 resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
3114         tcore_at_tok_free(tokens);
3115         dbg("Exit");
3116 }
3117
3118 /* SIM Operations */
3119 /*
3120  * Operation - get_imsi
3121  *
3122  * Request -
3123  * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3124  * where,
3125  * <command>
3126  * 176 READ BINARY
3127  * 178 READ RECORD
3128  * 192 GET RESPONSE
3129  * 214 UPDATE BINARY
3130  * 220 UPDATE RECORD
3131  * 242 STATUS
3132  *
3133  * <fileid>
3134  * 28423 meaning IMSI file (6F07)
3135  * 28473 meaning ACM file (6F39)
3136  * 28481 meaning PUKT file (6F41)
3137  * 28482 meaning SMS file (6F42)
3138  *
3139  * <P1>, <P2>, <P3>
3140  * Integer type defining the request.
3141  * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
3142  *
3143  * <data>
3144  * Information which shall be written to the SIM
3145  *
3146  * <pathid>
3147  * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
3148  *
3149  * <status>
3150  * 0 not active
3151  * 1 active
3152  *
3153  * Success:
3154  *      OK
3155  *      +CRSM: <sw1>,<sw2>[,<response>]
3156  *
3157  * <sw1>, <sw2>
3158  * Integer type containing the SIM information
3159  *
3160  * <response>
3161  * Response of successful completion of the command previously issued
3162  *
3163  * Failure:
3164  *      +CME ERROR: <error>
3165  */
3166 static TelReturn imc_sim_get_imsi (CoreObject *co,
3167         TcoreObjectResponseCallback cb, void *cb_data)
3168 {
3169         TelReturn ret;
3170         dbg("Entry");
3171
3172         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
3173
3174         return ret;
3175 }
3176
3177 static TelReturn imc_sim_get_ecc (CoreObject *co,
3178         TcoreObjectResponseCallback cb, void *cb_data)
3179 {
3180         TelReturn ret;
3181         dbg("Entry");
3182
3183         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
3184
3185         return ret;
3186 }
3187
3188 static TelReturn imc_sim_get_iccid (CoreObject *co,
3189         TcoreObjectResponseCallback cb, void *cb_data)
3190 {
3191         TelReturn ret;
3192         dbg("Entry");
3193
3194         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
3195
3196         return ret;
3197 }
3198
3199 static TelReturn imc_sim_get_language (CoreObject *co,
3200         TcoreObjectResponseCallback cb, void *cb_data)
3201 {
3202         TelReturn ret;
3203         dbg("Entry");
3204
3205         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_LP, ret);
3206
3207         return ret;
3208 }
3209
3210 static TelReturn imc_sim_set_language (CoreObject *co,
3211         TelSimLanguagePreferenceCode language,
3212         TcoreObjectResponseCallback cb, void *cb_data)
3213 {
3214         ImcSimMetaInfo file_meta = {0, };
3215         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3216         ImcRespCbData *resp_cb_data = NULL;
3217         char *tmp = NULL;
3218         int tmp_len = 0;
3219         char *encoded_data = NULL;
3220         int encoded_data_len = 0;
3221         int p1 = 0;
3222         int p2 = 0;
3223         int p3 = 0;
3224
3225         dbg("Entry");
3226
3227         file_meta.file_id = TEL_SIM_EF_LP;
3228         file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3229
3230         tcore_sim_get_type(co, &card_type);
3231
3232         dbg("language[%d], card_type[%d]", language, card_type);
3233
3234         if (TEL_SIM_CARD_TYPE_GSM == card_type) {
3235                 dbg("2G");
3236                 tcore_sim_encode_lp(language, &tmp, &tmp_len);
3237         } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
3238                 dbg("3G");
3239                 tcore_sim_encode_li(language, &tmp, &tmp_len);
3240         } else {
3241                 err("Invalid card_type:[%d]", card_type);
3242                 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
3243         }
3244         if (!tmp_len) {
3245                 err("Failed to encode Language [%d]", language);
3246                 return TEL_RETURN_FAILURE;
3247         }
3248         dbg("Encoded Language [%s]", tmp);
3249
3250         encoded_data_len = 2 * tmp_len;
3251         encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3252         tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3253         tcore_free(tmp);
3254
3255         p1 = 0;
3256         p2 = 0;
3257         p3 = encoded_data_len;
3258         dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3259
3260         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3261
3262         return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_BINARY,
3263                                         TEL_SIM_EF_LP, p1, p2, p3, encoded_data);
3264 }
3265
3266 static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
3267         TcoreObjectResponseCallback cb, void *cb_data)
3268 {
3269         TelReturn ret;
3270         dbg("Entry");
3271
3272         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
3273
3274         return ret;
3275 }
3276
3277 static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
3278         TcoreObjectResponseCallback cb, void *cb_data)
3279 {
3280         TelReturn ret;
3281         dbg("Entry");
3282
3283         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
3284
3285         return ret;
3286 }
3287
3288 static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
3289         const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
3290 {
3291         ImcSimMetaInfo file_meta = {0, };
3292         ImcRespCbData *resp_cb_data = NULL;
3293         gchar *encoded_mwis;
3294         guint encoded_mwis_len = 0;
3295         gchar *encoded_data = NULL;
3296         guint encoded_data_len = 0;
3297         int p1 = 0;
3298         int p2 = 0;
3299         int p3 = 0;
3300
3301         dbg("Entry");
3302
3303         /*
3304          * Videomail is not supported.
3305          */
3306         if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
3307                         &encoded_mwis, &encoded_mwis_len)) {
3308                 err("Failed to encode mwis");
3309                 return TEL_RETURN_FAILURE;
3310         }
3311
3312         encoded_data_len = 2 * encoded_mwis_len;
3313         encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3314         tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
3315         tcore_free(encoded_mwis);
3316         dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
3317
3318         p1 = 1;
3319         p2 = 0x04;
3320         p3 = TEL_SIM_MAILBOX_TYPE_MAX;  /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
3321         dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
3322
3323         file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
3324         file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3325
3326         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3327
3328         return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3329                                         TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
3330 }
3331
3332 static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
3333         TcoreObjectResponseCallback cb, void *cb_data)
3334 {
3335         TelReturn ret;
3336         dbg("Entry");
3337
3338         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
3339
3340         return ret;
3341 }
3342
3343 static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
3344         const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
3345 {
3346         ImcSimMetaInfo file_meta = {0, };
3347         ImcRespCbData *resp_cb_data = NULL;
3348         char *tmp = NULL;
3349         int tmp_len = 0;
3350         char *encoded_data = NULL;
3351         int encoded_data_len = 0;
3352         int p1 = 0;
3353         int p2 = 0;
3354         int p3 = 0;
3355
3356         dbg("Entry");
3357
3358         file_meta.file_id = TEL_SIM_EF_USIM_MBI;
3359         file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3360
3361         /* TBD - Do Encoding.
3362         if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
3363                 err("Failed to encode mwis");
3364                 return TEL_RETURN_FAILURE;
3365         } */
3366
3367         encoded_data_len = tmp_len * 2;
3368         encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3369         tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3370         if (!encoded_data) {
3371                 err("Failed to convert byte to hex");
3372                 tcore_free(encoded_data);
3373                 return TEL_RETURN_FAILURE;
3374         }
3375
3376         p1 = 1;
3377         p2 = 0x04;
3378         p3 = encoded_data_len;
3379         dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3380
3381         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3382
3383         return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3384                                         TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
3385 }
3386
3387 static TelReturn imc_sim_get_msisdn (CoreObject *co,
3388         TcoreObjectResponseCallback cb, void *cb_data)
3389 {
3390         TelReturn ret;
3391         dbg("Entry");
3392
3393         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
3394
3395         return ret;
3396 }
3397
3398 static TelReturn imc_sim_get_spn (CoreObject *co,
3399         TcoreObjectResponseCallback cb, void *cb_data)
3400 {
3401         TelReturn ret;
3402         dbg("Entry");
3403
3404         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
3405
3406         return ret;
3407 }
3408
3409 static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
3410         TcoreObjectResponseCallback cb, void *cb_data)
3411 {
3412         TelReturn ret;
3413         dbg("Entry");
3414
3415         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
3416
3417         return ret;
3418 }
3419
3420 static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
3421         TcoreObjectResponseCallback cb, void *cb_data)
3422 {
3423         TelReturn ret;
3424         dbg("Entry");
3425
3426         IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
3427
3428         return ret;
3429 }
3430
3431 static TelReturn imc_sim_req_authentication (CoreObject *co,
3432         const TelSimAuthenticationData *request,
3433         TcoreObjectResponseCallback cb, void *cb_data)
3434 {
3435         gchar *cmd_str = NULL;
3436         ImcRespCbData *resp_cb_data = NULL;
3437         TelReturn ret = TEL_RETURN_FAILURE;
3438         TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3439         char *convert_rand = NULL;
3440         char *convert_autn = NULL;
3441         int session_id;
3442         int context_type;
3443
3444         dbg("Entry");
3445
3446         tcore_sim_get_type(co, &card_type);
3447         if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
3448                 session_id = 0;
3449         } else {
3450                 err("Not Supported SIM type:[%d]", card_type);
3451                 return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3452         }
3453
3454         if (request->rand_data != NULL) {
3455                 convert_rand = tcore_malloc0(request->rand_length*2 + 1);
3456                 tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
3457                 dbg("Convert RAND hex to string: [%s]", convert_rand);
3458         } else {
3459                 err("rand_data is NULL");
3460                 goto EXIT;
3461         }
3462
3463         switch (request->auth_type) {
3464         case TEL_SIM_AUTH_GSM:
3465                 context_type = 2;
3466                 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
3467                         session_id, context_type, convert_rand);
3468         break;
3469         case TEL_SIM_AUTH_3G_CTX:
3470                 context_type = 1;
3471                 if (request->autn_data != NULL) {
3472                         convert_autn = tcore_malloc0(request->autn_length*2 + 1);
3473                         tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
3474                         dbg("Convert AUTN hex to string: [%s]", convert_autn);
3475                 } else {
3476                         err("autn_data is NULL");
3477                         goto EXIT;
3478                 }
3479                 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3480                         session_id, context_type, convert_rand, convert_autn);
3481         break;
3482         default:
3483                 err("Not supported Authentication type:[%d]", request->auth_type);
3484                 ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3485                 goto EXIT;
3486         }
3487
3488         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
3489
3490         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XAUTH:",
3491                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3492                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3493                                                 on_response_imc_sim_req_authentication, resp_cb_data,
3494                                                 on_send_imc_request, NULL, 0, NULL, NULL);
3495
3496         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
3497 EXIT:
3498         g_free(cmd_str);
3499         tcore_free(convert_rand);
3500         tcore_free(convert_autn);
3501         dbg("Exit");
3502         return ret;
3503 }
3504
3505 /*
3506  * Operation - verify_pins/verify_puks
3507  *
3508  * Request -
3509  * For SIM PIN
3510  * AT-Command: AT+CPIN= <pin> [, <newpin>]
3511  * where,
3512  * <pin>, <newpin>
3513  * String type values
3514  *
3515  * For SIM PIN2
3516  * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
3517  * where,
3518  * <puk2/pin2>, <newpin2>
3519  * String type values
3520  *
3521  * Success:
3522  *      OK
3523  *
3524  * Failure:
3525  *      +CME ERROR: <error>
3526  */
3527 static TelReturn imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
3528                 TcoreObjectResponseCallback cb, void *cb_data)
3529 {
3530         TelReturn ret = TEL_RETURN_FAILURE;
3531         ImcRespCbData *resp_cb_data = NULL;
3532         ImcSimCurrSecOp sec_op;
3533         gchar *cmd_str = NULL;
3534
3535         dbg("Entry");
3536
3537         if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3538                 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
3539                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
3540         } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3541                 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
3542                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
3543         } else {
3544                 err("Invalid pin type [%d]", request->pin_type);
3545                 return TEL_RETURN_INVALID_PARAMETER;
3546         }
3547
3548         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3549                         &sec_op, sizeof(sec_op));
3550
3551         ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3552                                                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3553                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3554                                                 NULL,
3555                                                 on_response_imc_sim_verify_pins,
3556                                                 resp_cb_data,
3557                                                 on_send_imc_request,
3558                                                 NULL, 0, NULL, NULL);
3559
3560         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
3561         g_free(cmd_str);
3562         return ret;
3563 }
3564
3565 static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
3566                 TcoreObjectResponseCallback cb, void *cb_data)
3567 {
3568         TelReturn ret = TEL_RETURN_FAILURE;
3569         ImcRespCbData *resp_cb_data = NULL;
3570         ImcSimCurrSecOp sec_op;
3571         gchar *cmd_str = NULL;
3572
3573         dbg("Entry");
3574
3575         if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
3576                 sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
3577                 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
3578                                 request->puk_pw, request->new_pin_pw);
3579         } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
3580                 sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
3581                 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
3582                                 request->puk_pw, request->new_pin_pw);
3583         } else {
3584                 err("Invalid puk type [%d]", request->puk_type);
3585                 return TEL_RETURN_INVALID_PARAMETER;
3586         }
3587
3588         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3589                         &sec_op, sizeof(sec_op));
3590
3591         ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3592                                                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3593                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3594                                                 NULL,
3595                                                 on_response_imc_sim_verify_puks,
3596                                                 resp_cb_data,
3597                                                 on_send_imc_request,
3598                                                 NULL, 0, NULL, NULL);
3599
3600         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
3601         g_free(cmd_str);
3602         return ret;
3603 }
3604
3605 /*
3606  * Operation - change_pins
3607  *
3608  * Request -
3609  * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
3610  * where,
3611  * <fac>
3612  * SIM facility
3613  *
3614  * <oldpwd>
3615  * Old Password
3616  *
3617  * <newpwd>
3618  * New Password
3619  *
3620  * Success:
3621  *      OK
3622  *
3623  * Failure:
3624  *      +CME ERROR: <error>
3625  */
3626 static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
3627                 TcoreObjectResponseCallback cb, void *cb_data)
3628 {
3629         TelReturn ret = TEL_RETURN_FAILURE;
3630         ImcRespCbData *resp_cb_data = NULL;
3631         ImcSimCurrSecOp sec_op;
3632         gchar *cmd_str = NULL;
3633         char *pin1_fac = "SC";
3634         char *pin2_fac = "P2";
3635
3636         dbg("Entry");
3637
3638         if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3639                 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
3640                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3641                                 pin1_fac, request->old_pw, request->new_pw);
3642         } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3643                 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
3644                 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3645                                 pin2_fac, request->old_pw, request->new_pw);
3646         } else {
3647                 err("Invalid pin type [%d]", request->pin_type);
3648                 return TEL_RETURN_INVALID_PARAMETER;
3649         }
3650
3651         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3652                         &sec_op, sizeof(sec_op));
3653
3654         ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3655                                                 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3656                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3657                                                 NULL,
3658                                                 on_response_imc_sim_change_pins,
3659                                                 resp_cb_data,
3660                                                 on_send_imc_request,
3661                                                 NULL, 0, NULL, NULL);
3662
3663         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
3664         g_free(cmd_str);
3665         return ret;
3666 }
3667
3668 /*
3669  * Operation - disable_facility/enable_facility/get_facility
3670  *
3671  * Request -
3672  * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
3673  * where,
3674  * <fac>
3675  * SIM facility
3676  *
3677  * <mode>
3678  * 0 unlock
3679  * 1 lock
3680  * 2 query status
3681  *
3682  * <passwd>
3683  * Password string
3684  *
3685  * <status>
3686  * 0 not active
3687  * 1 active
3688  *
3689  * Success: when <mode>=2:
3690  *      OK
3691  *      +CLCK: <status>[,<class1> [<CR><LF>
3692  *      +CLCK: <status>,<class2> [...]]
3693  *
3694  * Failure:
3695  */
3696 static TelReturn imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
3697                 TcoreObjectResponseCallback cb, void *cb_data)
3698 {
3699         TelReturn ret = TEL_RETURN_FAILURE;
3700         ImcRespCbData *resp_cb_data = NULL;
3701         ImcSimCurrSecOp sec_op;
3702         gchar *cmd_str = NULL;
3703         char *fac = "SC";
3704         int mode = 0; /*mode = 0 for disable lock*/
3705
3706         dbg("Entry");
3707
3708         fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3709                         &sec_op, DISABLE_FLAG);
3710         if (!fac)
3711                 return TEL_RETURN_INVALID_PARAMETER;
3712
3713         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3714                         fac, mode, request->pw);
3715
3716         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3717                         &sec_op, sizeof(sec_op));
3718
3719         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3720                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3721                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3722                                                 NULL,
3723                                                 on_response_imc_sim_disable_facility,
3724                                                 resp_cb_data,
3725                                                 on_send_imc_request,
3726                                                 NULL, 0, NULL, NULL);
3727
3728         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3729         g_free(cmd_str);
3730         return ret;
3731 }
3732
3733 static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
3734                 TcoreObjectResponseCallback cb, void *cb_data)
3735 {
3736         TelReturn ret = TEL_RETURN_FAILURE;
3737         ImcRespCbData *resp_cb_data = NULL;
3738         ImcSimCurrSecOp sec_op;
3739         gchar *cmd_str = NULL;
3740         char *fac = "SC";
3741         int mode = 1; /*mode = 1 for enable lock*/
3742
3743         dbg("Entry");
3744
3745         fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3746                         &sec_op, ENABLE_FLAG);
3747         if (!fac)
3748                 return TEL_RETURN_INVALID_PARAMETER;
3749
3750         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3751                         fac, mode, request->pw);
3752
3753         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3754                         &sec_op, sizeof(sec_op));
3755
3756         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3757                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3758                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3759                                                 NULL,
3760                                                 on_response_imc_sim_enable_facility,
3761                                                 resp_cb_data,
3762                                                 on_send_imc_request,
3763                                                 NULL, 0, NULL, NULL);
3764
3765         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3766         g_free(cmd_str);
3767         return ret;
3768 }
3769
3770 static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
3771                 TcoreObjectResponseCallback cb, void *cb_data)
3772 {
3773         TelReturn ret = TEL_RETURN_FAILURE;
3774         ImcRespCbData *resp_cb_data = NULL;
3775         ImcSimCurrSecOp sec_op;
3776         gchar *cmd_str = NULL;
3777         char *fac = "SC";
3778         int mode = 2; /*mode = 2 for Get Facility*/
3779
3780         dbg("Entry");
3781
3782         fac = __imc_sim_get_fac_from_lock_type(lock_type,
3783                         &sec_op, 0);
3784         if (!fac)
3785                 return TEL_RETURN_INVALID_PARAMETER;
3786
3787         cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3788
3789         resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3790                                 &sec_op, sizeof(sec_op));
3791
3792         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3793                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3794                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3795                                                 NULL,
3796                                                 on_response_imc_sim_get_facility,
3797                                                 resp_cb_data,
3798                                                 on_send_imc_request,
3799                                                 NULL, 0, NULL, NULL);
3800
3801         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
3802         g_free(cmd_str);
3803         return ret;
3804 }
3805
3806 static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
3807                 TcoreObjectResponseCallback cb, void *cb_data)
3808 {
3809         TelReturn ret = TEL_RETURN_FAILURE;
3810         ImcRespCbData *resp_cb_data = NULL;
3811         gchar *cmd_str = NULL;
3812         int lockType = 0;
3813
3814         dbg("Entry");
3815
3816         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3817
3818         switch (lock_type) {
3819         case TEL_SIM_LOCK_PS:
3820                 lockType = 9;
3821                 break;
3822
3823         case TEL_SIM_LOCK_SC:
3824                 lockType = 1;
3825                 break;
3826
3827         case TEL_SIM_LOCK_FD:
3828                 lockType = 2;
3829                 break;
3830
3831         case TEL_SIM_LOCK_PN:
3832                 lockType = 5;
3833                 break;
3834
3835         case TEL_SIM_LOCK_PU:
3836                 lockType = 6;
3837                 break;
3838
3839         case TEL_SIM_LOCK_PP:
3840                 lockType = 7;
3841                 break;
3842
3843         case TEL_SIM_LOCK_PC:
3844                 lockType = 8;
3845                 break;
3846
3847         default:
3848                 break;
3849         }
3850
3851         cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
3852
3853         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XPINCNT:",
3854                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3855                                                 TCORE_PENDING_PRIORITY_DEFAULT,
3856                                                 NULL,
3857                                                 on_response_imc_sim_get_lock_info,
3858                                                 resp_cb_data,
3859                                                 on_send_imc_request,
3860                                                 NULL, 0, NULL, NULL);
3861
3862         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
3863         g_free(cmd_str);
3864         return ret;
3865 }
3866
3867 static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
3868 {
3869         gchar *cmd_str = NULL;
3870         char *apdu = NULL;
3871         ImcRespCbData *resp_cb_data = NULL;
3872         TelReturn ret = TEL_RETURN_FAILURE;
3873
3874         dbg("Entry");
3875
3876         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3877
3878         apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
3879         tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
3880
3881         cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
3882
3883         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CSIM:",
3884                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3885                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3886                                                 on_response_imc_sim_req_apdu, resp_cb_data,
3887                                                 on_send_imc_request, NULL, 0, NULL, NULL);
3888
3889         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
3890
3891         g_free(cmd_str);
3892         g_free(apdu);
3893
3894         dbg("Exit");
3895         return ret;
3896 }
3897
3898 static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
3899 {
3900         gchar *cmd_str = NULL;
3901         ImcRespCbData *resp_cb_data = NULL;
3902         TelReturn ret = TEL_RETURN_FAILURE;
3903
3904         dbg("Entry");
3905
3906         resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3907
3908         cmd_str = g_strdup_printf("AT+XGATR");
3909
3910         ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XGATR:",
3911                                                 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3912                                                 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3913                                                 on_response_imc_sim_req_atr, resp_cb_data,
3914                                                 on_send_imc_request, NULL, 0, NULL, NULL);
3915
3916         IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
3917
3918         g_free(cmd_str);
3919
3920         dbg("Exit");
3921         return ret;
3922 }
3923
3924 /* SIM Operations */
3925 static TcoreSimOps imc_sim_ops = {
3926         .get_imsi = imc_sim_get_imsi,
3927         .get_ecc = imc_sim_get_ecc,
3928         .get_iccid = imc_sim_get_iccid,
3929         .get_language = imc_sim_get_language,
3930         .set_language = imc_sim_set_language,
3931         .get_callforwarding_info = imc_sim_get_callforwarding_info,
3932         .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
3933         .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
3934         .get_mailbox_info = imc_sim_get_mailbox_info,
3935         .set_mailbox_info = imc_sim_set_mailbox_info,
3936         .get_msisdn = imc_sim_get_msisdn,
3937         .get_spn = imc_sim_get_spn,
3938         .get_cphs_netname = imc_sim_get_cphs_netname,
3939         .get_sp_display_info = imc_sim_get_sp_display_info,
3940         .req_authentication = imc_sim_req_authentication,
3941         .verify_pins = imc_sim_verify_pins,
3942         .verify_puks = imc_sim_verify_puks,
3943         .change_pins = imc_sim_change_pins,
3944         .disable_facility = imc_sim_disable_facility,
3945         .enable_facility = imc_sim_enable_facility,
3946         .get_facility = imc_sim_get_facility,
3947         .get_lock_info = imc_sim_get_lock_info,
3948         .req_apdu = imc_sim_req_apdu,
3949         .req_atr = imc_sim_req_atr
3950 };
3951
3952 gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
3953 {
3954         ImcSimPrivateInfo *priv_info = NULL;
3955
3956         dbg("Entry");
3957
3958         priv_info = g_try_new0(ImcSimPrivateInfo, 1);
3959         if (priv_info == NULL)
3960                 return FALSE;
3961
3962         tcore_sim_link_userdata(co, priv_info);
3963
3964         /* Set operations */
3965         tcore_sim_set_ops(co, &imc_sim_ops);
3966
3967         /* Add Callbacks */
3968         tcore_object_add_callback(co, "+XSIM:",
3969                 on_notification_imc_sim_status, NULL);
3970
3971         /* Hooks */
3972         tcore_plugin_add_notification_hook(p,
3973                 TCORE_NOTIFICATION_MODEM_POWER,
3974                 on_hook_imc_modem_power, co);
3975
3976         dbg("Exit");
3977         return TRUE;
3978 }
3979
3980 void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
3981 {
3982         ImcSimPrivateInfo *priv_info = NULL;
3983
3984         dbg("Entry");
3985
3986         priv_info = tcore_sim_ref_userdata(co);
3987         g_free(priv_info);
3988
3989         dbg("Exit");
3990 }