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