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