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