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