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