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 case TEL_SIM_EF_USIM_LI:
930 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
931 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
932 __imc_sim_read_binary(co, resp_cb_data);
934 tcore_sim_get_type(co, &card_type);
935 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
936 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
937 if (resp_cb_data->cb)
938 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
941 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
942 else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
943 ImcSimMetaInfo file_meta_new = {0,};
945 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
946 file_meta_new.file_id = TEL_SIM_EF_ELP;
947 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
948 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
950 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
952 __imc_sim_get_response(co, resp_cb_data);
957 case TEL_SIM_EF_USIM_PL:
958 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
959 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
960 __imc_sim_read_binary(co, resp_cb_data);
962 /* EFELIand EFPL not present, so set language count as zero and select ECC */
964 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
965 if (resp_cb_data->cb)
966 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
972 tcore_sim_get_type(co, &card_type);
973 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
974 __imc_sim_read_binary(co, resp_cb_data);
975 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
976 if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) {
977 file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
979 file_meta->current_index++;
980 __imc_sim_read_record(co, resp_cb_data);
984 case TEL_SIM_EF_ICCID:
985 case TEL_SIM_EF_IMSI:
988 case TEL_SIM_EF_SPDI:
989 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
990 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
991 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
992 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
993 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
994 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
995 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
996 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
997 __imc_sim_read_binary(co, resp_cb_data);
1000 case TEL_SIM_EF_CPHS_CPHS_INFO:
1001 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1002 tcore_sim_set_cphs_status(co, TRUE);
1003 __imc_sim_read_binary(co, resp_cb_data);
1005 tcore_sim_set_cphs_status(co, FALSE);
1006 if (resp_cb_data->cb)
1007 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1012 case TEL_SIM_EF_USIM_CFIS:
1013 if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) {
1014 file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
1016 file_meta->current_index++;
1017 __imc_sim_read_record(co, resp_cb_data);
1020 case TEL_SIM_EF_MSISDN:
1021 file_meta->files.data.msisdn_list.list =
1022 tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
1024 case TEL_SIM_EF_OPL:
1025 case TEL_SIM_EF_PNN:
1026 case TEL_SIM_EF_USIM_MWIS:
1027 case TEL_SIM_EF_USIM_MBI:
1028 case TEL_SIM_EF_MBDN:
1029 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
1030 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1031 file_meta->current_index++;
1032 __imc_sim_read_record(co, resp_cb_data);
1035 case TEL_SIM_EF_SMSP:
1037 ImcSimPrivateInfo *priv_info = NULL;
1039 priv_info = tcore_sim_ref_userdata(co);
1041 dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",file_meta->rec_count, file_meta->rec_length);
1042 priv_info->smsp_count = file_meta->rec_count;
1043 priv_info->smsp_rec_len = file_meta->rec_length;
1048 dbg("error - File id for get file info [0x%x]", file_meta->file_id);
1054 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data)
1056 const TcoreAtResponse *resp = data;
1057 CoreObject *co_sim = NULL;
1058 GSList *tokens = NULL;
1059 TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
1061 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1062 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1066 co_sim = tcore_pending_ref_core_object(p);
1068 dbg("file_id:[0x%x]", file_meta->file_id);
1070 if (resp->success > 0) {
1075 line = (const char *)resp->lines->data;
1076 tokens = tcore_at_tok_new(line);
1077 if (g_slist_length(tokens) != 2) {
1078 err("Invalid message");
1081 sw1 = atoi(g_slist_nth_data(tokens, 0));
1082 sw2 = atoi(g_slist_nth_data(tokens, 1));
1085 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1086 sim_result = TEL_SIM_RESULT_SUCCESS;
1088 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1091 err("RESPONSE NOK");
1092 sim_result = TEL_SIM_RESULT_FAILURE;
1096 if (resp_cb_data->cb)
1097 resp_cb_data->cb(co_sim, (gint)sim_result, NULL, resp_cb_data->cb_data);
1099 tcore_at_tok_free(tokens);
1103 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len,
1104 const void *data, void *user_data)
1106 const TcoreAtResponse *resp = data;
1107 CoreObject *co = NULL;
1108 GSList *tokens = NULL;
1109 TelSimResult sim_result;
1110 gboolean dr = FALSE;
1111 const char *line = NULL;
1117 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1118 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1119 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1123 co = tcore_pending_ref_core_object(p);
1125 if (resp->success > 0) {
1128 line = (const char *)resp->lines->data;
1129 tokens = tcore_at_tok_new(line);
1130 if (g_slist_length(tokens) != 3) {
1131 err("Invalid message");
1132 tcore_at_tok_free(tokens);
1136 sw1 = atoi(g_slist_nth_data(tokens, 0));
1137 sw2 = atoi(g_slist_nth_data(tokens, 1));
1138 res = g_slist_nth_data(tokens, 2);
1140 tmp = tcore_at_tok_extract(res);
1141 tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
1142 dbg("Response: [%s] Response length: [%d]", res, res_len);
1144 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1145 sim_result = TEL_SIM_RESULT_SUCCESS;
1146 file_meta->files.result = sim_result;
1148 dbg("File ID: [0x%x]", file_meta->file_id);
1149 switch (file_meta->file_id) {
1150 case TEL_SIM_EF_IMSI: {
1151 dbg("Data: [%s]", res);
1152 dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
1154 err("IMSI decoding failed");
1156 __imc_sim_set_identity(co, &file_meta->imsi);
1159 tcore_sim_set_imsi(co, &file_meta->imsi);
1164 case TEL_SIM_EF_ICCID: {
1165 dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
1166 file_meta->files.data.iccid);
1170 case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1171 case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1172 case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1173 case TEL_SIM_EF_LP: /* 1 byte encoding */
1175 tcore_sim_get_type(co, &card_type);
1176 if ((TEL_SIM_CARD_TYPE_GSM == card_type)
1177 && (file_meta->file_id == TEL_SIM_EF_LP)) {
1179 * 2G LP(0x6F05) has 1 byte for each language
1181 dr = tcore_sim_decode_lp((unsigned char *)res, res_len, &file_meta->files.data.language);
1184 * 3G LI(0x6F05)/PL(0x2F05),
1185 * 2G ELP(0x2F05) has 2 bytes for each language
1187 dr = tcore_sim_decode_li((unsigned char *)res, res_len,
1188 file_meta->file_id, &file_meta->files.data.language);
1193 case TEL_SIM_EF_SPN:
1194 dr = tcore_sim_decode_spn((unsigned char *)res, res_len, &file_meta->files.data.spn);
1197 case TEL_SIM_EF_SPDI:
1198 dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, &file_meta->files.data.spdi);
1201 case TEL_SIM_EF_SST:
1203 TelSimServiceTable *svct = NULL;
1205 svct = g_try_new0(TelSimServiceTable, 1);
1206 tcore_sim_get_type(co, &card_type);
1207 svct->sim_type = card_type;
1208 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1209 dr = tcore_sim_decode_sst((unsigned char *)res, res_len, svct->table.sst_service);
1210 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1211 dr = tcore_sim_decode_ust((unsigned char *)res, res_len, svct->table.ust_service);
1213 err("Not handled card_type[%d]", card_type);
1217 err("SST/UST decoding failed");
1219 tcore_sim_set_service_table(co, svct);
1227 case TEL_SIM_EF_ECC:
1229 tcore_sim_get_type(co, &card_type);
1230 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1231 dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, &file_meta->files.data.ecc);
1232 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1233 TelSimEcc *ecc = NULL;
1235 ecc = g_try_new0(TelSimEcc, 1);
1236 dbg("Index [%d]", file_meta->current_index);
1238 dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
1240 memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], ecc, sizeof(TelSimEcc));
1241 file_meta->files.data.ecc.count++;
1247 dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
1252 case TEL_SIM_EF_MSISDN:
1254 TelSimSubscriberInfo *msisdn = NULL;
1256 dbg("Index [%d]", file_meta->current_index);
1257 msisdn = tcore_malloc0(sizeof(TelSimSubscriberInfo));
1258 dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
1260 memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
1261 msisdn, sizeof(TelSimSubscriberInfo));
1263 file_meta->files.data.msisdn_list.count++;
1267 dbg("Freeing resources");
1272 case TEL_SIM_EF_OPL:
1274 TelSimOpl *opl = NULL;
1276 dbg("decode w/ index [%d]", file_meta->current_index);
1277 opl = g_try_new0(TelSimOpl, 1);
1279 dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
1281 memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
1282 opl, sizeof(TelSimOpl));
1284 file_meta->files.data.opl.opl_count++;
1292 case TEL_SIM_EF_PNN:
1294 TelSimPnn *pnn = NULL;
1296 dbg("decode w/ index [%d]", file_meta->current_index);
1297 pnn = g_try_new0(TelSimPnn, 1);
1299 dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
1301 memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
1302 pnn, sizeof(TelSimPnn));
1304 file_meta->files.data.pnn.pnn_count++;
1312 case TEL_SIM_EF_OPLMN_ACT:
1313 /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1314 (unsigned char *)res, res_len);*/
1317 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1318 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1319 p_data->response, p_data->response_len);*/
1322 case TEL_SIM_EF_USIM_MBI: /* linear type */
1324 TelSimMbi *mbi = NULL;
1326 mbi = g_try_new0(TelSimMbi, 1);
1327 dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
1329 memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
1330 mbi, sizeof(TelSimMbi));
1331 file_meta->mbi_list.count++;
1333 dbg("mbi count[%d]", file_meta->mbi_list.count);
1341 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1342 case TEL_SIM_EF_MBDN: /* linear type */
1343 dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
1344 file_meta->mb_list[file_meta->current_index-1].alpha_id,
1345 file_meta->mb_list[file_meta->current_index-1].number);
1346 file_meta->mb_list[file_meta->current_index-1].alpha_id_len = strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
1347 file_meta->mb_list[file_meta->current_index-1].profile_id = file_meta->current_index;
1350 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1351 dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1354 case TEL_SIM_EF_USIM_MWIS: { /* linear type */
1355 TelSimMwis *mw = NULL;
1357 mw = g_try_new0(TelSimMwis, 1);
1359 dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
1361 guint count = file_meta->files.data.mw.profile_count;
1363 memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
1366 * The Profile Identity shall be between 1 and 4 as defined
1367 * in TS 23.097 for MSP
1369 file_meta->files.data.mw.mw[count].profile_id = count+1;
1371 file_meta->files.data.mw.profile_count++;
1379 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
1380 dr = tcore_sim_decode_cff((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1383 case TEL_SIM_EF_USIM_CFIS: /* linear type */
1385 TelSimCfis *cf = NULL;
1387 cf = g_try_new0(TelSimCfis, 1);
1388 dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
1390 memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
1391 cf, sizeof(TelSimCfis));
1392 file_meta->files.data.cf.profile_count++;
1400 case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
1401 dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1404 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1405 file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1406 dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
1407 (unsigned char*)file_meta->files.data.cphs_net.full_name);
1408 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1409 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1412 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1413 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1414 p_data->response, p_data->response_len);*/
1417 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1418 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1419 p_data->response_len);*/
1422 case TEL_SIM_EF_CPHS_CPHS_INFO:
1423 /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1424 (unsigned char *)res, res_len);*/
1427 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1428 file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
1429 dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
1430 (unsigned char*)file_meta->files.data.cphs_net.short_name);
1431 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
1432 file_meta->files.result, file_meta->files.data.cphs_net.short_name);
1435 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1436 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1440 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1445 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1446 file_meta->files.result = sim_result;
1454 tcore_at_tok_free(tokens);
1456 err("RESPONSE NOK");
1457 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1458 sim_result = TEL_SIM_RESULT_FAILURE;
1462 __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
1467 static void __on_response_imc_sim_get_response(TcorePending *p,
1468 guint data_len, const void *data, void *user_data)
1470 const TcoreAtResponse *resp = data;
1471 CoreObject *co = NULL;
1472 TelSimResult sim_result;
1473 GSList *tokens = NULL;
1474 const char *line = NULL;
1477 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
1478 ImcSimMetaInfo *file_meta =
1479 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1481 dbg("SIM Response - SIM File info: [+CRSM]");
1483 co = tcore_pending_ref_core_object(p);
1485 if (resp->success > 0) {
1488 line = (const char *)resp->lines->data;
1489 tokens = tcore_at_tok_new(line);
1490 if (g_slist_length(tokens) < 2) {
1491 err("Invalid message");
1492 tcore_at_tok_free(tokens);
1496 sw1 = atoi(g_slist_nth_data(tokens, 0));
1497 sw2 = atoi(g_slist_nth_data(tokens, 1));
1499 /*1. SIM access success case*/
1500 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1501 unsigned char tag_len = 0;
1502 unsigned short record_len = 0;
1503 char num_of_records = 0;
1504 unsigned char file_id_len = 0;
1505 unsigned short file_id = 0;
1506 unsigned short file_size = 0;
1507 unsigned short file_type = 0;
1508 unsigned short arr_file_id = 0;
1509 int arr_file_id_rec_num = 0;
1510 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1512 /* handling only last 3 bits */
1513 unsigned char file_type_tag = 0x07;
1514 unsigned char *ptr_data;
1518 char *record_data = NULL;
1519 guint record_data_len;
1520 hexData = g_slist_nth_data(tokens, 2);
1521 dbg("hexData: %s", hexData);
1522 dbg("hexData: %s", hexData + 1);
1524 tmp = tcore_at_tok_extract(hexData);
1525 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
1526 tcore_util_hex_dump(" ", record_data_len, record_data);
1529 ptr_data = (unsigned char *)record_data;
1530 tcore_sim_get_type(co, &card_type);
1531 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1533 ETSI TS 102 221 v7.9.0
1535 '62' FCP template tag
1536 - Response for an EF
1537 '82' M File Descriptor
1538 '83' M File Identifier
1539 'A5' O Proprietary information
1540 '8A' M Life Cycle Status Integer
1541 '8B', '8C' or 'AB' C1 Security attributes
1543 '81' O Total file size
1544 '88' O Short File Identifier (SFI)
1547 /* rsim.res_len has complete data length received */
1549 /* FCP template tag - File Control Parameters tag*/
1550 if (*ptr_data == 0x62) {
1551 /* parse complete FCP tag*/
1552 /* increment to next byte */
1554 tag_len = *ptr_data++;
1555 dbg("tag_len: %02x", tag_len);
1556 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1557 if (*ptr_data == 0x82) {
1558 /* increment to next byte */
1562 /* consider only last 3 bits*/
1563 dbg("file_type_tag: %02x", file_type_tag);
1564 file_type_tag = file_type_tag & (*ptr_data);
1565 dbg("file_type_tag: %02x", file_type_tag);
1567 switch (file_type_tag) {
1568 /* increment to next byte */
1571 dbg("Getting FileType: [Transparent file type]");
1572 file_type = IMC_SIM_FILE_TYPE_TRANSPARENT;
1574 /* increment to next byte */
1576 /* increment to next byte */
1581 dbg("Getting FileType: [Linear fixed file type]");
1582 /* increment to next byte */
1584 /* data coding byte - value 21 */
1587 memcpy(&record_len, ptr_data, 2);
1589 IMC_SWAP_BYTES_16(record_len);
1590 ptr_data = ptr_data + 2;
1591 num_of_records = *ptr_data++;
1592 /* Data lossy conversation from enum (int) to unsigned char */
1593 file_type = IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1597 dbg("Cyclic fixed file type");
1598 /* increment to next byte */
1600 /* data coding byte - value 21 */
1603 memcpy(&record_len, ptr_data, 2);
1605 IMC_SWAP_BYTES_16(record_len);
1606 ptr_data = ptr_data + 2;
1607 num_of_records = *ptr_data++;
1608 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1612 dbg("not handled file type [0x%x]", *ptr_data);
1616 dbg("INVALID FCP received - DEbug!");
1617 tcore_at_tok_free(tokens);
1618 g_free(record_data);
1622 /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
1623 if (*ptr_data == 0x83) {
1624 /* increment to next byte */
1626 file_id_len = *ptr_data++;
1627 dbg("file_id_len: %02x", file_id_len);
1629 memcpy(&file_id, ptr_data, file_id_len);
1630 dbg("file_id: %x", file_id);
1633 IMC_SWAP_BYTES_16(file_id);
1634 dbg("file_id: %x", file_id);
1636 ptr_data = ptr_data + 2;
1637 dbg("Getting FileID=[0x%x]", file_id);
1639 dbg("INVALID FCP received - DEbug!");
1640 tcore_at_tok_free(tokens);
1641 g_free(record_data);
1645 /* proprietary information */
1646 if (*ptr_data == 0xA5) {
1647 unsigned short prop_len;
1648 /* increment to next byte */
1652 prop_len = *ptr_data;
1653 dbg("prop_len: %02x", prop_len);
1656 ptr_data = ptr_data + prop_len + 1;
1658 dbg("INVALID FCP received - DEbug!");
1661 /* life cycle status integer [8A][length:0x01][status]*/
1664 00000000 : No information given
1665 00000001 : creation state
1666 00000011 : initialization state
1667 000001-1 : operation state -activated
1668 000001-0 : operation state -deactivated
1669 000011-- : Termination state
1670 b8~b5 !=0, b4~b1=X : Proprietary
1671 Any other value : RFU
1673 if (*ptr_data == 0x8A) {
1674 /* increment to next byte */
1676 /* length - value 1 */
1679 switch (*ptr_data) {
1682 dbg("<RX> operation state -deactivated");
1688 dbg("<RX> operation state -activated");
1693 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1699 /* related to security attributes : currently not handled*/
1700 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1701 /* increment to next byte */
1703 /* if tag length is 3 */
1704 if (*ptr_data == 0x03) {
1705 /* increment to next byte */
1708 memcpy(&arr_file_id, ptr_data, 2);
1710 IMC_SWAP_BYTES_16(arr_file_id);
1711 ptr_data = ptr_data + 2;
1712 arr_file_id_rec_num = *ptr_data++;
1713 dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
1715 /* if tag length is not 3 */
1716 /* ignoring bytes */
1717 // ptr_data = ptr_data + 4;
1718 dbg("Useless security attributes, so jump to next tag");
1719 ptr_data = ptr_data + (*ptr_data + 1);
1722 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1723 tcore_at_tok_free(tokens);
1724 g_free(record_data);
1728 dbg("Current ptr_data value is [%x]", *ptr_data);
1730 /* file size excluding structural info*/
1731 if (*ptr_data == 0x80) {
1732 /* for EF file size is body of file and for Linear or cyclic it is
1733 * number of recXsizeof(one record)
1735 /* increment to next byte */
1737 /* length is 1 byte - value is 2 bytes or more */
1739 memcpy(&file_size, ptr_data, 2);
1741 IMC_SWAP_BYTES_16(file_size);
1742 ptr_data = ptr_data + 2;
1744 dbg("INVALID FCP received - DEbug!");
1745 tcore_at_tok_free(tokens);
1746 g_free(record_data);
1750 /* total file size including structural info*/
1751 if (*ptr_data == 0x81) {
1753 /* increment to next byte */
1757 dbg("len:[%d]", len);
1759 ptr_data = ptr_data + 3;
1761 dbg("INVALID FCP received - DEbug!");
1762 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1764 /*short file identifier ignored*/
1765 if (*ptr_data == 0x88) {
1766 dbg("0x88: Do Nothing");
1770 dbg("INVALID FCP received - DEbug!");
1771 tcore_at_tok_free(tokens);
1772 g_free(record_data);
1775 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1776 unsigned char gsm_specific_file_data_len = 0;
1777 /* ignore RFU byte1 and byte2 */
1781 // file_size = p_info->response_len;
1782 memcpy(&file_size, ptr_data, 2);
1784 IMC_SWAP_BYTES_16(file_size);
1785 /* parsed file size */
1786 ptr_data = ptr_data + 2;
1788 memcpy(&file_id, ptr_data, 2);
1789 IMC_SWAP_BYTES_16(file_id);
1790 dbg("FILE id --> [%x]", file_id);
1791 ptr_data = ptr_data + 2;
1792 /* save file type - transparent, linear fixed or cyclic */
1793 file_type_tag = (*(ptr_data + 7));
1795 switch (*ptr_data) {
1798 dbg("RFU file type- not handled - Debug!");
1803 dbg("MF file type - not handled - Debug!");
1808 dbg("DF file type - not handled - Debug!");
1813 dbg("EF file type [%d] ", file_type_tag);
1814 /* increment to next byte */
1817 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1818 /* increament to next byte as this byte is RFU */
1821 (file_type_tag == 0x00) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1823 /* increment to next byte */
1825 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1826 /* the INCREASE command is allowed on the selected cyclic file. */
1827 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1829 /* bytes 9 to 11 give SIM file access conditions */
1831 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1833 /* byte 11 is invalidate and rehabilate nibbles */
1835 /* byte 12 - file status */
1837 /* byte 13 - GSM specific data */
1838 gsm_specific_file_data_len = *ptr_data;
1839 dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
1841 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1843 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1844 record_len = *ptr_data;
1845 dbg("record length[%d], file size[%d]", record_len, file_size);
1846 if (record_len != 0)
1847 num_of_records = (file_size / record_len);
1849 dbg("Number of records [%d]", num_of_records);
1853 dbg("not handled file type");
1857 err("Unknown Card Type - [%d]", card_type);
1860 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1861 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1863 file_meta->file_type = file_type;
1864 file_meta->data_size = file_size;
1865 file_meta->rec_length = record_len;
1866 file_meta->rec_count = num_of_records;
1867 file_meta->current_index = 0; /* reset for new record type EF */
1868 sim_result = TEL_SIM_RESULT_SUCCESS;
1869 g_free(record_data);
1871 /*2. SIM access fail case*/
1872 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1873 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1876 tcore_at_tok_free(tokens);
1878 err("RESPONSE NOK");
1879 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1880 sim_result = TEL_SIM_RESULT_FAILURE;
1883 dbg("Calling __imc_sim_next_from_get_response");
1884 __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
1888 static TelReturn __imc_sim_update_file(CoreObject *co,
1889 ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
1890 int p1, int p2, int p3, char *encoded_data)
1892 char *cmd_str = NULL;
1893 TelReturn ret = TEL_RETURN_FAILURE;
1894 ImcSimMetaInfo *file_meta =
1895 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1897 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1899 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"",
1900 cmd, ef, p1, p2, p3, encoded_data);
1902 ret = tcore_at_prepare_and_send_request(co,
1904 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1906 __on_response_imc_sim_update_file, resp_cb_data,
1907 on_send_imc_request, NULL);
1908 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
1910 tcore_free(encoded_data);
1916 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
1918 gchar *at_cmd = NULL;
1922 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1923 TelReturn ret = TEL_RETURN_FAILURE;
1925 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1927 /* According to TS 102 221, values of p1, p2, p3 can be as below:
1928 * 11.1.5 READ RECORD
1930 * P2: Mode, see table 11.11
1933 * Le: Number of bytes to be read (P3)
1936 p1 = (unsigned char) file_meta->current_index;
1937 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1938 p3 = (unsigned char) file_meta->rec_length;
1940 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1941 IMC_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
1943 ret = tcore_at_prepare_and_send_request(co,
1945 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1947 __on_response_imc_sim_read_data, resp_cb_data,
1948 on_send_imc_request, NULL);
1949 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
1951 dbg("ret:[%d]", ret);
1957 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
1959 gchar *at_cmd = NULL;
1964 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1965 TelReturn ret = TEL_RETURN_FAILURE;
1967 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1969 /* According to TS 102 221, values of P1, P2, P3 can be as below:
1970 * 11.1.3 READ BINARY
1971 * P1: See table 11.10
1975 * Le: Number of bytes to be read (P3)
1978 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1979 p2 = (unsigned char) offset & 0x00FF; /* offset low */
1980 p3 = (unsigned char) file_meta->data_size;
1982 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1983 IMC_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
1985 ret = tcore_at_prepare_and_send_request(co,
1987 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1989 __on_response_imc_sim_read_data, resp_cb_data,
1990 on_send_imc_request, NULL);
1991 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
1993 dbg("ret:[%d]", ret);
1999 static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
2001 gchar *at_cmd = NULL;
2002 ImcSimMetaInfo *file_meta =
2003 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2004 TelReturn ret = TEL_RETURN_FAILURE;
2006 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2008 at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
2009 IMC_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
2011 ret = tcore_at_prepare_and_send_request(co,
2013 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2015 __on_response_imc_sim_get_response, resp_cb_data,
2016 on_send_imc_request, NULL);
2017 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
2024 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
2025 const void *data, void *user_data)
2027 TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
2028 const TcoreAtResponse *at_resp = data;
2029 ImcRespCbData *resp_cb_data = user_data;
2030 CoreObject *co = tcore_pending_ref_core_object(p);
2031 ImcSimCurrSecOp *sec_op = NULL;
2032 GSList *tokens = NULL;
2033 const char *line = NULL;
2035 int attempts_left = 0;
2036 int time_penalty = 0;
2040 tcore_check_return_assert(co != NULL);
2041 tcore_check_return_assert(resp_cb_data != NULL);
2043 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2045 if (at_resp && at_resp->success) {
2046 dbg("Sim Get Retry Count [OK]");
2048 if (at_resp->lines) {
2049 line = (const char *)at_resp->lines->data;
2050 tokens = tcore_at_tok_new(line);
2051 if (g_slist_length(tokens) < 3) {
2052 err("Invalid message");
2056 lock_type = atoi(g_slist_nth_data(tokens, 0));
2057 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2058 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2060 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2061 lock_type, attempts_left, time_penalty);
2064 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2065 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2067 TelSimSecPinResult verify_pin = {0, };
2069 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
2070 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2071 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
2072 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2074 verify_pin.retry_count = attempts_left;
2076 if(resp_cb_data->cb)
2077 resp_cb_data->cb(co, (gint)result,
2078 &verify_pin, resp_cb_data->cb_data);
2081 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2082 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2084 TelSimSecPukResult verify_puk = {0, };
2086 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
2087 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2088 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
2089 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2091 verify_puk.retry_count = attempts_left;
2093 if(resp_cb_data->cb)
2094 resp_cb_data->cb(co, (gint)result,
2095 &verify_puk, resp_cb_data->cb_data);
2098 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2099 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2101 TelSimSecPinResult change_pin = {0, };
2103 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
2104 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2105 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
2106 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2108 change_pin.retry_count = attempts_left;
2110 if(resp_cb_data->cb)
2111 resp_cb_data->cb(co, (gint)result,
2112 &change_pin, resp_cb_data->cb_data);
2115 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2116 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2117 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2118 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
2119 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2120 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2121 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2122 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2124 TelSimFacilityResult disable_facility = {0, };
2127 lock_type = __imc_sim_get_lock_type(*sec_op);
2128 if (lock_type == -1)
2131 disable_facility.type = lock_type;
2132 disable_facility.retry_count = attempts_left;
2134 if(resp_cb_data->cb)
2135 resp_cb_data->cb(co, (gint)result,
2136 &disable_facility, resp_cb_data->cb_data);
2139 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2140 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2141 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2142 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
2143 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2144 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2145 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2146 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2148 TelSimFacilityResult enable_facility = {0, };
2151 lock_type = __imc_sim_get_lock_type(*sec_op);
2152 if (lock_type == -1)
2155 enable_facility.type = lock_type;
2156 enable_facility.retry_count = attempts_left;
2158 if(resp_cb_data->cb)
2159 resp_cb_data->cb(co, (gint)result,
2160 &enable_facility, resp_cb_data->cb_data);
2164 err("Unhandled sec op [%d]", *sec_op);
2168 tcore_at_tok_free(tokens);
2169 imc_destroy_resp_cb_data(resp_cb_data);
2172 err("Sim Get Retry Count [NOK]");
2174 /*TODO - send response for verify pin, puk etc.,
2175 * when get_retry_count fails
2177 tcore_at_tok_free(tokens);
2178 imc_destroy_resp_cb_data(resp_cb_data);
2181 static TelReturn __imc_sim_get_retry_count(CoreObject *co,
2182 ImcRespCbData *resp_cb_data)
2184 TelReturn ret = TEL_RETURN_FAILURE;
2185 ImcSimCurrSecOp *sec_op = (
2186 ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2188 gchar *cmd_str = NULL;
2193 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2194 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2195 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2196 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2199 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2200 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2201 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2202 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2203 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2204 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2207 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2210 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2213 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2214 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2217 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2218 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2221 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2222 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2225 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2226 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2229 case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
2235 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2237 ret = tcore_at_prepare_and_send_request(co,
2239 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2241 __on_response_imc_sim_get_retry_count, resp_cb_data,
2242 on_send_imc_request, NULL);
2243 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
2249 static TelSimLockType __imc_sim_lock_type(int lock_type)
2253 return TEL_SIM_LOCK_SC;
2255 return TEL_SIM_LOCK_FD;
2257 return TEL_SIM_LOCK_PN;
2259 return TEL_SIM_LOCK_PU;
2261 return TEL_SIM_LOCK_PP;
2263 return TEL_SIM_LOCK_PC ;
2265 return TEL_SIM_LOCK_PS ;
2267 err("Invalid lock_type [%d]", lock_type);
2272 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
2273 ImcSimCurrSecOp *sec_op, int flag)
2277 case TEL_SIM_LOCK_PS :
2279 if (flag == ENABLE_FLAG)
2280 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
2281 else if (flag == DISABLE_FLAG)
2282 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
2284 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
2286 case TEL_SIM_LOCK_SC :
2288 if (flag == ENABLE_FLAG)
2289 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
2290 else if (flag == DISABLE_FLAG)
2291 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
2293 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
2295 case TEL_SIM_LOCK_FD :
2297 if (flag == ENABLE_FLAG)
2298 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
2299 else if (flag == DISABLE_FLAG)
2300 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
2302 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
2304 case TEL_SIM_LOCK_PN :
2306 if (flag == ENABLE_FLAG)
2307 *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
2308 else if (flag == DISABLE_FLAG)
2309 *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
2311 *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
2313 case TEL_SIM_LOCK_PU :
2315 if (flag == ENABLE_FLAG)
2316 *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
2317 else if (flag == DISABLE_FLAG)
2318 *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
2320 *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
2322 case TEL_SIM_LOCK_PP :
2324 if (flag == ENABLE_FLAG)
2325 *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
2326 else if (flag == DISABLE_FLAG)
2327 *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
2329 *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
2331 case TEL_SIM_LOCK_PC :
2333 if (flag == ENABLE_FLAG)
2334 *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
2335 else if (flag == DISABLE_FLAG)
2336 *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
2338 *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
2341 err("Unhandled sim lock type [%d]", lock_type);
2346 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
2349 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
2350 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
2351 case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
2352 return TEL_SIM_LOCK_PS;
2353 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
2354 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
2355 case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
2356 return TEL_SIM_LOCK_SC;
2357 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
2358 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
2359 case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
2360 return TEL_SIM_LOCK_FD;
2361 case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
2362 case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
2363 case IMC_SIM_CURR_SEC_OP_NET_STATUS :
2364 return TEL_SIM_LOCK_PN;
2365 case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
2366 case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
2367 case IMC_SIM_CURR_SEC_OP_NS_STATUS :
2368 return TEL_SIM_LOCK_PU;
2369 case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
2370 case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
2371 case IMC_SIM_CURR_SEC_OP_SP_STATUS :
2372 return TEL_SIM_LOCK_PP;
2373 case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
2374 case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
2375 case IMC_SIM_CURR_SEC_OP_CP_STATUS :
2376 return TEL_SIM_LOCK_PC ;
2378 err("Invalid sec op [%d]", sec_op);
2385 * Notification: +XSIM: <SIM state>
2387 * Possible values of <SIM state> can be
2389 * 1 PIN verification needed
2390 * 2 PIN verification not needed - Ready
2391 * 3 PIN verified - Ready
2392 * 4 PUK verification needed
2393 * 5 SIM permanently blocked
2395 * 7 ready for attach (+COPS)
2396 * 8 SIM Technical Problem
2398 * 10 SIM Reactivating
2399 * 11 SIM Reactivated
2400 * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled)
2401 * 99 SIM State Unknown
2403 static gboolean on_notification_imc_sim_status(CoreObject *co,
2404 const void *event_info, void *user_data)
2406 GSList *lines = (GSList *)event_info;
2409 dbg("SIM notification - SIM status: [+XSIM]");
2411 if (g_slist_length(lines) != 1) {
2412 err("+XSIM unsolicited message expected to be "
2413 "Single line but received multiple lines");
2417 line = (const gchar *) (lines->data);
2425 * +XSIM: <SIM state>
2427 tokens = tcore_at_tok_new(line);
2428 if (g_slist_length(tokens) == 1) {
2430 sim_state = atoi(g_slist_nth_data(tokens, 0));
2432 /* Process SIM Status */
2433 __imc_sim_process_sim_status(co, sim_state);
2435 err("Invalid message");
2438 tcore_at_tok_free(tokens);
2445 static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
2446 TcoreNotification command, guint data_len, void *data, void *user_data)
2448 CoreObject *co = (CoreObject *)user_data;
2450 tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
2452 dbg("Get SIM status");
2453 (void)__imc_sim_get_sim_status(co, NULL, NULL);
2455 return TCORE_HOOK_RETURN_CONTINUE;
2458 /* Response Functions */
2459 static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
2460 const void *data, void *user_data)
2462 const TcoreAtResponse *at_resp = data;
2463 GSList *tokens = NULL;
2464 CoreObject *co = tcore_pending_ref_core_object(p);
2465 TelSimAuthenticationResponse auth_resp = {0, };
2466 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
2467 ImcRespCbData *resp_cb_data = user_data;
2468 TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2472 if (NULL == at_resp) {
2473 err("at_resp is NULL");
2474 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2478 auth_resp.auth_type = *auth_type;
2480 if (at_resp->success == TRUE) {
2485 if (at_resp->lines != NULL) {
2486 line = at_resp->lines->data;
2487 dbg("Received data: [%s]", line);
2489 err("at_resp->lines is NULL");
2490 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2494 tokens = tcore_at_tok_new(line);
2495 if (tokens == NULL) {
2496 err("tokens is NULL");
2497 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2501 status = atoi(g_slist_nth_data(tokens, 0));
2504 dbg("Authentications successful");
2505 auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
2508 err("Synchronize fail");
2509 auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
2513 auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
2516 err("Does not support security context");
2517 auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
2520 err("Other failure");
2521 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2525 if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
2527 char *convert_kc, *convert_sres;
2529 kc = g_slist_nth_data(tokens, 1);
2531 guint convert_kc_len = 0;
2532 kc = tcore_at_tok_extract(kc);
2533 dbg("Kc: [%s]", kc);
2535 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2536 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2537 auth_resp.authentication_key_length = convert_kc_len;
2538 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2541 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2547 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2551 sres = g_slist_nth_data(tokens, 2);
2553 guint convert_sres_len = 0;
2554 sres = tcore_at_tok_extract(sres);
2555 dbg("SRES: [%s]", sres);
2557 tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
2558 if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2559 auth_resp.resp_length = convert_sres_len;
2560 memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
2562 err("Invalid SRES");
2563 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2566 g_free(convert_sres);
2568 err("Invalid SRES");
2569 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2572 } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
2573 char *res, *ck, *ik, *kc;
2574 char *convert_res, *convert_ck;
2575 char *convert_ik, *convert_kc;
2577 res = g_slist_nth_data(tokens, 1);
2579 guint convert_res_len = 0;
2580 res = tcore_at_tok_extract(res);
2581 dbg("RES/AUTS: [%s]", res);
2583 tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
2584 if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2585 auth_resp.resp_length = convert_res_len;
2586 memcpy(auth_resp.resp_data, convert_res, convert_res_len);
2588 err("Invalid RES/AUTS");
2589 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2592 g_free(convert_res);
2594 err("Invalid RES/AUTS");
2595 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2599 ck = g_slist_nth_data(tokens, 2);
2601 guint convert_ck_len = 0;
2602 ck = tcore_at_tok_extract(ck);
2603 dbg("CK: [%s]", ck);
2605 tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
2606 if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2607 auth_resp.cipher_length = convert_ck_len;
2608 memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
2611 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2617 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2621 ik = g_slist_nth_data(tokens, 3);
2623 guint convert_ik_len = 0;
2624 ik = tcore_at_tok_extract(ik);
2625 dbg("IK: [%s]", ik);
2627 tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
2628 if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2629 auth_resp.integrity_length = convert_ik_len;
2630 memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
2633 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2639 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2643 kc = g_slist_nth_data(tokens, 4);
2645 guint convert_kc_len = 0;
2646 kc = tcore_at_tok_extract(kc);
2647 dbg("Kc: [%s]", kc);
2649 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2650 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2651 auth_resp.authentication_key_length = convert_kc_len;
2652 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2655 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2661 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2665 err("Not supported");
2666 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2669 sim_result = TEL_SIM_RESULT_SUCCESS;
2671 err("RESPONSE NOK");
2672 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2676 if(resp_cb_data->cb)
2677 resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
2679 tcore_at_tok_free(tokens);
2682 static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
2683 const void *data, void *user_data)
2685 const TcoreAtResponse *at_resp = data;
2686 ImcRespCbData *resp_cb_data = user_data;
2687 CoreObject *co = tcore_pending_ref_core_object(p);
2688 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2689 ImcSimCurrSecOp *sec_op = NULL;
2690 TelSimSecPinResult verify_pin_resp = {0, };
2694 tcore_check_return_assert(co != NULL);
2695 tcore_check_return_assert(resp_cb_data != NULL);
2697 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2699 if (at_resp && at_resp->success) {
2700 dbg("Sim Verify Pin Response- [OK]");
2702 result = TEL_SIM_RESULT_SUCCESS;
2704 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
2705 TelSimCardStatus status;
2707 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2709 tcore_sim_get_status(co, &status);
2710 if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
2711 /*Update sim status*/
2712 __imc_sim_update_sim_status(co,
2713 TEL_SIM_STATUS_SIM_INITIALIZING);
2715 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
2716 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2720 if(resp_cb_data->cb)
2721 resp_cb_data->cb(co, (gint)result,
2723 resp_cb_data->cb_data);
2724 imc_destroy_resp_cb_data(resp_cb_data);
2726 err("Sim Verify Pin Response- [NOK]");
2727 /* Get retry count */
2728 __imc_sim_get_retry_count(co, resp_cb_data);
2732 static void on_response_imc_sim_verify_puks(TcorePending *p, guint data_len,
2733 const void *data, void *user_data)
2735 const TcoreAtResponse *at_resp = data;
2736 ImcRespCbData *resp_cb_data = user_data;
2737 CoreObject *co = tcore_pending_ref_core_object(p);
2738 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2739 ImcSimCurrSecOp *sec_op = NULL;
2740 TelSimSecPukResult verify_puk_resp = {0, };
2744 tcore_check_return_assert(co != NULL);
2745 tcore_check_return_assert(resp_cb_data != NULL);
2747 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2749 if (at_resp && at_resp->success) {
2750 dbg("Sim Verify Puk Response- [OK]");
2752 result = TEL_SIM_RESULT_SUCCESS;
2754 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
2755 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2756 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
2757 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2760 if(resp_cb_data->cb)
2761 resp_cb_data->cb(co, (gint)result,
2763 resp_cb_data->cb_data);
2764 imc_destroy_resp_cb_data(resp_cb_data);
2766 err("Sim Verify Puk Response- [NOK]");
2767 /* Get retry count */
2768 __imc_sim_get_retry_count(co, resp_cb_data);
2772 static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
2773 const void *data, void *user_data)
2775 const TcoreAtResponse *at_resp = data;
2776 ImcRespCbData *resp_cb_data = user_data;
2777 CoreObject *co = tcore_pending_ref_core_object(p);
2778 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2779 ImcSimCurrSecOp *sec_op = NULL;
2780 TelSimSecPinResult change_pin_resp = {0, };
2784 tcore_check_return_assert(co != NULL);
2785 tcore_check_return_assert(resp_cb_data != NULL);
2787 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2789 if (at_resp && at_resp->success) {
2790 dbg("Sim Change Pin Response- [OK]");
2792 result = TEL_SIM_RESULT_SUCCESS;
2794 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
2795 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2796 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE) {
2797 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2800 if(resp_cb_data->cb)
2801 resp_cb_data->cb(co, (gint)result,
2803 resp_cb_data->cb_data);
2804 imc_destroy_resp_cb_data(resp_cb_data);
2806 err("Sim Change Pin Response- [NOK]");
2807 /* Get retry count */
2808 __imc_sim_get_retry_count(co, resp_cb_data);
2812 static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
2813 const void *data, void *user_data)
2815 const TcoreAtResponse *at_resp = data;
2816 ImcRespCbData *resp_cb_data = user_data;
2817 CoreObject *co = tcore_pending_ref_core_object(p);
2818 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2819 ImcSimCurrSecOp *sec_op = NULL;
2820 TelSimFacilityResult disable_facility_resp = {0, };
2824 tcore_check_return_assert(co != NULL);
2825 tcore_check_return_assert(resp_cb_data != NULL);
2827 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2829 if (at_resp && at_resp->success) {
2831 dbg("Sim Disable Facility Response- [OK]");
2833 lock_type = __imc_sim_get_lock_type(*sec_op);
2834 if (lock_type == -1) {
2835 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2838 if(resp_cb_data->cb)
2839 resp_cb_data->cb(co, (gint)result,
2841 resp_cb_data->cb_data);
2842 imc_destroy_resp_cb_data(resp_cb_data);
2846 disable_facility_resp.type = lock_type;
2847 result = TEL_SIM_RESULT_SUCCESS;
2850 if(resp_cb_data->cb)
2851 resp_cb_data->cb(co, (gint)result,
2852 &disable_facility_resp,
2853 resp_cb_data->cb_data);
2854 imc_destroy_resp_cb_data(resp_cb_data);
2856 err("Sim Disable Facility Response- [NOK]");
2857 /* Get retry count */
2858 __imc_sim_get_retry_count(co, resp_cb_data);
2862 static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
2863 const void *data, void *user_data)
2865 const TcoreAtResponse *at_resp = data;
2866 ImcRespCbData *resp_cb_data = user_data;
2867 CoreObject *co = tcore_pending_ref_core_object(p);
2868 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2869 ImcSimCurrSecOp *sec_op = NULL;
2870 TelSimFacilityResult enable_facility_resp = {0, };
2874 tcore_check_return_assert(co != NULL);
2875 tcore_check_return_assert(resp_cb_data != NULL);
2877 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2879 if (at_resp && at_resp->success) {
2881 dbg("Sim Enable Facility Response- [OK]");
2883 lock_type = __imc_sim_get_lock_type(*sec_op);
2884 if (lock_type == -1) {
2885 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2888 if(resp_cb_data->cb)
2889 resp_cb_data->cb(co, (gint)result,
2891 resp_cb_data->cb_data);
2892 imc_destroy_resp_cb_data(resp_cb_data);
2896 enable_facility_resp.type = lock_type;
2897 result = TEL_SIM_RESULT_SUCCESS;
2900 if(resp_cb_data->cb)
2901 resp_cb_data->cb(co, (gint)result,
2902 &enable_facility_resp,
2903 resp_cb_data->cb_data);
2904 imc_destroy_resp_cb_data(resp_cb_data);
2906 err("Sim Enable Facility Response- [NOK]");
2907 /* Get retry count */
2908 __imc_sim_get_retry_count(co, resp_cb_data);
2912 static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
2913 const void *data, void *user_data)
2915 const TcoreAtResponse *at_resp = data;
2916 ImcRespCbData *resp_cb_data = user_data;
2917 CoreObject *co = tcore_pending_ref_core_object(p);
2918 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2919 ImcSimCurrSecOp *sec_op = NULL;
2920 TelSimFacilityInfo get_facility_resp = {0, };
2924 tcore_check_return_assert(co != NULL);
2925 tcore_check_return_assert(resp_cb_data != NULL);
2927 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2929 if (at_resp && at_resp->success) {
2930 GSList *tokens = NULL;
2934 dbg("Sim Get Facility Response- [OK]");
2936 lock_type = __imc_sim_get_lock_type(*sec_op);
2937 if (lock_type == -1) {
2938 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2941 if (at_resp->lines) {
2942 line = (const char *)at_resp->lines->data;
2943 tokens = tcore_at_tok_new(line);
2944 if (g_slist_length(tokens) != 1) {
2945 err("Invalid message");
2946 tcore_at_tok_free(tokens);
2949 get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
2950 get_facility_resp.type = lock_type;
2951 result = TEL_SIM_RESULT_SUCCESS;
2954 tcore_at_tok_free(tokens);
2956 err("Sim Get Facility Response- [NOK]");
2959 /* Invoke callback */
2960 if(resp_cb_data->cb)
2961 resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
2962 imc_destroy_resp_cb_data(resp_cb_data);
2965 static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
2966 const void *data, void *user_data)
2968 const TcoreAtResponse *at_resp = data;
2969 ImcRespCbData *resp_cb_data = user_data;
2970 CoreObject *co = tcore_pending_ref_core_object(p);
2971 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2972 TelSimLockInfo get_lock_info_resp = {0, };
2976 tcore_check_return_assert(co != NULL);
2977 tcore_check_return_assert(resp_cb_data != NULL);
2979 if(at_resp && at_resp->success) {
2980 GSList *tokens = NULL;
2983 int attempts_left = 0;
2984 int time_penalty = 0;
2986 dbg("Sim Get Lock Info Response- [OK]");
2988 if (at_resp->lines) {
2989 line = (const char *)at_resp->lines->data;
2990 tokens = tcore_at_tok_new(line);
2991 if (g_slist_length(tokens) < 3) {
2992 err("Invalid message");
2993 tcore_at_tok_free(tokens);
2997 lock_type = atoi(g_slist_nth_data(tokens, 0));
2998 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2999 time_penalty = atoi(g_slist_nth_data(tokens, 2));
3001 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
3002 lock_type, attempts_left, time_penalty);
3004 get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
3005 get_lock_info_resp.retry_count = attempts_left;
3006 result = TEL_SIM_RESULT_SUCCESS;
3008 tcore_at_tok_free(tokens);
3010 err("Sim Get Lock Info Response- [NOK]");
3013 /* Invoke callback */
3014 if(resp_cb_data->cb)
3015 resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
3016 imc_destroy_resp_cb_data(resp_cb_data);
3019 static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
3021 const TcoreAtResponse *resp = data;
3022 CoreObject *co = NULL;
3023 TelSimApduResp apdu_resp = {0,};
3024 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3025 GSList *tokens = NULL;
3027 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3031 co = tcore_pending_ref_core_object(p);
3033 if (resp->success > 0) {
3037 char *decoded_data = NULL;
3038 guint decoded_data_len = 0;
3039 line = (const char *)resp->lines->data;
3040 tokens = tcore_at_tok_new(line);
3041 if (g_slist_length(tokens) != 2) {
3042 err("Invalid message");
3046 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3047 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3049 apdu_resp.apdu_resp_len = decoded_data_len;
3050 memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
3052 g_free(decoded_data);
3053 sim_result = TEL_SIM_RESULT_SUCCESS;
3056 err("RESPONSE NOK");
3061 if (resp_cb_data->cb)
3062 resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
3063 tcore_at_tok_free(tokens);
3067 static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
3069 const TcoreAtResponse *resp = data;
3070 CoreObject *co = NULL;
3071 TelSimAtr atr_res = {0,};
3072 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3073 GSList *tokens = NULL;
3075 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3079 co = tcore_pending_ref_core_object(p);
3081 if (resp->success > 0) {
3085 char *decoded_data = NULL;
3086 guint decoded_data_len = 0;
3087 line = (const char *)resp->lines->data;
3088 tokens = tcore_at_tok_new(line);
3089 if (g_slist_length(tokens) < 1) {
3090 err("Invalid message");
3094 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3095 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3097 atr_res.atr_len = decoded_data_len;
3098 memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
3100 g_free(decoded_data);
3101 sim_result = TEL_SIM_RESULT_SUCCESS;
3104 err("RESPONSE NOK");
3109 if (resp_cb_data->cb)
3110 resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
3111 tcore_at_tok_free(tokens);
3115 /* SIM Operations */
3117 * Operation - get_imsi
3120 * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3131 * 28423 meaning IMSI file (6F07)
3132 * 28473 meaning ACM file (6F39)
3133 * 28481 meaning PUKT file (6F41)
3134 * 28482 meaning SMS file (6F42)
3137 * Integer type defining the request.
3138 * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
3141 * Information which shall be written to the SIM
3144 * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
3152 * +CRSM: <sw1>,<sw2>[,<response>]
3155 * Integer type containing the SIM information
3158 * Response of successful completion of the command previously issued
3161 * +CME ERROR: <error>
3163 static TelReturn imc_sim_get_imsi (CoreObject *co,
3164 TcoreObjectResponseCallback cb, void *cb_data)
3169 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
3174 static TelReturn imc_sim_get_ecc (CoreObject *co,
3175 TcoreObjectResponseCallback cb, void *cb_data)
3180 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
3185 static TelReturn imc_sim_get_iccid (CoreObject *co,
3186 TcoreObjectResponseCallback cb, void *cb_data)
3191 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
3196 static TelReturn imc_sim_get_language (CoreObject *co,
3197 TcoreObjectResponseCallback cb, void *cb_data)
3202 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;
3213 char *encoded_data = NULL;
3214 int encoded_data_len = 0;
3221 file_meta.file_id = TEL_SIM_EF_LP;
3222 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3224 tcore_sim_get_type(co, &card_type);
3226 dbg("language[%d], card_type[%d]", language, card_type);
3228 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
3231 tcore_sim_encode_lp(language, &encoded_data, &encoded_data_len);
3232 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
3236 if (tcore_sim_encode_li(language, &tmp, &encoded_data_len)) {
3237 encoded_data = g_strdup_printf("%02x%02x", tmp[0], tmp[1]);
3241 err("Failed to encode Language [%d]", language);
3242 return TEL_RETURN_FAILURE;
3245 err("Invalid card_type:[%d]", card_type);
3246 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
3249 if (!encoded_data_len) {
3250 err("Failed to encode Language [%d]", language);
3251 return TEL_RETURN_FAILURE;
3253 dbg("Encoded Language [%s] len[%d]", encoded_data, encoded_data_len);
3257 p3 = encoded_data_len;
3259 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3260 &file_meta, sizeof(ImcSimMetaInfo));
3262 return __imc_sim_update_file(co, resp_cb_data,
3263 IMC_SIM_ACCESS_UPDATE_BINARY, TEL_SIM_EF_LP,
3264 p1, p2, p3, encoded_data);
3267 static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
3268 TcoreObjectResponseCallback cb, void *cb_data)
3273 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
3278 static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
3279 TcoreObjectResponseCallback cb, void *cb_data)
3284 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
3289 static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
3290 const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
3292 ImcSimMetaInfo file_meta = {0, };
3293 ImcRespCbData *resp_cb_data = NULL;
3294 gchar *encoded_mwis;
3295 guint encoded_mwis_len = 0;
3296 gchar *encoded_data = NULL;
3297 guint encoded_data_len = 0;
3305 * Videomail is not supported.
3307 if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
3308 &encoded_mwis, &encoded_mwis_len)) {
3309 err("Failed to encode mwis");
3310 return TEL_RETURN_FAILURE;
3313 encoded_data_len = 2 * encoded_mwis_len;
3314 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3315 tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
3316 tcore_free(encoded_mwis);
3317 dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
3321 p3 = TEL_SIM_MAILBOX_TYPE_MAX; /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
3322 dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
3324 file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
3325 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3327 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3329 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3330 TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
3333 static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
3334 TcoreObjectResponseCallback cb, void *cb_data)
3339 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
3344 static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
3345 const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
3347 ImcSimMetaInfo file_meta = {0, };
3348 ImcRespCbData *resp_cb_data = NULL;
3351 char *encoded_data = NULL;
3352 int encoded_data_len = 0;
3359 file_meta.file_id = TEL_SIM_EF_USIM_MBI;
3360 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3362 /* TBD - Do Encoding.
3363 if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
3364 err("Failed to encode mwis");
3365 return TEL_RETURN_FAILURE;
3368 encoded_data_len = tmp_len * 2;
3369 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3370 tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3371 if (!encoded_data) {
3372 err("Failed to convert byte to hex");
3373 tcore_free(encoded_data);
3374 return TEL_RETURN_FAILURE;
3379 p3 = encoded_data_len;
3380 dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3382 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3384 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3385 TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
3388 static TelReturn imc_sim_get_msisdn (CoreObject *co,
3389 TcoreObjectResponseCallback cb, void *cb_data)
3394 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
3399 static TelReturn imc_sim_get_spn (CoreObject *co,
3400 TcoreObjectResponseCallback cb, void *cb_data)
3405 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
3410 static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
3411 TcoreObjectResponseCallback cb, void *cb_data)
3416 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
3421 static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
3422 TcoreObjectResponseCallback cb, void *cb_data)
3427 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
3432 static TelReturn imc_sim_req_authentication (CoreObject *co,
3433 const TelSimAuthenticationData *request,
3434 TcoreObjectResponseCallback cb, void *cb_data)
3436 gchar *cmd_str = NULL;
3437 ImcRespCbData *resp_cb_data = NULL;
3438 TelReturn ret = TEL_RETURN_FAILURE;
3439 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3440 char *convert_rand = NULL;
3441 char *convert_autn = NULL;
3447 tcore_sim_get_type(co, &card_type);
3448 if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
3451 err("Not Supported SIM type:[%d]", card_type);
3452 return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3455 if (request->rand_data != NULL) {
3456 convert_rand = tcore_malloc0(request->rand_length*2 + 1);
3457 tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
3458 dbg("Convert RAND hex to string: [%s]", convert_rand);
3460 err("rand_data is NULL");
3464 switch (request->auth_type) {
3465 case TEL_SIM_AUTH_GSM:
3467 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
3468 session_id, context_type, convert_rand);
3470 case TEL_SIM_AUTH_3G_CTX:
3472 if (request->autn_data != NULL) {
3473 convert_autn = tcore_malloc0(request->autn_length*2 + 1);
3474 tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
3475 dbg("Convert AUTN hex to string: [%s]", convert_autn);
3477 err("autn_data is NULL");
3480 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3481 session_id, context_type, convert_rand, convert_autn);
3484 err("Not supported Authentication type:[%d]", request->auth_type);
3485 ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3489 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
3491 ret = tcore_at_prepare_and_send_request(co,
3493 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3495 on_response_imc_sim_req_authentication, resp_cb_data,
3496 on_send_imc_request, NULL);
3497 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
3501 tcore_free(convert_rand);
3502 tcore_free(convert_autn);
3508 * Operation - verify_pins/verify_puks
3512 * AT-Command: AT+CPIN= <pin> [, <newpin>]
3515 * String type values
3518 * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
3520 * <puk2/pin2>, <newpin2>
3521 * String type values
3527 * +CME ERROR: <error>
3529 static TelReturn imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
3530 TcoreObjectResponseCallback cb, void *cb_data)
3532 TelReturn ret = TEL_RETURN_FAILURE;
3533 ImcRespCbData *resp_cb_data = NULL;
3534 ImcSimCurrSecOp sec_op;
3535 gchar *cmd_str = NULL;
3539 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3540 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
3541 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
3542 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3543 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
3544 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
3546 err("Invalid pin type [%d]", request->pin_type);
3547 return TEL_RETURN_INVALID_PARAMETER;
3550 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3551 &sec_op, sizeof(sec_op));
3553 ret = tcore_at_prepare_and_send_request(co,
3555 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3557 on_response_imc_sim_verify_pins, resp_cb_data,
3558 on_send_imc_request, NULL);
3559 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
3565 static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
3566 TcoreObjectResponseCallback cb, void *cb_data)
3568 TelReturn ret = TEL_RETURN_FAILURE;
3569 ImcRespCbData *resp_cb_data = NULL;
3570 ImcSimCurrSecOp sec_op;
3571 gchar *cmd_str = NULL;
3575 if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
3576 sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
3577 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
3578 request->puk_pw, request->new_pin_pw);
3579 } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
3580 sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
3581 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
3582 request->puk_pw, request->new_pin_pw);
3584 err("Invalid puk type [%d]", request->puk_type);
3585 return TEL_RETURN_INVALID_PARAMETER;
3588 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3589 &sec_op, sizeof(sec_op));
3591 ret = tcore_at_prepare_and_send_request(co,
3593 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3595 on_response_imc_sim_verify_puks, resp_cb_data,
3596 on_send_imc_request, NULL);
3597 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
3604 * Operation - change_pins
3607 * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
3622 * +CME ERROR: <error>
3624 static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
3625 TcoreObjectResponseCallback cb, void *cb_data)
3627 TelReturn ret = TEL_RETURN_FAILURE;
3628 ImcRespCbData *resp_cb_data = NULL;
3629 ImcSimCurrSecOp sec_op;
3630 gchar *cmd_str = NULL;
3631 char *pin1_fac = "SC";
3632 char *pin2_fac = "P2";
3636 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3637 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
3638 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3639 pin1_fac, request->old_pw, request->new_pw);
3640 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3641 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
3642 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3643 pin2_fac, request->old_pw, request->new_pw);
3645 err("Invalid pin type [%d]", request->pin_type);
3646 return TEL_RETURN_INVALID_PARAMETER;
3649 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3650 &sec_op, sizeof(sec_op));
3652 ret = tcore_at_prepare_and_send_request(co,
3654 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3656 on_response_imc_sim_change_pins, resp_cb_data,
3657 on_send_imc_request, NULL);
3658 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
3665 * Operation - disable_facility/enable_facility/get_facility
3668 * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
3685 * Success: when <mode>=2:
3687 * +CLCK: <status>[,<class1> [<CR><LF>
3688 * +CLCK: <status>,<class2> [...]]
3692 static TelReturn imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
3693 TcoreObjectResponseCallback cb, void *cb_data)
3695 TelReturn ret = TEL_RETURN_FAILURE;
3696 ImcRespCbData *resp_cb_data = NULL;
3697 ImcSimCurrSecOp sec_op;
3698 gchar *cmd_str = NULL;
3700 int mode = 0; /*mode = 0 for disable lock*/
3704 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3705 &sec_op, DISABLE_FLAG);
3707 return TEL_RETURN_INVALID_PARAMETER;
3709 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3710 fac, mode, request->pw);
3712 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3713 &sec_op, sizeof(sec_op));
3715 ret = tcore_at_prepare_and_send_request(co,
3717 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3719 on_response_imc_sim_disable_facility, resp_cb_data,
3720 on_send_imc_request, NULL);
3721 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3727 static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
3728 TcoreObjectResponseCallback cb, void *cb_data)
3730 TelReturn ret = TEL_RETURN_FAILURE;
3731 ImcRespCbData *resp_cb_data = NULL;
3732 ImcSimCurrSecOp sec_op;
3733 gchar *cmd_str = NULL;
3735 int mode = 1; /*mode = 1 for enable lock*/
3739 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3740 &sec_op, ENABLE_FLAG);
3742 return TEL_RETURN_INVALID_PARAMETER;
3744 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3745 fac, mode, request->pw);
3747 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3748 &sec_op, sizeof(sec_op));
3750 ret = tcore_at_prepare_and_send_request(co,
3752 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3754 on_response_imc_sim_enable_facility, resp_cb_data,
3755 on_send_imc_request, NULL);
3756 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3762 static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
3763 TcoreObjectResponseCallback cb, void *cb_data)
3765 TelReturn ret = TEL_RETURN_FAILURE;
3766 ImcRespCbData *resp_cb_data = NULL;
3767 ImcSimCurrSecOp sec_op;
3768 gchar *cmd_str = NULL;
3770 int mode = 2; /*mode = 2 for Get Facility*/
3774 fac = __imc_sim_get_fac_from_lock_type(lock_type,
3777 return TEL_RETURN_INVALID_PARAMETER;
3779 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3781 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3782 &sec_op, sizeof(sec_op));
3784 ret = tcore_at_prepare_and_send_request(co,
3786 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3788 on_response_imc_sim_get_facility, resp_cb_data,
3789 on_send_imc_request, NULL);
3790 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
3796 static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
3797 TcoreObjectResponseCallback cb, void *cb_data)
3799 TelReturn ret = TEL_RETURN_FAILURE;
3800 ImcRespCbData *resp_cb_data = NULL;
3801 gchar *cmd_str = NULL;
3806 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3808 switch (lock_type) {
3809 case TEL_SIM_LOCK_PS:
3813 case TEL_SIM_LOCK_SC:
3817 case TEL_SIM_LOCK_FD:
3821 case TEL_SIM_LOCK_PN:
3825 case TEL_SIM_LOCK_PU:
3829 case TEL_SIM_LOCK_PP:
3833 case TEL_SIM_LOCK_PC:
3841 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
3843 ret = tcore_at_prepare_and_send_request(co,
3844 cmd_str, "+XPINCNT:",
3845 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3847 on_response_imc_sim_get_lock_info, resp_cb_data,
3848 on_send_imc_request, NULL);
3849 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
3855 static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
3857 gchar *cmd_str = NULL;
3859 ImcRespCbData *resp_cb_data = NULL;
3860 TelReturn ret = TEL_RETURN_FAILURE;
3864 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3866 apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
3867 tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
3869 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
3871 ret = tcore_at_prepare_and_send_request(co,
3873 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3875 on_response_imc_sim_req_apdu, resp_cb_data,
3876 on_send_imc_request, NULL);
3877 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
3886 static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
3888 gchar *cmd_str = NULL;
3889 ImcRespCbData *resp_cb_data = NULL;
3890 TelReturn ret = TEL_RETURN_FAILURE;
3894 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3896 cmd_str = g_strdup_printf("AT+XGATR");
3898 ret = tcore_at_prepare_and_send_request(co,
3900 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3902 on_response_imc_sim_req_atr, resp_cb_data,
3903 on_send_imc_request, NULL);
3904 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
3912 /* SIM Operations */
3913 static TcoreSimOps imc_sim_ops = {
3914 .get_imsi = imc_sim_get_imsi,
3915 .get_ecc = imc_sim_get_ecc,
3916 .get_iccid = imc_sim_get_iccid,
3917 .get_language = imc_sim_get_language,
3918 .set_language = imc_sim_set_language,
3919 .get_callforwarding_info = imc_sim_get_callforwarding_info,
3920 .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
3921 .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
3922 .get_mailbox_info = imc_sim_get_mailbox_info,
3923 .set_mailbox_info = imc_sim_set_mailbox_info,
3924 .get_msisdn = imc_sim_get_msisdn,
3925 .get_spn = imc_sim_get_spn,
3926 .get_cphs_netname = imc_sim_get_cphs_netname,
3927 .get_sp_display_info = imc_sim_get_sp_display_info,
3928 .req_authentication = imc_sim_req_authentication,
3929 .verify_pins = imc_sim_verify_pins,
3930 .verify_puks = imc_sim_verify_puks,
3931 .change_pins = imc_sim_change_pins,
3932 .disable_facility = imc_sim_disable_facility,
3933 .enable_facility = imc_sim_enable_facility,
3934 .get_facility = imc_sim_get_facility,
3935 .get_lock_info = imc_sim_get_lock_info,
3936 .req_apdu = imc_sim_req_apdu,
3937 .req_atr = imc_sim_req_atr
3940 gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
3942 ImcSimPrivateInfo *priv_info = NULL;
3946 priv_info = g_try_new0(ImcSimPrivateInfo, 1);
3947 if (priv_info == NULL)
3950 tcore_sim_link_userdata(co, priv_info);
3952 /* Set operations */
3953 tcore_sim_set_ops(co, &imc_sim_ops);
3956 tcore_object_add_callback(co, "+XSIM:",
3957 on_notification_imc_sim_status, NULL);
3960 tcore_plugin_add_notification_hook(p,
3961 TCORE_NOTIFICATION_MODEM_POWER,
3962 on_hook_imc_modem_power, co);
3968 void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
3970 ImcSimPrivateInfo *priv_info = NULL;
3974 priv_info = tcore_sim_ref_userdata(co);