4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include <core_object.h>
39 #include "imc_common.h"
42 #define DISABLE_FLAG 2
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
50 #define IMC_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \
52 ImcSimMetaInfo file_meta = {0, }; \
53 ImcRespCbData *resp_cb_data = NULL; \
55 file_meta.file_id = fileId; \
56 file_meta.file_result = TEL_SIM_RESULT_FAILURE; \
58 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo)); \
60 ret = __imc_sim_get_response(co, resp_cb_data); \
61 dbg("Request reading '%s' - [%s]", #fileId, (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAILURE")); \
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 */
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
109 guint smsp_count; /**< SMSP record count */
110 guint smsp_rec_len; /**< SMSP record length */
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*/
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);
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);
157 /* GET SMSP info for SMS module */
158 gboolean imc_sim_get_smsp_info(TcorePlugin *plugin, int *rec_count, int *rec_len)
160 CoreObject *co = NULL;
161 ImcSimPrivateInfo *priv_info = NULL;
165 co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
166 priv_info = tcore_sim_ref_userdata(co);
170 *rec_count = priv_info->smsp_count;
171 *rec_len = priv_info->smsp_rec_len;
173 dbg("smsp_count:[%d], smsp_rec_len:[%d]", priv_info->smsp_count, priv_info->smsp_rec_len);
177 static void __imc_sim_set_identity(CoreObject *co, TelSimImsiInfo *imsi)
179 gchar new_imsi[15 + 1] = {0, };
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));
186 /* TODO: This is temporary code, we should use secure storage instead of vconf */
187 old_imsi = vconf_get_str("db/telephony/imsi");
189 if (g_strcmp0(old_imsi, new_imsi) != 0) {
191 vconf_set_str("db/telephony/imsi", new_imsi);
192 tcore_sim_set_identification(co, TRUE);
195 tcore_sim_set_identification(co, FALSE);
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);
204 /* Utility Functions */
205 static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2)
207 TelSimResult rst = TEL_SIM_RESULT_FAILURE;
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);
268 rst = TEL_SIM_RESULT_CARD_ERROR;
269 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
274 static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status)
276 TelSimCardStatus curr_sim_status;
279 * Send SIM Init status, if not sent already
281 (void)tcore_sim_get_status(co, &curr_sim_status);
282 if (sim_status != curr_sim_status) {
283 TelSimCardStatusInfo sim_status_noti = {0, };
285 dbg("Change in SIM State - Old State: [0x%02x] --> New State: [0x%02x]",
286 curr_sim_status, sim_status);
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);
293 /* Send notification: SIM Status */
294 tcore_object_send_notification(co,
295 TCORE_NOTIFICATION_SIM_STATUS,
296 sizeof(sim_status_noti), &sim_status_noti);
300 static void __imc_sim_notify_sms_state(CoreObject *co,
305 gboolean sms_status = FALSE;
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);
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"));
318 TelSimCardStatus sim_status;
320 /* Update SMS State */
321 tcore_sms_set_ready_status(co_sms, sms_ready);
323 dbg("SMS Status - Changed [%s] --> [%s]",
324 (sms_status ? "INITIALIZED" : "UNINITIALIZED"),
325 (sms_ready ? "INITIALIZED" : "UNINITIALIZED"));
328 * Send SMS device ready notification, if SIM is initialiazed.
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);
340 TelReturn __imc_sim_start_to_cache(CoreObject *co)
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);
355 static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co,
356 gint result, const void *response, void *user_data)
358 dbg("SIM Response - SIM Type (internal): [+XUICC]");
360 if (result == TEL_SIM_RESULT_SUCCESS) {
361 TelSimCardType *sim_type = (TelSimCardType *)response;
362 dbg("SIM Type: [%d]", *sim_type);
364 /* Update SIM type */
365 tcore_sim_set_type(co, *sim_type);
366 if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) {
369 /* Start Caching SIM files */
370 ret = __imc_sim_start_to_cache(co);
372 /* Send SIM Type notification */
373 tcore_object_send_notification(co,
374 TCORE_NOTIFICATION_SIM_TYPE,
375 sizeof(TelSimCardType), sim_type);
380 static void __on_response_imc_sim_get_sim_type(TcorePending *p,
381 guint data_len, const void *data, void *user_data)
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;
388 TelSimResult result = TEL_SIM_RESULT_FAILURE;
390 dbg("SIM Response - SIM Type: [+XUICC]");
392 tcore_check_return_assert(co != NULL);
393 tcore_check_return_assert(resp_cb_data != NULL);
395 if (at_resp && at_resp->success) {
396 if (at_resp->lines) {
400 line = (const gchar *)at_resp->lines->data;
407 tokens = tcore_at_tok_new(line);
410 if (g_slist_length(tokens) == 1) {
411 guint state = atoi(g_slist_nth_data(tokens, 0));
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;
418 result = TEL_SIM_RESULT_SUCCESS;
421 err("Invalid message");
424 tcore_at_tok_free(tokens);
428 /* Invoke callback */
429 if (resp_cb_data->cb)
430 resp_cb_data->cb(co, (gint)result, &sim_type, resp_cb_data->cb_data);
432 /* Free callback data */
433 imc_destroy_resp_cb_data(resp_cb_data);
437 * Operation - get_sim_type
440 * AT-Command: AT+XUICC?
442 * Response - sim_type (TelSimCardType)
443 * Success: (Single line) -
447 * +CME ERROR: <error>
449 gboolean __imc_sim_get_sim_type(CoreObject *co,
450 TcoreObjectResponseCallback cb, void *cb_data)
452 ImcRespCbData *resp_cb_data;
455 /* Response callback data */
456 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
459 /* Send Request to modem */
460 ret = tcore_at_prepare_and_send_request(co,
461 "AT+XUICC?", "+XUICC:",
462 TCORE_AT_COMMAND_TYPE_SINGLELINE,
464 __on_response_imc_sim_get_sim_type, resp_cb_data,
465 on_send_imc_request, NULL);
466 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
471 static void __imc_sim_process_sim_status(CoreObject *co, guint sim_state)
473 TelSimCardStatus sim_card_status;
477 sim_card_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
482 sim_card_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
487 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
488 dbg("PIN DISABLED AT BOOT UP");
492 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
497 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
502 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
503 dbg("CARD PERMANENTLY BLOCKED");
507 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
508 dbg("SIM CARD ERROR");
512 sim_card_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
513 dbg("SIM INIT COMPLETED");
517 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
518 dbg("SIM CARD ERROR");
522 sim_card_status = TEL_SIM_STATUS_CARD_REMOVED;
527 dbg("SIM SMS Ready");
529 /* Notify SMS status */
530 return __imc_sim_notify_sms_state(co, TRUE);
533 sim_card_status = TEL_SIM_STATUS_UNKNOWN;
534 dbg("SIM STATE UNKNOWN");
538 err("Unknown/Unsupported SIM state: [%d]", sim_state);
542 switch (sim_card_status) {
543 case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
544 TelSimCardType sim_type;
546 dbg("SIM INIT COMPLETED");
548 (void)tcore_sim_get_type(co, &sim_type);
549 if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) {
551 * SIM is initialized for first time, need to
554 (void)__imc_sim_get_sim_type(co,
555 __on_response_imc_sim_get_sim_type_internal, NULL);
562 case TEL_SIM_STATUS_CARD_REMOVED:
563 dbg("SIM CARD REMOVED");
564 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
567 case TEL_SIM_STATUS_CARD_NOT_PRESENT:
568 dbg("SIM CARD NOT PRESENT");
569 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
572 case TEL_SIM_STATUS_CARD_ERROR:
573 dbg("SIM CARD ERROR");
574 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
578 err("SIM Status: [0x%02x]", sim_card_status);
582 /* Update SIM Status */
583 return __imc_sim_update_sim_status(co, sim_card_status);
586 static void __on_response_imc_sim_get_sim_status(TcorePending *p,
587 guint data_len, const void *data, void *user_data)
589 const TcoreAtResponse *at_resp = data;
590 CoreObject *co = tcore_pending_ref_core_object(p);
591 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
594 dbg("SIM Response - SIM status: [+XSIMSTATE]");
596 tcore_check_return_assert(co != NULL);
597 tcore_check_return_assert(resp_cb_data != NULL);
599 if (at_resp && at_resp->success) {
600 if (at_resp->lines) {
601 const gchar *line = NULL;
603 /* Process +XSIMSTATE response */
604 line = (const gchar *) (at_resp->lines->data);
607 guint sim_state, sms_state;
612 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
614 tokens = tcore_at_tok_new(line);
616 if (g_slist_length(tokens) == 4) {
618 sim_state = atoi(g_slist_nth_data(tokens, 1));
620 /* Process SIM Status */
621 __imc_sim_process_sim_status(co, sim_state);
624 sms_state = atoi(g_slist_nth_data(tokens, 3));
626 /* Notify SMS status */
627 __imc_sim_notify_sms_state(co, (sms_state > 0));
630 err("Invalid message");
633 tcore_at_tok_free(tokens);
638 /* Free callback data */
639 imc_destroy_resp_cb_data(resp_cb_data);
643 * Operation - get_sim_status
646 * AT-Command: AT+XSIMSTATE?
648 * Response - sim_status
649 * Success: (Single line) -
650 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
653 * +CME ERROR: <error>
655 static gboolean __imc_sim_get_sim_status(CoreObject *co,
656 TcoreObjectResponseCallback cb, void *cb_data)
658 ImcRespCbData *resp_cb_data;
661 /* Response callback data */
662 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
665 /* Send Request to modem */
666 ret = tcore_at_prepare_and_send_request(co,
667 "AT+XSIMSTATE?", "+XSIMSTATE:",
668 TCORE_AT_COMMAND_TYPE_SINGLELINE,
670 __on_response_imc_sim_get_sim_status, resp_cb_data,
671 on_send_imc_request, NULL);
672 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Status");
677 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
679 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
680 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
684 dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", file_meta->file_id, sim_result, decode_ret);
685 switch (file_meta->file_id) {
687 case TEL_SIM_EF_USIM_PL:
689 case TEL_SIM_EF_USIM_LI:
690 if (decode_ret == TRUE) {
691 if (resp_cb_data->cb)
692 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
694 tcore_sim_get_type(co, &card_type);
696 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
697 - EFELP is not available;
698 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
699 - the ME does not support any of the languages in EFELP.
702 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
703 - if the EFLI has the value 'FFFF' in its highest priority position
704 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
706 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
707 if (file_meta->file_id == TEL_SIM_EF_LP) {
708 if (resp_cb_data->cb)
709 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
711 file_meta->file_id = TEL_SIM_EF_LP;
712 __imc_sim_get_response(co, resp_cb_data);
714 } else if (TEL_SIM_CARD_TYPE_USIM) {
715 if (file_meta->file_id == TEL_SIM_EF_LP || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
716 file_meta->file_id = TEL_SIM_EF_ELP;
717 __imc_sim_get_response(co, resp_cb_data);
719 if (resp_cb_data->cb)
720 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
727 tcore_sim_get_type(co, &card_type);
728 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
729 if (file_meta->current_index == file_meta->rec_count) {
730 if (resp_cb_data->cb)
731 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
733 file_meta->current_index++;
734 __imc_sim_read_record(co, resp_cb_data);
736 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
737 if (resp_cb_data->cb)
738 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
740 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", card_type);
744 case TEL_SIM_EF_IMSI:
745 if (resp_cb_data->cb) {
746 resp_cb_data->cb(co, (gint)sim_result, &file_meta->imsi, resp_cb_data->cb_data);
748 file_meta->file_id = TEL_SIM_EF_CPHS_CPHS_INFO;
749 file_meta->file_result = TEL_SIM_RESULT_FAILURE;
750 __imc_sim_get_response(co, resp_cb_data);
752 /* Update SIM INIT status - INIT COMPLETE */
753 __imc_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
756 case TEL_SIM_EF_MSISDN:
757 if (file_meta->current_index == file_meta->rec_count) {
759 dbg("rec_count [%d], msisdn_count[%d]", file_meta->rec_count,
760 file_meta->files.data.msisdn_list.count);
761 if (resp_cb_data->cb) {
762 resp_cb_data->cb(co, (gint)sim_result,
763 &file_meta->files.data.msisdn_list, resp_cb_data->cb_data);
767 for (i = 0; i < file_meta->files.data.msisdn_list.count; i++) {
768 tcore_free(file_meta->files.data.msisdn_list.list[i].alpha_id);
769 tcore_free(file_meta->files.data.msisdn_list.list[i].num);
771 tcore_free(file_meta->files.data.msisdn_list.list);
773 file_meta->current_index++;
774 __imc_sim_read_record(co, resp_cb_data);
779 if (file_meta->current_index == file_meta->rec_count) {
780 if (resp_cb_data->cb)
781 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
784 file_meta->current_index++;
785 __imc_sim_read_record(co, resp_cb_data);
790 if (file_meta->current_index == file_meta->rec_count) {
791 if (resp_cb_data->cb)
792 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
794 file_meta->current_index++;
795 __imc_sim_read_record(co, resp_cb_data);
799 case TEL_SIM_EF_USIM_CFIS:
800 case TEL_SIM_EF_USIM_MWIS:
801 case TEL_SIM_EF_USIM_MBI:
802 case TEL_SIM_EF_MBDN:
803 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
804 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
805 if (file_meta->current_index == file_meta->rec_count) {
806 if (resp_cb_data->cb)
807 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
809 file_meta->current_index++;
810 __imc_sim_read_record(co, resp_cb_data);
814 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
816 ImcSimMetaInfo *file_meta_new = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
818 file_meta->files.result = sim_result;
819 if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
820 file_meta_new->files.data.cphs_net.full_name = file_meta->files.data.cphs_net.full_name;
821 dbg("file_meta_new->files.data.cphs_net.full_name[%s]", file_meta_new->files.data.cphs_net.full_name);
824 file_meta_new->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
825 file_meta_new->file_result = TEL_SIM_RESULT_FAILURE;
827 __imc_sim_get_response(co, resp_cb_data);
831 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
832 if (resp_cb_data->cb)
833 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.cphs_net, resp_cb_data->cb_data);
835 tcore_free(file_meta->files.data.cphs_net.full_name);
836 tcore_free(file_meta->files.data.cphs_net.short_name);
837 file_meta->files.data.cphs_net.full_name = NULL;
838 file_meta->files.data.cphs_net.short_name = NULL;
841 case TEL_SIM_EF_ICCID:
842 if (resp_cb_data->cb)
843 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.iccid, resp_cb_data->cb_data);
846 case TEL_SIM_EF_SPDI: {
848 dbg("spdi count[%d]", file_meta->files.data.spdi.count);
850 if (resp_cb_data->cb)
851 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
854 for (i = 0; i < file_meta->files.data.spdi.count; i++)
855 tcore_free(file_meta->files.data.spdi.list[i].plmn);
857 tcore_free(file_meta->files.data.spdi.list);
863 case TEL_SIM_EF_OPLMN_ACT:
864 case TEL_SIM_EF_CPHS_CPHS_INFO:
865 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
866 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
867 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
868 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
869 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
870 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
871 if (resp_cb_data->cb)
872 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
876 err("File id not handled [0x%x]", file_meta->file_id);
881 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result)
883 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
884 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
886 dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
888 file_meta->files.result = sim_result;
889 if (file_meta->file_id != TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING)
890 memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
892 if ((file_meta->file_id != TEL_SIM_EF_ELP && file_meta->file_id != TEL_SIM_EF_LP &&
893 file_meta->file_id != TEL_SIM_EF_USIM_PL && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
894 && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
895 if (resp_cb_data->cb)
896 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
900 switch (file_meta->file_id) {
902 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
903 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
904 __imc_sim_read_binary(co, resp_cb_data);
906 tcore_sim_get_type(co, &card_type);
907 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
908 ImcSimMetaInfo file_meta_new = {0,};
910 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
911 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
912 file_meta_new.file_id = TEL_SIM_EF_LP;
913 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
914 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
916 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
918 __imc_sim_get_response(co, resp_cb_data);
919 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
920 dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))");
921 if (resp_cb_data->cb)
922 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
929 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
930 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
931 __imc_sim_read_binary(co, resp_cb_data);
933 tcore_sim_get_type(co, &card_type);
934 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
935 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
936 if (resp_cb_data->cb)
937 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
940 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
941 else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
942 ImcSimMetaInfo file_meta_new = {0,};
944 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
945 file_meta_new.file_id = TEL_SIM_EF_ELP;
946 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
947 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
949 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
951 __imc_sim_get_response(co, resp_cb_data);
956 case TEL_SIM_EF_USIM_PL:
957 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
958 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
959 __imc_sim_read_binary(co, resp_cb_data);
961 /* EFELIand EFPL not present, so set language count as zero and select ECC */
963 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
964 if (resp_cb_data->cb)
965 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
971 tcore_sim_get_type(co, &card_type);
972 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
973 __imc_sim_read_binary(co, resp_cb_data);
974 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
975 if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) {
976 file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
978 file_meta->current_index++;
979 __imc_sim_read_record(co, resp_cb_data);
983 case TEL_SIM_EF_ICCID:
984 case TEL_SIM_EF_IMSI:
987 case TEL_SIM_EF_SPDI:
988 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
989 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
990 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
991 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
992 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
993 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
994 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
995 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
996 __imc_sim_read_binary(co, resp_cb_data);
999 case TEL_SIM_EF_CPHS_CPHS_INFO:
1000 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1001 tcore_sim_set_cphs_status(co, TRUE);
1002 __imc_sim_read_binary(co, resp_cb_data);
1004 tcore_sim_set_cphs_status(co, FALSE);
1005 if (resp_cb_data->cb)
1006 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1011 case TEL_SIM_EF_USIM_CFIS:
1012 if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) {
1013 file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
1015 file_meta->current_index++;
1016 __imc_sim_read_record(co, resp_cb_data);
1019 case TEL_SIM_EF_MSISDN:
1020 file_meta->files.data.msisdn_list.list =
1021 tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
1023 case TEL_SIM_EF_OPL:
1024 case TEL_SIM_EF_PNN:
1025 case TEL_SIM_EF_USIM_MWIS:
1026 case TEL_SIM_EF_USIM_MBI:
1027 case TEL_SIM_EF_MBDN:
1028 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
1029 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1030 file_meta->current_index++;
1031 __imc_sim_read_record(co, resp_cb_data);
1034 case TEL_SIM_EF_SMSP:
1036 ImcSimPrivateInfo *priv_info = NULL;
1038 priv_info = tcore_sim_ref_userdata(co);
1040 dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",file_meta->rec_count, file_meta->rec_length);
1041 priv_info->smsp_count = file_meta->rec_count;
1042 priv_info->smsp_rec_len = file_meta->rec_length;
1047 dbg("error - File id for get file info [0x%x]", file_meta->file_id);
1053 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data)
1055 const TcoreAtResponse *resp = data;
1056 CoreObject *co_sim = NULL;
1057 GSList *tokens = NULL;
1058 TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
1060 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1061 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1065 co_sim = tcore_pending_ref_core_object(p);
1067 dbg("file_id:[0x%x]", file_meta->file_id);
1069 if (resp->success > 0) {
1074 line = (const char *)resp->lines->data;
1075 tokens = tcore_at_tok_new(line);
1076 if (g_slist_length(tokens) != 2) {
1077 err("Invalid message");
1080 sw1 = atoi(g_slist_nth_data(tokens, 0));
1081 sw2 = atoi(g_slist_nth_data(tokens, 1));
1084 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1085 sim_result = TEL_SIM_RESULT_SUCCESS;
1087 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1090 err("RESPONSE NOK");
1091 sim_result = TEL_SIM_RESULT_FAILURE;
1095 if (resp_cb_data->cb)
1096 resp_cb_data->cb(co_sim, (gint)sim_result, NULL, resp_cb_data->cb_data);
1098 tcore_at_tok_free(tokens);
1102 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len,
1103 const void *data, void *user_data)
1105 const TcoreAtResponse *resp = data;
1106 CoreObject *co = NULL;
1107 GSList *tokens = NULL;
1108 TelSimResult sim_result;
1109 gboolean dr = FALSE;
1110 const char *line = NULL;
1116 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1117 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1118 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1122 co = tcore_pending_ref_core_object(p);
1124 if (resp->success > 0) {
1127 line = (const char *)resp->lines->data;
1128 tokens = tcore_at_tok_new(line);
1129 if (g_slist_length(tokens) != 3) {
1130 err("Invalid message");
1131 tcore_at_tok_free(tokens);
1135 sw1 = atoi(g_slist_nth_data(tokens, 0));
1136 sw2 = atoi(g_slist_nth_data(tokens, 1));
1137 res = g_slist_nth_data(tokens, 2);
1139 tmp = tcore_at_tok_extract(res);
1140 tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
1141 dbg("Response: [%s] Response length: [%d]", res, res_len);
1143 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1144 sim_result = TEL_SIM_RESULT_SUCCESS;
1145 file_meta->files.result = sim_result;
1147 dbg("File ID: [0x%x]", file_meta->file_id);
1148 switch (file_meta->file_id) {
1149 case TEL_SIM_EF_IMSI: {
1150 dbg("Data: [%s]", res);
1151 dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
1153 err("IMSI decoding failed");
1155 __imc_sim_set_identity(co, &file_meta->imsi);
1158 tcore_sim_set_imsi(co, &file_meta->imsi);
1163 case TEL_SIM_EF_ICCID: {
1164 dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
1165 file_meta->files.data.iccid);
1169 case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1170 case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1171 case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1172 case TEL_SIM_EF_LP: /* 1 byte encoding */
1174 tcore_sim_get_type(co, &card_type);
1175 if ((TEL_SIM_CARD_TYPE_GSM == card_type)
1176 && (file_meta->file_id == TEL_SIM_EF_LP)) {
1178 * 2G LP(0x6F05) has 1 byte for each language
1180 dr = tcore_sim_decode_lp((unsigned char *)res, res_len, &file_meta->files.data.language);
1183 * 3G LI(0x6F05)/PL(0x2F05),
1184 * 2G ELP(0x2F05) has 2 bytes for each language
1186 dr = tcore_sim_decode_li((unsigned char *)res, res_len,
1187 file_meta->file_id, &file_meta->files.data.language);
1192 case TEL_SIM_EF_SPN:
1193 dr = tcore_sim_decode_spn((unsigned char *)res, res_len, &file_meta->files.data.spn);
1196 case TEL_SIM_EF_SPDI:
1197 dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, &file_meta->files.data.spdi);
1200 case TEL_SIM_EF_SST:
1202 TelSimServiceTable *svct = NULL;
1204 svct = g_try_new0(TelSimServiceTable, 1);
1205 tcore_sim_get_type(co, &card_type);
1206 svct->sim_type = card_type;
1207 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1208 dr = tcore_sim_decode_sst((unsigned char *)res, res_len, svct->table.sst_service);
1209 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1210 dr = tcore_sim_decode_ust((unsigned char *)res, res_len, svct->table.ust_service);
1212 err("Not handled card_type[%d]", card_type);
1216 err("SST/UST decoding failed");
1218 tcore_sim_set_service_table(co, svct);
1226 case TEL_SIM_EF_ECC:
1228 tcore_sim_get_type(co, &card_type);
1229 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1230 dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, &file_meta->files.data.ecc);
1231 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1232 TelSimEcc *ecc = NULL;
1234 ecc = g_try_new0(TelSimEcc, 1);
1235 dbg("Index [%d]", file_meta->current_index);
1237 dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
1239 memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], ecc, sizeof(TelSimEcc));
1240 file_meta->files.data.ecc.count++;
1246 dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
1251 case TEL_SIM_EF_MSISDN:
1253 TelSimSubscriberInfo *msisdn = NULL;
1255 dbg("Index [%d]", file_meta->current_index);
1256 msisdn = tcore_malloc0(sizeof(TelSimSubscriberInfo));
1257 dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
1259 memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
1260 msisdn, sizeof(TelSimSubscriberInfo));
1262 file_meta->files.data.msisdn_list.count++;
1266 dbg("Freeing resources");
1271 case TEL_SIM_EF_OPL:
1273 TelSimOpl *opl = NULL;
1275 dbg("decode w/ index [%d]", file_meta->current_index);
1276 opl = g_try_new0(TelSimOpl, 1);
1278 dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
1280 memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
1281 opl, sizeof(TelSimOpl));
1283 file_meta->files.data.opl.opl_count++;
1291 case TEL_SIM_EF_PNN:
1293 TelSimPnn *pnn = NULL;
1295 dbg("decode w/ index [%d]", file_meta->current_index);
1296 pnn = g_try_new0(TelSimPnn, 1);
1298 dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
1300 memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
1301 pnn, sizeof(TelSimPnn));
1303 file_meta->files.data.pnn.pnn_count++;
1311 case TEL_SIM_EF_OPLMN_ACT:
1312 /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1313 (unsigned char *)res, res_len);*/
1316 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1317 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1318 p_data->response, p_data->response_len);*/
1321 case TEL_SIM_EF_USIM_MBI: /* linear type */
1323 TelSimMbi *mbi = NULL;
1325 mbi = g_try_new0(TelSimMbi, 1);
1326 dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
1328 memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
1329 mbi, sizeof(TelSimMbi));
1330 file_meta->mbi_list.count++;
1332 dbg("mbi count[%d]", file_meta->mbi_list.count);
1340 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1341 case TEL_SIM_EF_MBDN: /* linear type */
1342 dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
1343 file_meta->mb_list[file_meta->current_index-1].alpha_id,
1344 file_meta->mb_list[file_meta->current_index-1].number);
1345 file_meta->mb_list[file_meta->current_index-1].alpha_id_len = strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
1346 file_meta->mb_list[file_meta->current_index-1].profile_id = file_meta->current_index;
1349 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1350 dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1353 case TEL_SIM_EF_USIM_MWIS: { /* linear type */
1354 TelSimMwis *mw = NULL;
1356 mw = g_try_new0(TelSimMwis, 1);
1358 dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
1360 guint count = file_meta->files.data.mw.profile_count;
1362 memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
1365 * The Profile Identity shall be between 1 and 4 as defined
1366 * in TS 23.097 for MSP
1368 file_meta->files.data.mw.mw[count].profile_id = count+1;
1370 file_meta->files.data.mw.profile_count++;
1378 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
1379 dr = tcore_sim_decode_cff((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1382 case TEL_SIM_EF_USIM_CFIS: /* linear type */
1384 TelSimCfis *cf = NULL;
1386 cf = g_try_new0(TelSimCfis, 1);
1387 dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
1389 memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
1390 cf, sizeof(TelSimCfis));
1391 file_meta->files.data.cf.profile_count++;
1399 case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
1400 dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1403 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1404 file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1405 dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
1406 (unsigned char*)file_meta->files.data.cphs_net.full_name);
1407 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1408 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1411 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1412 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1413 p_data->response, p_data->response_len);*/
1416 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1417 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1418 p_data->response_len);*/
1421 case TEL_SIM_EF_CPHS_CPHS_INFO:
1422 /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1423 (unsigned char *)res, res_len);*/
1426 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1427 file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
1428 dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
1429 (unsigned char*)file_meta->files.data.cphs_net.short_name);
1430 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
1431 file_meta->files.result, file_meta->files.data.cphs_net.short_name);
1434 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1435 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1439 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1444 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1445 file_meta->files.result = sim_result;
1453 tcore_at_tok_free(tokens);
1455 err("RESPONSE NOK");
1456 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1457 sim_result = TEL_SIM_RESULT_FAILURE;
1461 __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
1466 static void __on_response_imc_sim_get_response(TcorePending *p,
1467 guint data_len, const void *data, void *user_data)
1469 const TcoreAtResponse *resp = data;
1470 CoreObject *co = NULL;
1471 TelSimResult sim_result;
1472 GSList *tokens = NULL;
1473 const char *line = NULL;
1476 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
1477 ImcSimMetaInfo *file_meta =
1478 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1480 dbg("SIM Response - SIM File info: [+CRSM]");
1482 co = tcore_pending_ref_core_object(p);
1484 if (resp->success > 0) {
1487 line = (const char *)resp->lines->data;
1488 tokens = tcore_at_tok_new(line);
1489 if (g_slist_length(tokens) < 2) {
1490 err("Invalid message");
1491 tcore_at_tok_free(tokens);
1495 sw1 = atoi(g_slist_nth_data(tokens, 0));
1496 sw2 = atoi(g_slist_nth_data(tokens, 1));
1498 /*1. SIM access success case*/
1499 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1500 unsigned char tag_len = 0;
1501 unsigned short record_len = 0;
1502 char num_of_records = 0;
1503 unsigned char file_id_len = 0;
1504 unsigned short file_id = 0;
1505 unsigned short file_size = 0;
1506 unsigned short file_type = 0;
1507 unsigned short arr_file_id = 0;
1508 int arr_file_id_rec_num = 0;
1509 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1511 /* handling only last 3 bits */
1512 unsigned char file_type_tag = 0x07;
1513 unsigned char *ptr_data;
1517 char *record_data = NULL;
1518 guint record_data_len;
1519 hexData = g_slist_nth_data(tokens, 2);
1520 dbg("hexData: %s", hexData);
1521 dbg("hexData: %s", hexData + 1);
1523 tmp = tcore_at_tok_extract(hexData);
1524 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
1525 tcore_util_hex_dump(" ", record_data_len, record_data);
1528 ptr_data = (unsigned char *)record_data;
1529 tcore_sim_get_type(co, &card_type);
1530 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1532 ETSI TS 102 221 v7.9.0
1534 '62' FCP template tag
1535 - Response for an EF
1536 '82' M File Descriptor
1537 '83' M File Identifier
1538 'A5' O Proprietary information
1539 '8A' M Life Cycle Status Integer
1540 '8B', '8C' or 'AB' C1 Security attributes
1542 '81' O Total file size
1543 '88' O Short File Identifier (SFI)
1546 /* rsim.res_len has complete data length received */
1548 /* FCP template tag - File Control Parameters tag*/
1549 if (*ptr_data == 0x62) {
1550 /* parse complete FCP tag*/
1551 /* increment to next byte */
1553 tag_len = *ptr_data++;
1554 dbg("tag_len: %02x", tag_len);
1555 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1556 if (*ptr_data == 0x82) {
1557 /* increment to next byte */
1561 /* consider only last 3 bits*/
1562 dbg("file_type_tag: %02x", file_type_tag);
1563 file_type_tag = file_type_tag & (*ptr_data);
1564 dbg("file_type_tag: %02x", file_type_tag);
1566 switch (file_type_tag) {
1567 /* increment to next byte */
1570 dbg("Getting FileType: [Transparent file type]");
1571 file_type = IMC_SIM_FILE_TYPE_TRANSPARENT;
1573 /* increment to next byte */
1575 /* increment to next byte */
1580 dbg("Getting FileType: [Linear fixed file type]");
1581 /* increment to next byte */
1583 /* data coding byte - value 21 */
1586 memcpy(&record_len, ptr_data, 2);
1588 IMC_SWAP_BYTES_16(record_len);
1589 ptr_data = ptr_data + 2;
1590 num_of_records = *ptr_data++;
1591 /* Data lossy conversation from enum (int) to unsigned char */
1592 file_type = IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1596 dbg("Cyclic fixed file type");
1597 /* increment to next byte */
1599 /* data coding byte - value 21 */
1602 memcpy(&record_len, ptr_data, 2);
1604 IMC_SWAP_BYTES_16(record_len);
1605 ptr_data = ptr_data + 2;
1606 num_of_records = *ptr_data++;
1607 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1611 dbg("not handled file type [0x%x]", *ptr_data);
1615 dbg("INVALID FCP received - DEbug!");
1616 tcore_at_tok_free(tokens);
1617 g_free(record_data);
1621 /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
1622 if (*ptr_data == 0x83) {
1623 /* increment to next byte */
1625 file_id_len = *ptr_data++;
1626 dbg("file_id_len: %02x", file_id_len);
1628 memcpy(&file_id, ptr_data, file_id_len);
1629 dbg("file_id: %x", file_id);
1632 IMC_SWAP_BYTES_16(file_id);
1633 dbg("file_id: %x", file_id);
1635 ptr_data = ptr_data + 2;
1636 dbg("Getting FileID=[0x%x]", file_id);
1638 dbg("INVALID FCP received - DEbug!");
1639 tcore_at_tok_free(tokens);
1640 g_free(record_data);
1644 /* proprietary information */
1645 if (*ptr_data == 0xA5) {
1646 unsigned short prop_len;
1647 /* increment to next byte */
1651 prop_len = *ptr_data;
1652 dbg("prop_len: %02x", prop_len);
1655 ptr_data = ptr_data + prop_len + 1;
1657 dbg("INVALID FCP received - DEbug!");
1660 /* life cycle status integer [8A][length:0x01][status]*/
1663 00000000 : No information given
1664 00000001 : creation state
1665 00000011 : initialization state
1666 000001-1 : operation state -activated
1667 000001-0 : operation state -deactivated
1668 000011-- : Termination state
1669 b8~b5 !=0, b4~b1=X : Proprietary
1670 Any other value : RFU
1672 if (*ptr_data == 0x8A) {
1673 /* increment to next byte */
1675 /* length - value 1 */
1678 switch (*ptr_data) {
1681 dbg("<RX> operation state -deactivated");
1687 dbg("<RX> operation state -activated");
1692 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1698 /* related to security attributes : currently not handled*/
1699 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1700 /* increment to next byte */
1702 /* if tag length is 3 */
1703 if (*ptr_data == 0x03) {
1704 /* increment to next byte */
1707 memcpy(&arr_file_id, ptr_data, 2);
1709 IMC_SWAP_BYTES_16(arr_file_id);
1710 ptr_data = ptr_data + 2;
1711 arr_file_id_rec_num = *ptr_data++;
1712 dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
1714 /* if tag length is not 3 */
1715 /* ignoring bytes */
1716 // ptr_data = ptr_data + 4;
1717 dbg("Useless security attributes, so jump to next tag");
1718 ptr_data = ptr_data + (*ptr_data + 1);
1721 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1722 tcore_at_tok_free(tokens);
1723 g_free(record_data);
1727 dbg("Current ptr_data value is [%x]", *ptr_data);
1729 /* file size excluding structural info*/
1730 if (*ptr_data == 0x80) {
1731 /* for EF file size is body of file and for Linear or cyclic it is
1732 * number of recXsizeof(one record)
1734 /* increment to next byte */
1736 /* length is 1 byte - value is 2 bytes or more */
1738 memcpy(&file_size, ptr_data, 2);
1740 IMC_SWAP_BYTES_16(file_size);
1741 ptr_data = ptr_data + 2;
1743 dbg("INVALID FCP received - DEbug!");
1744 tcore_at_tok_free(tokens);
1745 g_free(record_data);
1749 /* total file size including structural info*/
1750 if (*ptr_data == 0x81) {
1752 /* increment to next byte */
1756 dbg("len:[%d]", len);
1758 ptr_data = ptr_data + 3;
1760 dbg("INVALID FCP received - DEbug!");
1761 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1763 /*short file identifier ignored*/
1764 if (*ptr_data == 0x88) {
1765 dbg("0x88: Do Nothing");
1769 dbg("INVALID FCP received - DEbug!");
1770 tcore_at_tok_free(tokens);
1771 g_free(record_data);
1774 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1775 unsigned char gsm_specific_file_data_len = 0;
1776 /* ignore RFU byte1 and byte2 */
1780 // file_size = p_info->response_len;
1781 memcpy(&file_size, ptr_data, 2);
1783 IMC_SWAP_BYTES_16(file_size);
1784 /* parsed file size */
1785 ptr_data = ptr_data + 2;
1787 memcpy(&file_id, ptr_data, 2);
1788 IMC_SWAP_BYTES_16(file_id);
1789 dbg("FILE id --> [%x]", file_id);
1790 ptr_data = ptr_data + 2;
1791 /* save file type - transparent, linear fixed or cyclic */
1792 file_type_tag = (*(ptr_data + 7));
1794 switch (*ptr_data) {
1797 dbg("RFU file type- not handled - Debug!");
1802 dbg("MF file type - not handled - Debug!");
1807 dbg("DF file type - not handled - Debug!");
1812 dbg("EF file type [%d] ", file_type_tag);
1813 /* increment to next byte */
1816 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1817 /* increament to next byte as this byte is RFU */
1820 (file_type_tag == 0x00) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1822 /* increment to next byte */
1824 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1825 /* the INCREASE command is allowed on the selected cyclic file. */
1826 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1828 /* bytes 9 to 11 give SIM file access conditions */
1830 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1832 /* byte 11 is invalidate and rehabilate nibbles */
1834 /* byte 12 - file status */
1836 /* byte 13 - GSM specific data */
1837 gsm_specific_file_data_len = *ptr_data;
1838 dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
1840 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1842 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1843 record_len = *ptr_data;
1844 dbg("record length[%d], file size[%d]", record_len, file_size);
1845 if (record_len != 0)
1846 num_of_records = (file_size / record_len);
1848 dbg("Number of records [%d]", num_of_records);
1852 dbg("not handled file type");
1856 err("Unknown Card Type - [%d]", card_type);
1859 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1860 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1862 file_meta->file_type = file_type;
1863 file_meta->data_size = file_size;
1864 file_meta->rec_length = record_len;
1865 file_meta->rec_count = num_of_records;
1866 file_meta->current_index = 0; /* reset for new record type EF */
1867 sim_result = TEL_SIM_RESULT_SUCCESS;
1868 g_free(record_data);
1870 /*2. SIM access fail case*/
1871 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1872 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1875 tcore_at_tok_free(tokens);
1877 err("RESPONSE NOK");
1878 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1879 sim_result = TEL_SIM_RESULT_FAILURE;
1882 dbg("Calling __imc_sim_next_from_get_response");
1883 __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
1887 static TelReturn __imc_sim_update_file(CoreObject *co,
1888 ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
1889 int p1, int p2, int p3, char *encoded_data)
1891 char *cmd_str = NULL;
1892 TelReturn ret = TEL_RETURN_FAILURE;
1893 ImcSimMetaInfo *file_meta =
1894 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1896 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1898 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"",
1899 cmd, ef, p1, p2, p3, encoded_data);
1901 ret = tcore_at_prepare_and_send_request(co,
1903 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1905 __on_response_imc_sim_update_file, resp_cb_data,
1906 on_send_imc_request, NULL);
1907 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
1909 tcore_free(encoded_data);
1915 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
1917 gchar *at_cmd = NULL;
1921 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1922 TelReturn ret = TEL_RETURN_FAILURE;
1924 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1926 /* According to TS 102 221, values of p1, p2, p3 can be as below:
1927 * 11.1.5 READ RECORD
1929 * P2: Mode, see table 11.11
1932 * Le: Number of bytes to be read (P3)
1935 p1 = (unsigned char) file_meta->current_index;
1936 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1937 p3 = (unsigned char) file_meta->rec_length;
1939 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1940 IMC_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
1942 ret = tcore_at_prepare_and_send_request(co,
1944 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1946 __on_response_imc_sim_read_data, resp_cb_data,
1947 on_send_imc_request, NULL);
1948 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
1950 dbg("ret:[%d]", ret);
1956 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
1958 gchar *at_cmd = NULL;
1963 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1964 TelReturn ret = TEL_RETURN_FAILURE;
1966 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1968 /* According to TS 102 221, values of P1, P2, P3 can be as below:
1969 * 11.1.3 READ BINARY
1970 * P1: See table 11.10
1974 * Le: Number of bytes to be read (P3)
1977 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1978 p2 = (unsigned char) offset & 0x00FF; /* offset low */
1979 p3 = (unsigned char) file_meta->data_size;
1981 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1982 IMC_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
1984 ret = tcore_at_prepare_and_send_request(co,
1986 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1988 __on_response_imc_sim_read_data, resp_cb_data,
1989 on_send_imc_request, NULL);
1990 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
1992 dbg("ret:[%d]", ret);
1998 static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
2000 gchar *at_cmd = NULL;
2001 ImcSimMetaInfo *file_meta =
2002 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2003 TelReturn ret = TEL_RETURN_FAILURE;
2005 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2007 at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
2008 IMC_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
2010 ret = tcore_at_prepare_and_send_request(co,
2012 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2014 __on_response_imc_sim_get_response, resp_cb_data,
2015 on_send_imc_request, NULL);
2016 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
2023 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
2024 const void *data, void *user_data)
2026 TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
2027 const TcoreAtResponse *at_resp = data;
2028 ImcRespCbData *resp_cb_data = user_data;
2029 CoreObject *co = tcore_pending_ref_core_object(p);
2030 ImcSimCurrSecOp *sec_op = NULL;
2031 GSList *tokens = NULL;
2032 const char *line = NULL;
2034 int attempts_left = 0;
2035 int time_penalty = 0;
2039 tcore_check_return_assert(co != NULL);
2040 tcore_check_return_assert(resp_cb_data != NULL);
2042 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2044 if (at_resp && at_resp->success) {
2045 dbg("Sim Get Retry Count [OK]");
2047 if (at_resp->lines) {
2048 line = (const char *)at_resp->lines->data;
2049 tokens = tcore_at_tok_new(line);
2050 if (g_slist_length(tokens) < 3) {
2051 err("Invalid message");
2055 lock_type = atoi(g_slist_nth_data(tokens, 0));
2056 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2057 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2059 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2060 lock_type, attempts_left, time_penalty);
2063 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2064 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2066 TelSimSecPinResult verify_pin = {0, };
2068 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
2069 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2070 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
2071 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2073 verify_pin.retry_count = attempts_left;
2075 if(resp_cb_data->cb)
2076 resp_cb_data->cb(co, (gint)result,
2077 &verify_pin, resp_cb_data->cb_data);
2080 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2081 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2083 TelSimSecPukResult verify_puk = {0, };
2085 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
2086 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2087 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
2088 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2090 verify_puk.retry_count = attempts_left;
2092 if(resp_cb_data->cb)
2093 resp_cb_data->cb(co, (gint)result,
2094 &verify_puk, resp_cb_data->cb_data);
2097 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2098 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2100 TelSimSecPinResult change_pin = {0, };
2102 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
2103 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2104 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
2105 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2107 change_pin.retry_count = attempts_left;
2109 if(resp_cb_data->cb)
2110 resp_cb_data->cb(co, (gint)result,
2111 &change_pin, resp_cb_data->cb_data);
2114 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2115 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2116 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2117 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
2118 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2119 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2120 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2121 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2123 TelSimFacilityResult disable_facility = {0, };
2126 lock_type = __imc_sim_get_lock_type(*sec_op);
2127 if (lock_type == -1)
2130 disable_facility.type = lock_type;
2131 disable_facility.retry_count = attempts_left;
2133 if(resp_cb_data->cb)
2134 resp_cb_data->cb(co, (gint)result,
2135 &disable_facility, resp_cb_data->cb_data);
2138 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2139 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2140 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2141 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
2142 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2143 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2144 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2145 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2147 TelSimFacilityResult enable_facility = {0, };
2150 lock_type = __imc_sim_get_lock_type(*sec_op);
2151 if (lock_type == -1)
2154 enable_facility.type = lock_type;
2155 enable_facility.retry_count = attempts_left;
2157 if(resp_cb_data->cb)
2158 resp_cb_data->cb(co, (gint)result,
2159 &enable_facility, resp_cb_data->cb_data);
2163 err("Unhandled sec op [%d]", *sec_op);
2167 tcore_at_tok_free(tokens);
2168 imc_destroy_resp_cb_data(resp_cb_data);
2171 err("Sim Get Retry Count [NOK]");
2173 /*TODO - send response for verify pin, puk etc.,
2174 * when get_retry_count fails
2176 tcore_at_tok_free(tokens);
2177 imc_destroy_resp_cb_data(resp_cb_data);
2180 static TelReturn __imc_sim_get_retry_count(CoreObject *co,
2181 ImcRespCbData *resp_cb_data)
2183 TelReturn ret = TEL_RETURN_FAILURE;
2184 ImcSimCurrSecOp *sec_op = (
2185 ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2187 gchar *cmd_str = NULL;
2192 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2193 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2194 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2195 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2198 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2199 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2200 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2201 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2202 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2203 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2206 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2209 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2212 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2213 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2216 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2217 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2220 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2221 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2224 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2225 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2228 case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
2234 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2236 ret = tcore_at_prepare_and_send_request(co,
2238 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2240 __on_response_imc_sim_get_retry_count, resp_cb_data,
2241 on_send_imc_request, NULL);
2242 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
2248 static TelSimLockType __imc_sim_lock_type(int lock_type)
2252 return TEL_SIM_LOCK_SC;
2254 return TEL_SIM_LOCK_FD;
2256 return TEL_SIM_LOCK_PN;
2258 return TEL_SIM_LOCK_PU;
2260 return TEL_SIM_LOCK_PP;
2262 return TEL_SIM_LOCK_PC ;
2264 return TEL_SIM_LOCK_PS ;
2266 err("Invalid lock_type [%d]", lock_type);
2271 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
2272 ImcSimCurrSecOp *sec_op, int flag)
2276 case TEL_SIM_LOCK_PS :
2278 if (flag == ENABLE_FLAG)
2279 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
2280 else if (flag == DISABLE_FLAG)
2281 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
2283 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
2285 case TEL_SIM_LOCK_SC :
2287 if (flag == ENABLE_FLAG)
2288 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
2289 else if (flag == DISABLE_FLAG)
2290 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
2292 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
2294 case TEL_SIM_LOCK_FD :
2296 if (flag == ENABLE_FLAG)
2297 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
2298 else if (flag == DISABLE_FLAG)
2299 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
2301 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
2303 case TEL_SIM_LOCK_PN :
2305 if (flag == ENABLE_FLAG)
2306 *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
2307 else if (flag == DISABLE_FLAG)
2308 *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
2310 *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
2312 case TEL_SIM_LOCK_PU :
2314 if (flag == ENABLE_FLAG)
2315 *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
2316 else if (flag == DISABLE_FLAG)
2317 *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
2319 *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
2321 case TEL_SIM_LOCK_PP :
2323 if (flag == ENABLE_FLAG)
2324 *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
2325 else if (flag == DISABLE_FLAG)
2326 *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
2328 *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
2330 case TEL_SIM_LOCK_PC :
2332 if (flag == ENABLE_FLAG)
2333 *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
2334 else if (flag == DISABLE_FLAG)
2335 *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
2337 *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
2340 err("Unhandled sim lock type [%d]", lock_type);
2345 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
2348 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
2349 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
2350 case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
2351 return TEL_SIM_LOCK_PS;
2352 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
2353 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
2354 case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
2355 return TEL_SIM_LOCK_SC;
2356 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
2357 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
2358 case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
2359 return TEL_SIM_LOCK_FD;
2360 case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
2361 case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
2362 case IMC_SIM_CURR_SEC_OP_NET_STATUS :
2363 return TEL_SIM_LOCK_PN;
2364 case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
2365 case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
2366 case IMC_SIM_CURR_SEC_OP_NS_STATUS :
2367 return TEL_SIM_LOCK_PU;
2368 case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
2369 case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
2370 case IMC_SIM_CURR_SEC_OP_SP_STATUS :
2371 return TEL_SIM_LOCK_PP;
2372 case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
2373 case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
2374 case IMC_SIM_CURR_SEC_OP_CP_STATUS :
2375 return TEL_SIM_LOCK_PC ;
2377 err("Invalid sec op [%d]", sec_op);
2384 * Notification: +XSIM: <SIM state>
2386 * Possible values of <SIM state> can be
2388 * 1 PIN verification needed
2389 * 2 PIN verification not needed - Ready
2390 * 3 PIN verified - Ready
2391 * 4 PUK verification needed
2392 * 5 SIM permanently blocked
2394 * 7 ready for attach (+COPS)
2395 * 8 SIM Technical Problem
2397 * 10 SIM Reactivating
2398 * 11 SIM Reactivated
2399 * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled)
2400 * 99 SIM State Unknown
2402 static gboolean on_notification_imc_sim_status(CoreObject *co,
2403 const void *event_info, void *user_data)
2405 GSList *lines = (GSList *)event_info;
2408 dbg("SIM notification - SIM status: [+XSIM]");
2410 if (g_slist_length(lines) != 1) {
2411 err("+XSIM unsolicited message expected to be "
2412 "Single line but received multiple lines");
2416 line = (const gchar *) (lines->data);
2424 * +XSIM: <SIM state>
2426 tokens = tcore_at_tok_new(line);
2427 if (g_slist_length(tokens) == 1) {
2429 sim_state = atoi(g_slist_nth_data(tokens, 0));
2431 /* Process SIM Status */
2432 __imc_sim_process_sim_status(co, sim_state);
2434 err("Invalid message");
2437 tcore_at_tok_free(tokens);
2444 static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
2445 TcoreNotification command, guint data_len, void *data, void *user_data)
2447 CoreObject *co = (CoreObject *)user_data;
2449 tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
2451 dbg("Get SIM status");
2452 (void)__imc_sim_get_sim_status(co, NULL, NULL);
2454 return TCORE_HOOK_RETURN_CONTINUE;
2457 /* Response Functions */
2458 static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
2459 const void *data, void *user_data)
2461 const TcoreAtResponse *at_resp = data;
2462 GSList *tokens = NULL;
2463 CoreObject *co = tcore_pending_ref_core_object(p);
2464 TelSimAuthenticationResponse auth_resp = {0, };
2465 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
2466 ImcRespCbData *resp_cb_data = user_data;
2467 TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2471 if (NULL == at_resp) {
2472 err("at_resp is NULL");
2473 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2477 auth_resp.auth_type = *auth_type;
2479 if (at_resp->success == TRUE) {
2484 if (at_resp->lines != NULL) {
2485 line = at_resp->lines->data;
2486 dbg("Received data: [%s]", line);
2488 err("at_resp->lines is NULL");
2489 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2493 tokens = tcore_at_tok_new(line);
2494 if (tokens == NULL) {
2495 err("tokens is NULL");
2496 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2500 status = atoi(g_slist_nth_data(tokens, 0));
2503 dbg("Authentications successful");
2504 auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
2507 err("Synchronize fail");
2508 auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
2512 auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
2515 err("Does not support security context");
2516 auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
2519 err("Other failure");
2520 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2524 if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
2526 char *convert_kc, *convert_sres;
2528 kc = g_slist_nth_data(tokens, 1);
2530 guint convert_kc_len = 0;
2531 kc = tcore_at_tok_extract(kc);
2532 dbg("Kc: [%s]", kc);
2534 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2535 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2536 auth_resp.authentication_key_length = convert_kc_len;
2537 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2540 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2546 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2550 sres = g_slist_nth_data(tokens, 2);
2552 guint convert_sres_len = 0;
2553 sres = tcore_at_tok_extract(sres);
2554 dbg("SRES: [%s]", sres);
2556 tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
2557 if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2558 auth_resp.resp_length = convert_sres_len;
2559 memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
2561 err("Invalid SRES");
2562 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2565 g_free(convert_sres);
2567 err("Invalid SRES");
2568 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2571 } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
2572 char *res, *ck, *ik, *kc;
2573 char *convert_res, *convert_ck;
2574 char *convert_ik, *convert_kc;
2576 res = g_slist_nth_data(tokens, 1);
2578 guint convert_res_len = 0;
2579 res = tcore_at_tok_extract(res);
2580 dbg("RES/AUTS: [%s]", res);
2582 tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
2583 if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2584 auth_resp.resp_length = convert_res_len;
2585 memcpy(auth_resp.resp_data, convert_res, convert_res_len);
2587 err("Invalid RES/AUTS");
2588 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2591 g_free(convert_res);
2593 err("Invalid RES/AUTS");
2594 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2598 ck = g_slist_nth_data(tokens, 2);
2600 guint convert_ck_len = 0;
2601 ck = tcore_at_tok_extract(ck);
2602 dbg("CK: [%s]", ck);
2604 tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
2605 if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2606 auth_resp.cipher_length = convert_ck_len;
2607 memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
2610 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2616 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2620 ik = g_slist_nth_data(tokens, 3);
2622 guint convert_ik_len = 0;
2623 ik = tcore_at_tok_extract(ik);
2624 dbg("IK: [%s]", ik);
2626 tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
2627 if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2628 auth_resp.integrity_length = convert_ik_len;
2629 memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
2632 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2638 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2642 kc = g_slist_nth_data(tokens, 4);
2644 guint convert_kc_len = 0;
2645 kc = tcore_at_tok_extract(kc);
2646 dbg("Kc: [%s]", kc);
2648 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2649 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2650 auth_resp.authentication_key_length = convert_kc_len;
2651 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2654 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2660 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2664 err("Not supported");
2665 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2668 sim_result = TEL_SIM_RESULT_SUCCESS;
2670 err("RESPONSE NOK");
2671 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2675 if(resp_cb_data->cb)
2676 resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
2678 tcore_at_tok_free(tokens);
2681 static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
2682 const void *data, void *user_data)
2684 const TcoreAtResponse *at_resp = data;
2685 ImcRespCbData *resp_cb_data = user_data;
2686 CoreObject *co = tcore_pending_ref_core_object(p);
2687 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2688 ImcSimCurrSecOp *sec_op = NULL;
2689 TelSimSecPinResult verify_pin_resp = {0, };
2693 tcore_check_return_assert(co != NULL);
2694 tcore_check_return_assert(resp_cb_data != NULL);
2696 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2698 if (at_resp && at_resp->success) {
2699 dbg("Sim Verify Pin Response- [OK]");
2701 result = TEL_SIM_RESULT_SUCCESS;
2703 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
2704 TelSimCardStatus status;
2706 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2708 tcore_sim_get_status(co, &status);
2709 if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
2710 /*Update sim status*/
2711 __imc_sim_update_sim_status(co,
2712 TEL_SIM_STATUS_SIM_INITIALIZING);
2714 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
2715 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2719 if(resp_cb_data->cb)
2720 resp_cb_data->cb(co, (gint)result,
2722 resp_cb_data->cb_data);
2723 imc_destroy_resp_cb_data(resp_cb_data);
2725 err("Sim Verify Pin Response- [NOK]");
2726 /* Get retry count */
2727 __imc_sim_get_retry_count(co, resp_cb_data);
2731 static void on_response_imc_sim_verify_puks(TcorePending *p, guint data_len,
2732 const void *data, void *user_data)
2734 const TcoreAtResponse *at_resp = data;
2735 ImcRespCbData *resp_cb_data = user_data;
2736 CoreObject *co = tcore_pending_ref_core_object(p);
2737 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2738 ImcSimCurrSecOp *sec_op = NULL;
2739 TelSimSecPukResult verify_puk_resp = {0, };
2743 tcore_check_return_assert(co != NULL);
2744 tcore_check_return_assert(resp_cb_data != NULL);
2746 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2748 if (at_resp && at_resp->success) {
2749 dbg("Sim Verify Puk Response- [OK]");
2751 result = TEL_SIM_RESULT_SUCCESS;
2753 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
2754 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2755 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
2756 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2759 if(resp_cb_data->cb)
2760 resp_cb_data->cb(co, (gint)result,
2762 resp_cb_data->cb_data);
2763 imc_destroy_resp_cb_data(resp_cb_data);
2765 err("Sim Verify Puk Response- [NOK]");
2766 /* Get retry count */
2767 __imc_sim_get_retry_count(co, resp_cb_data);
2771 static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
2772 const void *data, void *user_data)
2774 const TcoreAtResponse *at_resp = data;
2775 ImcRespCbData *resp_cb_data = user_data;
2776 CoreObject *co = tcore_pending_ref_core_object(p);
2777 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2778 ImcSimCurrSecOp *sec_op = NULL;
2779 TelSimSecPinResult change_pin_resp = {0, };
2783 tcore_check_return_assert(co != NULL);
2784 tcore_check_return_assert(resp_cb_data != NULL);
2786 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2788 if (at_resp && at_resp->success) {
2789 dbg("Sim Change Pin Response- [OK]");
2791 result = TEL_SIM_RESULT_SUCCESS;
2793 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
2794 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2795 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE) {
2796 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2799 if(resp_cb_data->cb)
2800 resp_cb_data->cb(co, (gint)result,
2802 resp_cb_data->cb_data);
2803 imc_destroy_resp_cb_data(resp_cb_data);
2805 err("Sim Change Pin Response- [NOK]");
2806 /* Get retry count */
2807 __imc_sim_get_retry_count(co, resp_cb_data);
2811 static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
2812 const void *data, void *user_data)
2814 const TcoreAtResponse *at_resp = data;
2815 ImcRespCbData *resp_cb_data = user_data;
2816 CoreObject *co = tcore_pending_ref_core_object(p);
2817 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2818 ImcSimCurrSecOp *sec_op = NULL;
2819 TelSimFacilityResult disable_facility_resp = {0, };
2823 tcore_check_return_assert(co != NULL);
2824 tcore_check_return_assert(resp_cb_data != NULL);
2826 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2828 if (at_resp && at_resp->success) {
2830 dbg("Sim Disable Facility Response- [OK]");
2832 lock_type = __imc_sim_get_lock_type(*sec_op);
2833 if (lock_type == -1) {
2834 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2837 if(resp_cb_data->cb)
2838 resp_cb_data->cb(co, (gint)result,
2840 resp_cb_data->cb_data);
2841 imc_destroy_resp_cb_data(resp_cb_data);
2845 disable_facility_resp.type = lock_type;
2846 result = TEL_SIM_RESULT_SUCCESS;
2849 if(resp_cb_data->cb)
2850 resp_cb_data->cb(co, (gint)result,
2851 &disable_facility_resp,
2852 resp_cb_data->cb_data);
2853 imc_destroy_resp_cb_data(resp_cb_data);
2855 err("Sim Disable Facility Response- [NOK]");
2856 /* Get retry count */
2857 __imc_sim_get_retry_count(co, resp_cb_data);
2861 static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
2862 const void *data, void *user_data)
2864 const TcoreAtResponse *at_resp = data;
2865 ImcRespCbData *resp_cb_data = user_data;
2866 CoreObject *co = tcore_pending_ref_core_object(p);
2867 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2868 ImcSimCurrSecOp *sec_op = NULL;
2869 TelSimFacilityResult enable_facility_resp = {0, };
2873 tcore_check_return_assert(co != NULL);
2874 tcore_check_return_assert(resp_cb_data != NULL);
2876 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2878 if (at_resp && at_resp->success) {
2880 dbg("Sim Enable Facility Response- [OK]");
2882 lock_type = __imc_sim_get_lock_type(*sec_op);
2883 if (lock_type == -1) {
2884 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2887 if(resp_cb_data->cb)
2888 resp_cb_data->cb(co, (gint)result,
2890 resp_cb_data->cb_data);
2891 imc_destroy_resp_cb_data(resp_cb_data);
2895 enable_facility_resp.type = lock_type;
2896 result = TEL_SIM_RESULT_SUCCESS;
2899 if(resp_cb_data->cb)
2900 resp_cb_data->cb(co, (gint)result,
2901 &enable_facility_resp,
2902 resp_cb_data->cb_data);
2903 imc_destroy_resp_cb_data(resp_cb_data);
2905 err("Sim Enable Facility Response- [NOK]");
2906 /* Get retry count */
2907 __imc_sim_get_retry_count(co, resp_cb_data);
2911 static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
2912 const void *data, void *user_data)
2914 const TcoreAtResponse *at_resp = data;
2915 ImcRespCbData *resp_cb_data = user_data;
2916 CoreObject *co = tcore_pending_ref_core_object(p);
2917 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2918 ImcSimCurrSecOp *sec_op = NULL;
2919 TelSimFacilityInfo get_facility_resp = {0, };
2923 tcore_check_return_assert(co != NULL);
2924 tcore_check_return_assert(resp_cb_data != NULL);
2926 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2928 if (at_resp && at_resp->success) {
2929 GSList *tokens = NULL;
2933 dbg("Sim Get Facility Response- [OK]");
2935 lock_type = __imc_sim_get_lock_type(*sec_op);
2936 if (lock_type == -1) {
2937 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2940 if (at_resp->lines) {
2941 line = (const char *)at_resp->lines->data;
2942 tokens = tcore_at_tok_new(line);
2943 if (g_slist_length(tokens) != 1) {
2944 err("Invalid message");
2945 tcore_at_tok_free(tokens);
2948 get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
2949 get_facility_resp.type = lock_type;
2950 result = TEL_SIM_RESULT_SUCCESS;
2953 tcore_at_tok_free(tokens);
2955 err("Sim Get Facility Response- [NOK]");
2958 /* Invoke callback */
2959 if(resp_cb_data->cb)
2960 resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
2961 imc_destroy_resp_cb_data(resp_cb_data);
2964 static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
2965 const void *data, void *user_data)
2967 const TcoreAtResponse *at_resp = data;
2968 ImcRespCbData *resp_cb_data = user_data;
2969 CoreObject *co = tcore_pending_ref_core_object(p);
2970 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2971 TelSimLockInfo get_lock_info_resp = {0, };
2975 tcore_check_return_assert(co != NULL);
2976 tcore_check_return_assert(resp_cb_data != NULL);
2978 if(at_resp && at_resp->success) {
2979 GSList *tokens = NULL;
2982 int attempts_left = 0;
2983 int time_penalty = 0;
2985 dbg("Sim Get Lock Info Response- [OK]");
2987 if (at_resp->lines) {
2988 line = (const char *)at_resp->lines->data;
2989 tokens = tcore_at_tok_new(line);
2990 if (g_slist_length(tokens) < 3) {
2991 err("Invalid message");
2992 tcore_at_tok_free(tokens);
2996 lock_type = atoi(g_slist_nth_data(tokens, 0));
2997 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2998 time_penalty = atoi(g_slist_nth_data(tokens, 2));
3000 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
3001 lock_type, attempts_left, time_penalty);
3003 get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
3004 get_lock_info_resp.retry_count = attempts_left;
3005 result = TEL_SIM_RESULT_SUCCESS;
3007 tcore_at_tok_free(tokens);
3009 err("Sim Get Lock Info Response- [NOK]");
3012 /* Invoke callback */
3013 if(resp_cb_data->cb)
3014 resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
3015 imc_destroy_resp_cb_data(resp_cb_data);
3018 static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
3020 const TcoreAtResponse *resp = data;
3021 CoreObject *co = NULL;
3022 TelSimApduResp apdu_resp = {0,};
3023 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3024 GSList *tokens = NULL;
3026 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3030 co = tcore_pending_ref_core_object(p);
3032 if (resp->success > 0) {
3036 char *decoded_data = NULL;
3037 guint decoded_data_len = 0;
3038 line = (const char *)resp->lines->data;
3039 tokens = tcore_at_tok_new(line);
3040 if (g_slist_length(tokens) != 2) {
3041 err("Invalid message");
3045 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3046 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3048 apdu_resp.apdu_resp_len = decoded_data_len;
3049 memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
3051 g_free(decoded_data);
3052 sim_result = TEL_SIM_RESULT_SUCCESS;
3055 err("RESPONSE NOK");
3060 if (resp_cb_data->cb)
3061 resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
3062 tcore_at_tok_free(tokens);
3066 static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
3068 const TcoreAtResponse *resp = data;
3069 CoreObject *co = NULL;
3070 TelSimAtr atr_res = {0,};
3071 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3072 GSList *tokens = NULL;
3074 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3078 co = tcore_pending_ref_core_object(p);
3080 if (resp->success > 0) {
3084 char *decoded_data = NULL;
3085 guint decoded_data_len = 0;
3086 line = (const char *)resp->lines->data;
3087 tokens = tcore_at_tok_new(line);
3088 if (g_slist_length(tokens) < 1) {
3089 err("Invalid message");
3093 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3094 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3096 atr_res.atr_len = decoded_data_len;
3097 memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
3099 g_free(decoded_data);
3100 sim_result = TEL_SIM_RESULT_SUCCESS;
3103 err("RESPONSE NOK");
3108 if (resp_cb_data->cb)
3109 resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
3110 tcore_at_tok_free(tokens);
3114 /* SIM Operations */
3116 * Operation - get_imsi
3119 * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3130 * 28423 meaning IMSI file (6F07)
3131 * 28473 meaning ACM file (6F39)
3132 * 28481 meaning PUKT file (6F41)
3133 * 28482 meaning SMS file (6F42)
3136 * Integer type defining the request.
3137 * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
3140 * Information which shall be written to the SIM
3143 * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
3151 * +CRSM: <sw1>,<sw2>[,<response>]
3154 * Integer type containing the SIM information
3157 * Response of successful completion of the command previously issued
3160 * +CME ERROR: <error>
3162 static TelReturn imc_sim_get_imsi (CoreObject *co,
3163 TcoreObjectResponseCallback cb, void *cb_data)
3168 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
3173 static TelReturn imc_sim_get_ecc (CoreObject *co,
3174 TcoreObjectResponseCallback cb, void *cb_data)
3179 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
3184 static TelReturn imc_sim_get_iccid (CoreObject *co,
3185 TcoreObjectResponseCallback cb, void *cb_data)
3190 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
3195 static TelReturn imc_sim_get_language (CoreObject *co,
3196 TcoreObjectResponseCallback cb, void *cb_data)
3201 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_LP, ret);
3206 static TelReturn imc_sim_set_language (CoreObject *co,
3207 TelSimLanguagePreferenceCode language,
3208 TcoreObjectResponseCallback cb, void *cb_data)
3210 ImcSimMetaInfo file_meta = {0, };
3211 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3212 ImcRespCbData *resp_cb_data = NULL;
3215 char *encoded_data = NULL;
3216 int encoded_data_len = 0;
3223 file_meta.file_id = TEL_SIM_EF_LP;
3224 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3226 tcore_sim_get_type(co, &card_type);
3228 dbg("language[%d], card_type[%d]", language, card_type);
3230 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
3233 tcore_sim_encode_lp(language, &encoded_data, &encoded_data_len);
3234 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
3238 if (tcore_sim_encode_li(language, &tmp, &encoded_data_len)) {
3239 encoded_data = g_strdup_printf("%02x%02x", tmp[0], tmp[1]);
3243 err("Failed to encode Language [%d]", language);
3244 return TEL_RETURN_FAILURE;
3247 err("Invalid card_type:[%d]", card_type);
3248 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
3251 if (!encoded_data_len) {
3252 err("Failed to encode Language [%d]", language);
3253 return TEL_RETURN_FAILURE;
3255 dbg("Encoded Language [%s] len[%d]", encoded_data, encoded_data_len);
3259 p3 = encoded_data_len;
3261 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3262 &file_meta, sizeof(ImcSimMetaInfo));
3264 return __imc_sim_update_file(co, resp_cb_data,
3265 IMC_SIM_ACCESS_UPDATE_BINARY, TEL_SIM_EF_LP,
3266 p1, p2, p3, encoded_data);
3269 static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
3270 TcoreObjectResponseCallback cb, void *cb_data)
3275 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
3280 static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
3281 TcoreObjectResponseCallback cb, void *cb_data)
3286 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
3291 static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
3292 const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
3294 ImcSimMetaInfo file_meta = {0, };
3295 ImcRespCbData *resp_cb_data = NULL;
3296 gchar *encoded_mwis;
3297 guint encoded_mwis_len = 0;
3298 gchar *encoded_data = NULL;
3299 guint encoded_data_len = 0;
3307 * Videomail is not supported.
3309 if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
3310 &encoded_mwis, &encoded_mwis_len)) {
3311 err("Failed to encode mwis");
3312 return TEL_RETURN_FAILURE;
3315 encoded_data_len = 2 * encoded_mwis_len;
3316 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3317 tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
3318 tcore_free(encoded_mwis);
3319 dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
3323 p3 = TEL_SIM_MAILBOX_TYPE_MAX; /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
3324 dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
3326 file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
3327 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3329 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3331 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3332 TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
3335 static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
3336 TcoreObjectResponseCallback cb, void *cb_data)
3341 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
3346 static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
3347 const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
3349 ImcSimMetaInfo file_meta = {0, };
3350 ImcRespCbData *resp_cb_data = NULL;
3353 char *encoded_data = NULL;
3354 int encoded_data_len = 0;
3361 file_meta.file_id = TEL_SIM_EF_USIM_MBI;
3362 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3364 /* TBD - Do Encoding.
3365 if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
3366 err("Failed to encode mwis");
3367 return TEL_RETURN_FAILURE;
3370 encoded_data_len = tmp_len * 2;
3371 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3372 tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3373 if (!encoded_data) {
3374 err("Failed to convert byte to hex");
3375 tcore_free(encoded_data);
3376 return TEL_RETURN_FAILURE;
3381 p3 = encoded_data_len;
3382 dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3384 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3386 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3387 TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
3390 static TelReturn imc_sim_get_msisdn (CoreObject *co,
3391 TcoreObjectResponseCallback cb, void *cb_data)
3396 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
3401 static TelReturn imc_sim_get_spn (CoreObject *co,
3402 TcoreObjectResponseCallback cb, void *cb_data)
3407 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
3412 static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
3413 TcoreObjectResponseCallback cb, void *cb_data)
3418 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
3423 static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
3424 TcoreObjectResponseCallback cb, void *cb_data)
3429 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
3434 static TelReturn imc_sim_req_authentication (CoreObject *co,
3435 const TelSimAuthenticationData *request,
3436 TcoreObjectResponseCallback cb, void *cb_data)
3438 gchar *cmd_str = NULL;
3439 ImcRespCbData *resp_cb_data = NULL;
3440 TelReturn ret = TEL_RETURN_FAILURE;
3441 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3442 char *convert_rand = NULL;
3443 char *convert_autn = NULL;
3449 tcore_sim_get_type(co, &card_type);
3450 if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
3453 err("Not Supported SIM type:[%d]", card_type);
3454 return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3457 if (request->rand_data != NULL) {
3458 convert_rand = tcore_malloc0(request->rand_length*2 + 1);
3459 tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
3460 dbg("Convert RAND hex to string: [%s]", convert_rand);
3462 err("rand_data is NULL");
3466 switch (request->auth_type) {
3467 case TEL_SIM_AUTH_GSM:
3469 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
3470 session_id, context_type, convert_rand);
3472 case TEL_SIM_AUTH_3G_CTX:
3474 if (request->autn_data != NULL) {
3475 convert_autn = tcore_malloc0(request->autn_length*2 + 1);
3476 tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
3477 dbg("Convert AUTN hex to string: [%s]", convert_autn);
3479 err("autn_data is NULL");
3482 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3483 session_id, context_type, convert_rand, convert_autn);
3486 err("Not supported Authentication type:[%d]", request->auth_type);
3487 ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3491 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
3493 ret = tcore_at_prepare_and_send_request(co,
3495 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3497 on_response_imc_sim_req_authentication, resp_cb_data,
3498 on_send_imc_request, NULL);
3499 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
3503 tcore_free(convert_rand);
3504 tcore_free(convert_autn);
3510 * Operation - verify_pins/verify_puks
3514 * AT-Command: AT+CPIN= <pin> [, <newpin>]
3517 * String type values
3520 * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
3522 * <puk2/pin2>, <newpin2>
3523 * String type values
3529 * +CME ERROR: <error>
3531 static TelReturn imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
3532 TcoreObjectResponseCallback cb, void *cb_data)
3534 TelReturn ret = TEL_RETURN_FAILURE;
3535 ImcRespCbData *resp_cb_data = NULL;
3536 ImcSimCurrSecOp sec_op;
3537 gchar *cmd_str = NULL;
3541 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3542 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
3543 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
3544 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3545 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
3546 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
3548 err("Invalid pin type [%d]", request->pin_type);
3549 return TEL_RETURN_INVALID_PARAMETER;
3552 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3553 &sec_op, sizeof(sec_op));
3555 ret = tcore_at_prepare_and_send_request(co,
3557 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3559 on_response_imc_sim_verify_pins, resp_cb_data,
3560 on_send_imc_request, NULL);
3561 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
3567 static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
3568 TcoreObjectResponseCallback cb, void *cb_data)
3570 TelReturn ret = TEL_RETURN_FAILURE;
3571 ImcRespCbData *resp_cb_data = NULL;
3572 ImcSimCurrSecOp sec_op;
3573 gchar *cmd_str = NULL;
3577 if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
3578 sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
3579 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
3580 request->puk_pw, request->new_pin_pw);
3581 } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
3582 sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
3583 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
3584 request->puk_pw, request->new_pin_pw);
3586 err("Invalid puk type [%d]", request->puk_type);
3587 return TEL_RETURN_INVALID_PARAMETER;
3590 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3591 &sec_op, sizeof(sec_op));
3593 ret = tcore_at_prepare_and_send_request(co,
3595 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3597 on_response_imc_sim_verify_puks, resp_cb_data,
3598 on_send_imc_request, NULL);
3599 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
3606 * Operation - change_pins
3609 * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
3624 * +CME ERROR: <error>
3626 static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
3627 TcoreObjectResponseCallback cb, void *cb_data)
3629 TelReturn ret = TEL_RETURN_FAILURE;
3630 ImcRespCbData *resp_cb_data = NULL;
3631 ImcSimCurrSecOp sec_op;
3632 gchar *cmd_str = NULL;
3633 char *pin1_fac = "SC";
3634 char *pin2_fac = "P2";
3638 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3639 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
3640 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3641 pin1_fac, request->old_pw, request->new_pw);
3642 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3643 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
3644 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3645 pin2_fac, request->old_pw, request->new_pw);
3647 err("Invalid pin type [%d]", request->pin_type);
3648 return TEL_RETURN_INVALID_PARAMETER;
3651 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3652 &sec_op, sizeof(sec_op));
3654 ret = tcore_at_prepare_and_send_request(co,
3656 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3658 on_response_imc_sim_change_pins, resp_cb_data,
3659 on_send_imc_request, NULL);
3660 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
3667 * Operation - disable_facility/enable_facility/get_facility
3670 * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
3687 * Success: when <mode>=2:
3689 * +CLCK: <status>[,<class1> [<CR><LF>
3690 * +CLCK: <status>,<class2> [...]]
3694 static TelReturn imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
3695 TcoreObjectResponseCallback cb, void *cb_data)
3697 TelReturn ret = TEL_RETURN_FAILURE;
3698 ImcRespCbData *resp_cb_data = NULL;
3699 ImcSimCurrSecOp sec_op;
3700 gchar *cmd_str = NULL;
3702 int mode = 0; /*mode = 0 for disable lock*/
3706 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3707 &sec_op, DISABLE_FLAG);
3709 return TEL_RETURN_INVALID_PARAMETER;
3711 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3712 fac, mode, request->pw);
3714 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3715 &sec_op, sizeof(sec_op));
3717 ret = tcore_at_prepare_and_send_request(co,
3719 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3721 on_response_imc_sim_disable_facility, resp_cb_data,
3722 on_send_imc_request, NULL);
3723 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3729 static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
3730 TcoreObjectResponseCallback cb, void *cb_data)
3732 TelReturn ret = TEL_RETURN_FAILURE;
3733 ImcRespCbData *resp_cb_data = NULL;
3734 ImcSimCurrSecOp sec_op;
3735 gchar *cmd_str = NULL;
3737 int mode = 1; /*mode = 1 for enable lock*/
3741 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3742 &sec_op, ENABLE_FLAG);
3744 return TEL_RETURN_INVALID_PARAMETER;
3746 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3747 fac, mode, request->pw);
3749 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3750 &sec_op, sizeof(sec_op));
3752 ret = tcore_at_prepare_and_send_request(co,
3754 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3756 on_response_imc_sim_enable_facility, resp_cb_data,
3757 on_send_imc_request, NULL);
3758 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3764 static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
3765 TcoreObjectResponseCallback cb, void *cb_data)
3767 TelReturn ret = TEL_RETURN_FAILURE;
3768 ImcRespCbData *resp_cb_data = NULL;
3769 ImcSimCurrSecOp sec_op;
3770 gchar *cmd_str = NULL;
3772 int mode = 2; /*mode = 2 for Get Facility*/
3776 fac = __imc_sim_get_fac_from_lock_type(lock_type,
3779 return TEL_RETURN_INVALID_PARAMETER;
3781 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3783 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3784 &sec_op, sizeof(sec_op));
3786 ret = tcore_at_prepare_and_send_request(co,
3788 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3790 on_response_imc_sim_get_facility, resp_cb_data,
3791 on_send_imc_request, NULL);
3792 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
3798 static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
3799 TcoreObjectResponseCallback cb, void *cb_data)
3801 TelReturn ret = TEL_RETURN_FAILURE;
3802 ImcRespCbData *resp_cb_data = NULL;
3803 gchar *cmd_str = NULL;
3808 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3810 switch (lock_type) {
3811 case TEL_SIM_LOCK_PS:
3815 case TEL_SIM_LOCK_SC:
3819 case TEL_SIM_LOCK_FD:
3823 case TEL_SIM_LOCK_PN:
3827 case TEL_SIM_LOCK_PU:
3831 case TEL_SIM_LOCK_PP:
3835 case TEL_SIM_LOCK_PC:
3843 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
3845 ret = tcore_at_prepare_and_send_request(co,
3846 cmd_str, "+XPINCNT:",
3847 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3849 on_response_imc_sim_get_lock_info, resp_cb_data,
3850 on_send_imc_request, NULL);
3851 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
3857 static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
3859 gchar *cmd_str = NULL;
3861 ImcRespCbData *resp_cb_data = NULL;
3862 TelReturn ret = TEL_RETURN_FAILURE;
3866 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3868 apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
3869 tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
3871 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
3873 ret = tcore_at_prepare_and_send_request(co,
3875 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3877 on_response_imc_sim_req_apdu, resp_cb_data,
3878 on_send_imc_request, NULL);
3879 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
3888 static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
3890 gchar *cmd_str = NULL;
3891 ImcRespCbData *resp_cb_data = NULL;
3892 TelReturn ret = TEL_RETURN_FAILURE;
3896 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3898 cmd_str = g_strdup_printf("AT+XGATR");
3900 ret = tcore_at_prepare_and_send_request(co,
3902 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3904 on_response_imc_sim_req_atr, resp_cb_data,
3905 on_send_imc_request, NULL);
3906 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
3914 /* SIM Operations */
3915 static TcoreSimOps imc_sim_ops = {
3916 .get_imsi = imc_sim_get_imsi,
3917 .get_ecc = imc_sim_get_ecc,
3918 .get_iccid = imc_sim_get_iccid,
3919 .get_language = imc_sim_get_language,
3920 .set_language = imc_sim_set_language,
3921 .get_callforwarding_info = imc_sim_get_callforwarding_info,
3922 .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
3923 .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
3924 .get_mailbox_info = imc_sim_get_mailbox_info,
3925 .set_mailbox_info = imc_sim_set_mailbox_info,
3926 .get_msisdn = imc_sim_get_msisdn,
3927 .get_spn = imc_sim_get_spn,
3928 .get_cphs_netname = imc_sim_get_cphs_netname,
3929 .get_sp_display_info = imc_sim_get_sp_display_info,
3930 .req_authentication = imc_sim_req_authentication,
3931 .verify_pins = imc_sim_verify_pins,
3932 .verify_puks = imc_sim_verify_puks,
3933 .change_pins = imc_sim_change_pins,
3934 .disable_facility = imc_sim_disable_facility,
3935 .enable_facility = imc_sim_enable_facility,
3936 .get_facility = imc_sim_get_facility,
3937 .get_lock_info = imc_sim_get_lock_info,
3938 .req_apdu = imc_sim_req_apdu,
3939 .req_atr = imc_sim_req_atr
3942 gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
3944 ImcSimPrivateInfo *priv_info = NULL;
3948 priv_info = g_try_new0(ImcSimPrivateInfo, 1);
3949 if (priv_info == NULL)
3952 tcore_sim_link_userdata(co, priv_info);
3954 /* Set operations */
3955 tcore_sim_set_ops(co, &imc_sim_ops);
3958 tcore_object_add_callback(co, "+XSIM:",
3959 on_notification_imc_sim_status, NULL);
3962 tcore_plugin_add_notification_hook(p,
3963 TCORE_NOTIFICATION_MODEM_POWER,
3964 on_hook_imc_modem_power, co);
3970 void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
3972 ImcSimPrivateInfo *priv_info = NULL;
3976 priv_info = tcore_sim_ref_userdata(co);