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