4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <core_object.h>
32 #include <user_request.h>
39 #define ID_RESERVED_AT 0x0229
41 #define SWAPBYTES16(x) \
43 unsigned short int data = *(unsigned short int *) &(x); \
44 data = ((data & 0xff00) >> 8) | \
45 ((data & 0x00ff) << 8); \
46 *(unsigned short int *) &(x) = data; \
49 enum s_sim_file_type_e {
50 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
51 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
52 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
53 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
54 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
69 SEC_PIN2_DISABLE, // 10
90 SEC_SIM_UNKNOWN = 0xff
93 struct s_sim_property {
94 gboolean b_valid; /**< Valid or not */
95 enum tel_sim_file_id file_id; /**< File identifier */
96 enum s_sim_file_type_e file_type; /**< File type and structure */
97 int rec_length; /**< Length of one record in file */
98 int rec_count; /**< Number of records in file */
99 int data_size; /**< File size */
100 int current_index; /**< current index to read */
101 enum tel_sim_status first_recv_status;
102 enum s_sim_sec_op_e current_sec_op; /**< current index to read */
103 struct tel_sim_mbi_list mbi_list;
104 struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
105 struct tresp_sim_read files;
108 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
109 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
110 static gboolean _get_sim_type(CoreObject *o);
111 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
112 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
113 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
114 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
115 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
117 static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
119 TcoreATRequest *req = NULL;
120 TcoreHal *hal = NULL;
121 TcorePending *pending = NULL;
125 hal = tcore_object_get_hal(co);
128 pending = tcore_pending_new(co, 0);
130 dbg("Pending is NULL");
131 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
133 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
135 tcore_pending_set_request_data(pending, 0, req);
136 tcore_pending_set_response_callback(pending, callback, NULL);
137 tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
138 ret = tcore_hal_send_request(hal, pending);
143 static enum tcore_response_command _find_resp_command(UserRequest *ur)
145 enum tcore_request_command command;
147 command = tcore_user_request_get_command(ur);
149 case TREQ_SIM_VERIFY_PINS:
150 return TRESP_SIM_VERIFY_PINS;
153 case TREQ_SIM_VERIFY_PUKS:
154 return TRESP_SIM_VERIFY_PUKS;
157 case TREQ_SIM_CHANGE_PINS:
158 return TRESP_SIM_CHANGE_PINS;
161 case TREQ_SIM_GET_FACILITY_STATUS:
162 return TRESP_SIM_GET_FACILITY_STATUS;
165 case TREQ_SIM_DISABLE_FACILITY:
166 return TRESP_SIM_DISABLE_FACILITY;
169 case TREQ_SIM_ENABLE_FACILITY:
170 return TRESP_SIM_ENABLE_FACILITY;
173 case TREQ_SIM_GET_LOCK_INFO:
174 return TRESP_SIM_GET_LOCK_INFO;
177 case TREQ_SIM_TRANSMIT_APDU:
178 return TRESP_SIM_TRANSMIT_APDU;
181 case TREQ_SIM_GET_ATR:
182 return TRESP_SIM_GET_ATR;
185 case TREQ_SIM_GET_ECC:
186 return TRESP_SIM_GET_ECC;
189 case TREQ_SIM_GET_LANGUAGE:
190 return TRESP_SIM_GET_LANGUAGE;
193 case TREQ_SIM_SET_LANGUAGE:
194 return TRESP_SIM_SET_LANGUAGE;
197 case TREQ_SIM_GET_ICCID:
198 return TRESP_SIM_GET_ICCID;
201 case TREQ_SIM_GET_MAILBOX:
202 return TRESP_SIM_GET_MAILBOX;
205 case TREQ_SIM_GET_CALLFORWARDING:
206 return TRESP_SIM_GET_CALLFORWARDING;
209 case TREQ_SIM_SET_CALLFORWARDING:
210 return TRESP_SIM_SET_CALLFORWARDING;
213 case TREQ_SIM_GET_MESSAGEWAITING:
214 return TRESP_SIM_GET_MESSAGEWAITING;
217 case TREQ_SIM_GET_CPHS_INFO:
218 return TRESP_SIM_GET_CPHS_INFO;
221 case TREQ_SIM_GET_MSISDN:
222 return TRESP_SIM_GET_MSISDN;
225 case TREQ_SIM_GET_SPN:
226 return TRESP_SIM_GET_SPN;
229 case TREQ_SIM_GET_SPDI:
230 return TRESP_SIM_GET_SPDI;
233 case TREQ_SIM_GET_OPL:
234 return TRESP_SIM_GET_OPL;
237 case TREQ_SIM_GET_PNN:
238 return TRESP_SIM_GET_PNN;
241 case TREQ_SIM_GET_CPHS_NETNAME:
242 return TRESP_SIM_GET_CPHS_NETNAME;
245 case TREQ_SIM_GET_OPLMNWACT:
246 return TRESP_SIM_GET_OPLMNWACT;
249 case TREQ_SIM_REQ_AUTHENTICATION:
250 return TRESP_SIM_REQ_AUTHENTICATION;
256 return TRESP_UNKNOWN;
259 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
263 dbg("current sec_op[%d]", op);
266 case SEC_PIN1_VERIFY:
267 case SEC_PIN1_CHANGE:
268 ret_type = SIM_PTYPE_PIN1;
271 case SEC_PIN2_VERIFY:
272 case SEC_PIN2_CHANGE:
273 ret_type = SIM_PTYPE_PIN2;
276 case SEC_PUK1_VERIFY:
277 ret_type = SIM_PTYPE_PUK1;
280 case SEC_PUK2_VERIFY:
281 ret_type = SIM_PTYPE_PUK2;
285 ret_type = SIM_PTYPE_SIM;
289 ret_type = SIM_PTYPE_ADM;
292 case SEC_PIN1_ENABLE:
293 case SEC_PIN1_DISABLE:
294 case SEC_PIN1_STATUS:
295 ret_type = SIM_FACILITY_SC;
299 case SEC_SIM_DISABLE:
301 ret_type = SIM_FACILITY_PS;
305 case SEC_NET_DISABLE:
307 ret_type = SIM_FACILITY_PN;
313 ret_type = SIM_FACILITY_PU;
319 ret_type = SIM_FACILITY_PP;
325 ret_type = SIM_FACILITY_PC;
329 case SEC_FDN_DISABLE:
331 ret_type = SIM_FACILITY_FD;
335 dbg("not handled current sec op[%d]", op)
341 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
343 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
345 if (status_word1 == 0x93 && status_word2 == 0x00) {
346 rst = SIM_ACCESS_FAILED;
347 /*Failed SIM request command*/
348 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
349 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
350 rst = SIM_ACCESS_FAILED;
351 /*Failed SIM request command*/
352 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
353 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
354 rst = SIM_ACCESS_FAILED;
355 /*Failed SIM request command*/
356 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
357 status_word1, status_word2);
358 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
359 rst = SIM_ACCESS_FILE_NOT_FOUND;
360 /*Failed SIM request command*/
361 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
362 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
363 rst = SIM_ACCESS_FAILED; /* MOdem not support */
364 /*Failed SIM request command*/
365 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
366 status_word1, status_word2);
367 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
368 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
369 /*Failed SIM request command*/
370 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
371 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
372 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
373 /*Failed SIM request command*/
374 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
375 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
376 status_word1, status_word2);
377 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
378 status_word1, status_word2);
379 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
380 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
381 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
382 /*Failed SIM request command*/
383 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
384 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
385 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
386 /*Failed SIM request command*/
387 dbg(" error - Contradiction with invalidation status [%x][%x]",
388 status_word1, status_word2);
389 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
390 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
391 /*Failed SIM request command*/
392 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
393 status_word1, status_word2);
394 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
395 status_word1, status_word2);
396 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
397 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
398 rst = SIM_ACCESS_FAILED;
399 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
400 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
401 rst = SIM_ACCESS_FAILED;
402 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
403 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
404 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
405 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
406 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
407 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
408 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
409 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
410 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
411 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
412 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
413 rst = SIM_ACCESS_FAILED;
414 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
415 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
416 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
417 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
418 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
419 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
420 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
422 rst = SIM_ACCESS_CARD_ERROR;
423 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
428 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
431 Storage *strg = NULL;
432 char *old_imsi = NULL;
433 char new_imsi[15 + 1] = {0, };
435 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
437 dbg("there is no valid server at this point");
440 strg = (Storage *) tcore_server_find_storage(s, "vconf");
442 dbg("there is no valid storage plugin");
445 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
446 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
447 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
449 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
450 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
452 if (old_imsi != NULL) {
453 if (strncmp(old_imsi, new_imsi, 15) != 0) {
455 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
456 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
458 tcore_sim_set_identification(o, TRUE);
461 tcore_sim_set_identification(o, FALSE);
464 dbg("OLD SIM VALUE IS NULL. NEW SIM");
465 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
466 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
468 tcore_sim_set_identification(o, TRUE);
473 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
475 struct tresp_sim_read resp = {0, };
476 struct s_sim_property *file_meta = NULL;
478 dbg("EF[0x%x] access Result[%d]", ef, rt);
481 memset(&resp.data, 0x00, sizeof(resp.data));
482 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
484 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
485 && (rt != SIM_ACCESS_SUCCESS)) {
486 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
492 if (rt == SIM_ACCESS_SUCCESS) {
493 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
494 /* if (po->language_file == 0x00)
495 po->language_file = SIM_EF_ELP;*/
496 _get_file_data(o, ur, ef, 0, file_meta->data_size);
498 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
499 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
500 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
501 _get_file_info(o, ur, SIM_EF_LP);
502 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
504 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
505 /* EFELPand EFLI not present at this point. */
506 /* po->language.lang_cnt = 0;*/
507 tcore_user_request_send_response(ur, _find_resp_command(ur),
508 sizeof(struct tresp_sim_read), &resp);
514 case SIM_EF_LP: // same with SIM_EF_USIM_LI
515 if (rt == SIM_ACCESS_SUCCESS) {
516 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
517 _get_file_data(o, ur, ef, 0, file_meta->data_size);
519 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
520 tcore_sim_get_type(o));
521 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
522 tcore_user_request_send_response(ur, _find_resp_command(ur),
523 sizeof(struct tresp_sim_read), &resp);
526 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
527 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
528 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
529 _get_file_info(o, ur, SIM_EF_ELP);
535 if (rt == SIM_ACCESS_SUCCESS) {
536 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
537 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
539 /* EFELIand EFPL not present, so set language count as zero and select ECC */
541 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
542 tcore_user_request_send_response(ur, _find_resp_command(ur),
543 sizeof(struct tresp_sim_read), &resp);
549 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
550 _get_file_data(o, ur, ef, 0, file_meta->data_size);
551 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
552 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
553 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
556 file_meta->current_index++;
557 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
566 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
567 case SIM_EF_CPHS_VOICE_MSG_WAITING:
568 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
569 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
570 case SIM_EF_CPHS_DYNAMICFLAGS:
571 case SIM_EF_CPHS_DYNAMIC2FLAG:
572 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
573 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
574 _get_file_data(o, ur, ef, 0, file_meta->data_size);
577 case SIM_EF_CPHS_CPHS_INFO:
578 if (rt == SIM_ACCESS_SUCCESS) {
579 tcore_sim_set_cphs_status(o, TRUE);
580 if (!tcore_user_request_ref_communicator(ur)) {
581 dbg("internal CPHS INFO request before sim status update");
582 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
584 dbg("external CPHS INFO request");
585 _get_file_data(o, ur, ef, 0, file_meta->data_size);
588 tcore_sim_set_cphs_status(o, FALSE);
589 if (!tcore_user_request_ref_communicator(ur)) {
590 dbg("internal CPHS INFO request before sim status update");
591 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
593 dbg("external CPHS INFO request");
594 tcore_user_request_send_response(ur, _find_resp_command(ur),
595 sizeof(struct tresp_sim_read), &resp);
601 case SIM_EF_USIM_CFIS:
602 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
603 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
605 file_meta->current_index++;
606 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
611 case SIM_EF_USIM_MWIS:
612 case SIM_EF_USIM_MBI:
614 case SIM_EF_CPHS_MAILBOX_NUMBERS:
615 case SIM_EF_CPHS_INFORMATION_NUMBERS:
617 file_meta->current_index++;
618 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
622 dbg("error - File id for get file info [0x%x]", ef);
628 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
630 struct s_sim_property *file_meta = NULL;
634 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
635 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
636 switch (file_meta->file_id) {
641 if (decode_ret == TRUE) {
642 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
643 /* po->language_file = SIM_EF_LP;*/
644 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
645 /* po->language_file = SIM_EF_ELP;*/
647 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
650 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
651 - EFELP is not available;
652 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
653 - the ME does not support any of the languages in EFELP.
656 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
657 - if the EFLI has the value 'FFFF' in its highest priority position
658 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
660 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
661 if (file_meta->file_id == SIM_EF_LP) {
662 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
664 _get_file_info(o, ur, SIM_EF_LP);
666 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
667 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
668 _get_file_info(o, ur, SIM_EF_ELP);
670 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
677 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
678 if (file_meta->current_index == file_meta->rec_count) {
679 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
681 file_meta->current_index++;
682 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
684 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
685 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
687 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
692 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
693 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
697 if (file_meta->current_index == file_meta->rec_count) {
698 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
700 file_meta->current_index++;
701 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
706 if (file_meta->current_index == file_meta->rec_count) {
707 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
709 file_meta->current_index++;
710 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
715 if (file_meta->current_index == file_meta->rec_count) {
716 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
718 file_meta->current_index++;
719 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
723 case SIM_EF_USIM_CFIS:
724 case SIM_EF_USIM_MWIS:
725 case SIM_EF_USIM_MBI:
727 case SIM_EF_CPHS_MAILBOX_NUMBERS:
728 case SIM_EF_CPHS_INFORMATION_NUMBERS:
729 if (file_meta->current_index == file_meta->rec_count) {
730 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
732 file_meta->current_index++;
733 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
737 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
738 file_meta->files.result = rt;
739 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
740 memcpy(file_meta->files.data.cphs_net.full_name, file_meta->files.data.cphs_net.full_name, strlen((char *) file_meta->files.data.cphs_net.full_name));
742 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
745 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
746 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
747 file_meta->files.result = SIM_ACCESS_SUCCESS;
749 if (strlen((char *) file_meta->files.data.cphs_net.full_name)) {
750 memcpy(&file_meta->files.data.cphs_net.full_name, &file_meta->files.data.cphs_net.full_name, strlen((char *) file_meta->files.data.cphs_net.full_name));
752 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
759 case SIM_EF_OPLMN_ACT:
760 case SIM_EF_CPHS_CPHS_INFO:
761 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
762 case SIM_EF_CPHS_VOICE_MSG_WAITING:
763 case SIM_EF_CPHS_DYNAMICFLAGS:
764 case SIM_EF_CPHS_DYNAMIC2FLAG:
765 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
766 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
767 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
771 dbg("File id not handled [0x%x]", file_meta->file_id);
776 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
778 struct tnoti_sim_status noti_data = {0, };
780 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
781 tcore_sim_set_status(o, sim_status);
782 noti_data.sim_status = sim_status;
783 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
784 sizeof(struct tnoti_sim_status), ¬i_data);
787 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
789 const TcoreATResponse *resp = data;
790 UserRequest *ur = NULL;
791 CoreObject *co_sim = NULL;
792 struct s_sim_property *sp = NULL;
793 GSList *tokens = NULL;
794 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
798 dbg(" Function entry ");
800 co_sim = tcore_pending_ref_core_object(p);
801 sp = tcore_sim_ref_userdata(co_sim);
802 ur = tcore_pending_ref_user_request(p);
804 if (resp->success > 0) {
807 line = (const char *) resp->lines->data;
808 tokens = tcore_at_tok_new(line);
809 if (g_slist_length(tokens) != 1) {
810 msg("invalid message");
811 tcore_at_tok_free(tokens);
815 state = atoi(g_slist_nth_data(tokens, 0));
816 dbg("SIM Type is %d", state);
819 sim_type = SIM_TYPE_GSM;
820 } else if (state == 1) {
821 sim_type = SIM_TYPE_USIM;
823 sim_type = SIM_TYPE_UNKNOWN;
827 sim_type = SIM_TYPE_UNKNOWN;
830 tcore_sim_set_type(co_sim, sim_type);
831 _sim_status_update(co_sim, sp->first_recv_status);
832 tcore_at_tok_free(tokens);
833 dbg(" Function exit");
836 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
838 const TcoreATResponse *resp = data;
839 UserRequest *ur = NULL;
840 CoreObject *co_sim = NULL;
841 struct s_sim_property *file_meta = NULL;
842 GSList *tokens = NULL;
843 enum tel_sim_access_result rt;
844 const char *line = NULL;
848 dbg(" Function entry ");
850 co_sim = tcore_pending_ref_core_object(p);
851 ur = tcore_pending_ref_user_request(p);
852 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
854 if (resp->success > 0) {
857 line = (const char *) resp->lines->data;
858 tokens = tcore_at_tok_new(line);
859 if (g_slist_length(tokens) < 2) {
860 err("invalid message");
861 tcore_at_tok_free(tokens);
865 sw1 = atoi(g_slist_nth_data(tokens, 0));
866 sw2 = atoi(g_slist_nth_data(tokens, 1));
868 /*1. SIM access success case*/
869 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
870 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
871 unsigned short record_len = 0;
872 char num_of_records = 0;
873 unsigned char file_id_len = 0;
874 unsigned short file_id = 0;
875 unsigned short file_size = 0;
876 unsigned short file_type = 0;
877 unsigned short arr_file_id = 0;
878 int arr_file_id_rec_num = 0;
880 /* handling only last 3 bits */
881 unsigned char file_type_tag = 0x07;
882 unsigned char *ptr_data;
886 char *recordData = NULL;
887 hexData = g_slist_nth_data(tokens, 2);
888 dbg("hexData: %s", hexData);
889 dbg("hexData: %s", hexData + 1);
891 tmp = util_removeQuotes(hexData);
892 recordData = util_hexStringToBytes(tmp);
893 util_hex_dump(" ", strlen(hexData) / 2, recordData);
896 ptr_data = (unsigned char *) recordData;
897 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
899 ETSI TS 102 221 v7.9.0
901 '62' FCP template tag
903 '82' M File Descriptor
904 '83' M File Identifier
905 'A5' O Proprietary information
906 '8A' M Life Cycle Status Integer
907 '8B', '8C' or 'AB' C1 Security attributes
909 '81' O Total file size
910 '88' O Short File Identifier (SFI)
913 /* rsim.res_len has complete data length received */
915 /* FCP template tag - File Control Parameters tag*/
916 if (*ptr_data == 0x62) {
917 /* parse complete FCP tag*/
918 /* increment to next byte */
920 tag_len = *ptr_data++;
921 dbg("tag_len: %02x", tag_len);
922 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
923 if (*ptr_data == 0x82) {
924 /* increment to next byte */
928 /* unsigned char file_desc_len = *ptr_data++;*/
929 /* dbg("file descriptor length: [%d]", file_desc_len);*/
930 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
931 /* consider only last 3 bits*/
932 dbg("file_type_tag: %02x", file_type_tag);
933 file_type_tag = file_type_tag & (*ptr_data);
934 dbg("file_type_tag: %02x", file_type_tag);
936 switch (file_type_tag) {
937 /* increment to next byte */
940 dbg("Getting FileType: [Transparent file type]");
941 file_type = SIM_FTYPE_TRANSPARENT;
943 /* increment to next byte */
945 /* increment to next byte */
950 dbg("Getting FileType: [Linear fixed file type]");
951 /* increment to next byte */
953 /* data coding byte - value 21 */
956 memcpy(&record_len, ptr_data, 2);
958 SWAPBYTES16(record_len);
959 ptr_data = ptr_data + 2;
960 num_of_records = *ptr_data++;
961 /* Data lossy conversation from enum (int) to unsigned char */
962 file_type = SIM_FTYPE_LINEAR_FIXED;
966 dbg(" Cyclic fixed file type");
967 /* increment to next byte */
969 /* data coding byte - value 21 */
972 memcpy(&record_len, ptr_data, 2);
974 SWAPBYTES16(record_len);
975 ptr_data = ptr_data + 2;
976 num_of_records = *ptr_data++;
977 file_type = SIM_FTYPE_CYCLIC;
981 dbg("not handled file type [0x%x]", *ptr_data);
985 dbg("INVALID FCP received - DEbug!");
986 tcore_at_tok_free(tokens);
991 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
992 if (*ptr_data == 0x83) {
993 /* increment to next byte */
995 file_id_len = *ptr_data++;
996 dbg("file_id_len: %02x", file_id_len);
998 memcpy(&file_id, ptr_data, file_id_len);
999 dbg("file_id: %x", file_id);
1002 SWAPBYTES16(file_id);
1003 dbg("file_id: %x", file_id);
1005 ptr_data = ptr_data + 2;
1006 dbg("Getting FileID=[0x%x]", file_id);
1008 dbg("INVALID FCP received - DEbug!");
1009 tcore_at_tok_free(tokens);
1014 /* proprietary information */
1015 if (*ptr_data == 0xA5) {
1016 unsigned short prop_len;
1017 /* increment to next byte */
1021 prop_len = *ptr_data;
1022 dbg("prop_len: %02x", prop_len);
1025 ptr_data = ptr_data + prop_len + 1;
1027 dbg("INVALID FCP received - DEbug!");
1030 /* life cycle status integer [8A][length:0x01][status]*/
1033 00000000 : No information given
1034 00000001 : creation state
1035 00000011 : initialization state
1036 000001-1 : operation state -activated
1037 000001-0 : operation state -deactivated
1038 000011-- : Termination state
1039 b8~b5 !=0, b4~b1=X : Proprietary
1040 Any other value : RFU
1042 if (*ptr_data == 0x8A) {
1043 /* increment to next byte */
1045 /* length - value 1 */
1048 switch (*ptr_data) {
1051 dbg("<RX> operation state -deactivated");
1057 dbg("<RX> operation state -activated");
1062 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1068 /* related to security attributes : currently not handled*/
1069 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1070 /* increment to next byte */
1072 /* if tag length is 3 */
1073 if (*ptr_data == 0x03) {
1074 /* increment to next byte */
1077 memcpy(&arr_file_id, ptr_data, 2);
1079 SWAPBYTES16(arr_file_id);
1080 ptr_data = ptr_data + 2;
1081 arr_file_id_rec_num = *ptr_data++;
1083 /* if tag length is not 3 */
1084 /* ignoring bytes */
1085 // ptr_data = ptr_data + 4;
1086 dbg("Useless security attributes, so jump to next tag");
1087 ptr_data = ptr_data + (*ptr_data + 1);
1090 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1091 tcore_at_tok_free(tokens);
1096 dbg("Current ptr_data value is [%x]", *ptr_data);
1098 /* file size excluding structural info*/
1099 if (*ptr_data == 0x80) {
1100 /* for EF file size is body of file and for Linear or cyclic it is
1101 * number of recXsizeof(one record)
1103 /* increment to next byte */
1105 /* length is 1 byte - value is 2 bytes or more */
1107 memcpy(&file_size, ptr_data, 2);
1109 SWAPBYTES16(file_size);
1110 ptr_data = ptr_data + 2;
1112 dbg("INVALID FCP received - DEbug!");
1113 tcore_at_tok_free(tokens);
1118 /* total file size including structural info*/
1119 if (*ptr_data == 0x81) {
1121 /* increment to next byte */
1126 ptr_data = ptr_data + 3;
1128 dbg("INVALID FCP received - DEbug!");
1129 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1132 /*short file identifier ignored*/
1133 if (*ptr_data == 0x88) {
1134 dbg("0x88: Do Nothing");
1138 dbg("INVALID FCP received - DEbug!");
1139 tcore_at_tok_free(tokens);
1143 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1144 unsigned char gsm_specific_file_data_len = 0;
1145 /* ignore RFU byte1 and byte2 */
1149 // file_size = p_info->response_len;
1150 memcpy(&file_size, ptr_data, 2);
1152 SWAPBYTES16(file_size);
1153 /* parsed file size */
1154 ptr_data = ptr_data + 2;
1156 memcpy(&file_id, ptr_data, 2);
1157 SWAPBYTES16(file_id);
1158 dbg(" FILE id --> [%x]", file_id);
1159 ptr_data = ptr_data + 2;
1160 /* save file type - transparent, linear fixed or cyclic */
1161 file_type_tag = (*(ptr_data + 7));
1163 switch (*ptr_data) {
1166 dbg(" RFU file type- not handled - Debug!");
1171 dbg(" MF file type - not handled - Debug!");
1176 dbg(" DF file type - not handled - Debug!");
1181 dbg(" EF file type [%d] ", file_type_tag);
1182 /* increment to next byte */
1185 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1186 /* increament to next byte as this byte is RFU */
1189 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1191 /* increment to next byte */
1193 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1194 /* the INCREASE command is allowed on the selected cyclic file. */
1195 file_type = SIM_FTYPE_CYCLIC;
1197 /* bytes 9 to 11 give SIM file access conditions */
1199 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1201 /* byte 11 is invalidate and rehabilate nibbles */
1203 /* byte 12 - file status */
1205 /* byte 13 - GSM specific data */
1206 gsm_specific_file_data_len = *ptr_data;
1208 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1210 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1211 record_len = *ptr_data;
1212 dbg("record length[%d], file size[%d]", record_len, file_size);
1214 if (record_len != 0)
1215 num_of_records = (file_size / record_len);
1217 dbg("Number of records [%d]", num_of_records);
1221 dbg(" not handled file type");
1225 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1228 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1229 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1231 file_meta->file_type = file_type;
1232 file_meta->data_size = file_size;
1233 file_meta->rec_length = record_len;
1234 file_meta->rec_count = num_of_records;
1235 file_meta->current_index = 0; // reset for new record type EF
1236 rt = SIM_ACCESS_SUCCESS;
1239 /*2. SIM access fail case*/
1240 dbg("error to get ef[0x%x]", file_meta->file_id);
1241 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1242 rt = _decode_status_word(sw1, sw2);
1244 ur = tcore_user_request_ref(ur);
1246 dbg("Calling _next_from_get_file_info");
1247 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1248 tcore_at_tok_free(tokens);
1250 dbg("RESPONSE NOK");
1251 dbg("error to get ef[0x%x]", file_meta->file_id);
1252 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1253 rt = SIM_ACCESS_FAILED;
1255 ur = tcore_user_request_ref(ur);
1256 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1258 dbg(" Function exit");
1261 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1263 const TcoreATResponse *resp = data;
1264 UserRequest *ur = NULL;
1265 CoreObject *co_sim = NULL;
1266 struct s_sim_property *file_meta = NULL;
1267 GSList *tokens = NULL;
1268 enum tel_sim_access_result rt;
1269 struct tel_sim_imsi *imsi = NULL;
1270 struct tel_sim_service_table *svct = NULL;
1271 struct tel_sim_ecc *ecc = NULL;
1272 struct tel_sim_msisdn *msisdn = NULL;
1273 struct tel_sim_opl *opl = NULL;
1274 struct tel_sim_pnn *pnn = NULL;
1275 struct tel_sim_cfis *cf = NULL;
1276 struct tel_sim_mbi *mbi = NULL;
1277 struct tel_sim_mw *mw = NULL;
1278 gboolean dr = FALSE;
1279 const char *line = NULL;
1286 dbg(" Function entry ");
1288 co_sim = tcore_pending_ref_core_object(p);
1289 ur = tcore_pending_ref_user_request(p);
1290 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
1292 if (resp->success > 0) {
1295 line = (const char *) resp->lines->data;
1296 tokens = tcore_at_tok_new(line);
1297 if (g_slist_length(tokens) != 3) {
1298 msg("invalid message");
1299 tcore_at_tok_free(tokens);
1303 sw1 = atoi(g_slist_nth_data(tokens, 0));
1304 sw2 = atoi(g_slist_nth_data(tokens, 1));
1305 res = g_slist_nth_data(tokens, 2);
1307 tmp = util_removeQuotes(res);
1308 res = util_hexStringToBytes(tmp);
1309 res_len = strlen((const char *) res);
1310 dbg("res: %s res_len: %d", res, res_len);
1312 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1313 rt = SIM_ACCESS_SUCCESS;
1314 file_meta->files.result = rt;
1315 dbg("file_meta->file_id : %x", file_meta->file_id);
1317 switch (file_meta->file_id) {
1320 dbg("res: %s", res);
1321 imsi = calloc(sizeof(struct tel_sim_imsi),1);
1322 dr = tcore_sim_decode_imsi(imsi, (unsigned char *) res, res_len);
1324 dbg("imsi decoding failed");
1326 _sim_check_identity(co_sim, imsi);
1327 tcore_sim_set_imsi(co_sim, imsi);
1335 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
1338 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
1339 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1340 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
1341 case SIM_EF_LP: /* 1 byte encoding*/
1342 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1343 /*2G LP(0x6F05) has 1 byte for each language*/
1344 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
1346 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1347 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
1352 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
1356 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
1359 case SIM_EF_SST: //EF UST has same address
1360 svct = calloc(sizeof(struct tel_sim_service_table),1);
1361 if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1362 dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *) res, res_len);
1363 }else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1364 dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *) res, res_len);
1366 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1369 dbg("SST/UST decoding failed");
1371 tcore_sim_set_service_table(co_sim, svct);
1378 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1379 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
1380 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1381 ecc = calloc(sizeof(struct tel_sim_ecc),1);
1382 dbg("decode w/ index [%d]", file_meta->current_index);
1383 dr = tcore_sim_decode_uecc(ecc, (unsigned char *) res, res_len);
1385 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1386 file_meta->files.data.ecc.ecc_count++;
1391 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
1396 dbg("decode w/ index [%d]", file_meta->current_index);
1397 msisdn = calloc(sizeof(struct tel_sim_msisdn),1);
1398 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *) res, res_len);
1400 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], msisdn, sizeof(struct tel_sim_msisdn));
1401 file_meta->files.data.msisdn_list.count++;
1408 dbg("decode w/ index [%d]", file_meta->current_index);
1409 opl = calloc(sizeof(struct tel_sim_opl),1);
1410 dr = tcore_sim_decode_opl(opl, (unsigned char *) res, res_len);
1412 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], opl, sizeof(struct tel_sim_opl));
1413 file_meta->files.data.opl.opl_count++;
1418 dbg("decode w/ index [%d]", file_meta->current_index);
1419 pnn = calloc(sizeof(struct tel_sim_pnn),1);
1420 dr = tcore_sim_decode_pnn(pnn, (unsigned char *) res, res_len);
1422 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], pnn, sizeof(struct tel_sim_pnn));
1423 file_meta->files.data.pnn.pnn_count++;
1429 case SIM_EF_OPLMN_ACT:
1430 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
1433 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1434 /* dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1437 case SIM_EF_USIM_MBI: //linear type
1438 mbi = calloc(sizeof(struct tel_sim_mbi),1);
1439 dr = tcore_sim_decode_mbi(mbi, (unsigned char *) res, res_len);
1441 memcpy( &file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count], mbi, sizeof(struct tel_sim_mbi) );
1442 file_meta->mbi_list.profile_count++;
1443 dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
1444 dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
1445 dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
1446 dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
1447 dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
1448 dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
1454 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1455 case SIM_EF_MBDN: //linear type
1456 dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info, (unsigned char *) res, res_len);
1457 file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
1460 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1461 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw, (unsigned char *) res, res_len);
1464 case SIM_EF_USIM_MWIS: //linear type
1465 mw = calloc(sizeof(struct tel_sim_mw),1);
1466 dr = tcore_sim_decode_mwis(mw, (unsigned char *) res, res_len);
1468 memcpy( &file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw) );
1469 file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
1470 file_meta->files.data.mw.mw_list.profile_count++;
1476 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
1477 dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf, (unsigned char *) res, res_len);
1480 case SIM_EF_USIM_CFIS: //linear type
1481 cf = calloc(sizeof(struct tel_sim_cfis),1);
1482 dr = tcore_sim_decode_cfis(cf, (unsigned char *) res, res_len);
1484 memcpy( &file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count], cf, sizeof(struct tel_sim_cfis) );
1485 file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
1486 file_meta->files.data.cf.cf_list.profile_count++;
1492 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1493 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1496 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1497 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
1498 dbg(" file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]", file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1501 case SIM_EF_CPHS_DYNAMICFLAGS:
1502 /* dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, p_data->response, p_data->response_len);*/
1505 case SIM_EF_CPHS_DYNAMIC2FLAG:
1506 /* dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response, p_data->response_len);*/
1509 case SIM_EF_CPHS_CPHS_INFO:
1510 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
1513 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1514 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
1517 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1518 /* dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1522 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1527 rt = _decode_status_word(sw1, sw2);
1528 file_meta->files.result = rt;
1532 tcore_at_tok_free(tokens);
1534 dbg("RESPONSE NOK");
1535 dbg("error to get ef[0x%x]", file_meta->file_id);
1536 rt = SIM_ACCESS_FAILED;
1538 ur = tcore_user_request_ref(ur);
1540 dbg("Calling _next_from_get_file_data");
1541 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1542 dbg(" Function exit");
1545 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1547 const TcoreATResponse *resp = data;
1548 UserRequest *ur = NULL;
1549 CoreObject *co_sim = NULL;
1550 struct s_sim_property *sp = NULL;
1551 GSList *tokens = NULL;
1552 const char *line = NULL;
1553 struct tresp_sim_verify_pins v_pin = {0, };
1554 struct tresp_sim_verify_puks v_puk = {0, };
1555 struct tresp_sim_change_pins change_pin = {0, };
1556 struct tresp_sim_disable_facility dis_facility = {0, };
1557 struct tresp_sim_enable_facility en_facility = {0, };
1559 int attempts_left = 0;
1560 int time_penalty = 0;
1562 dbg(" Function entry ");
1564 co_sim = tcore_pending_ref_core_object(p);
1565 sp = tcore_sim_ref_userdata(co_sim);
1566 ur = tcore_pending_ref_user_request(p);
1568 if (resp->success > 0) {
1571 line = (const char *) resp->lines->data;
1572 tokens = tcore_at_tok_new(line);
1573 if (g_slist_length(tokens) < 3) {
1574 msg("invalid message");
1575 tcore_at_tok_free(tokens);
1579 lock_type = atoi(g_slist_nth_data(tokens, 0));
1580 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1581 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1583 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1584 lock_type, attempts_left, time_penalty);
1586 switch (sp->current_sec_op) {
1587 case SEC_PIN1_VERIFY:
1588 case SEC_PIN2_VERIFY:
1589 case SEC_SIM_VERIFY:
1590 case SEC_ADM_VERIFY:
1591 v_pin.result = SIM_INCORRECT_PASSWORD;
1592 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1593 v_pin.retry_count = attempts_left;
1594 tcore_user_request_send_response(ur, _find_resp_command(ur),
1595 sizeof(struct tresp_sim_verify_pins), &v_pin);
1598 case SEC_PUK1_VERIFY:
1599 case SEC_PUK2_VERIFY:
1600 v_puk.result = SIM_INCORRECT_PASSWORD;
1601 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1602 v_puk.retry_count = attempts_left;
1603 tcore_user_request_send_response(ur, _find_resp_command(ur),
1604 sizeof(struct tresp_sim_verify_puks), &v_puk);
1607 case SEC_PIN1_CHANGE:
1608 case SEC_PIN2_CHANGE:
1609 change_pin.result = SIM_INCORRECT_PASSWORD;
1610 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1611 change_pin.retry_count = attempts_left;
1612 tcore_user_request_send_response(ur, _find_resp_command(ur),
1613 sizeof(struct tresp_sim_change_pins), &change_pin);
1616 case SEC_PIN1_DISABLE:
1617 case SEC_PIN2_DISABLE:
1618 case SEC_FDN_DISABLE:
1619 case SEC_SIM_DISABLE:
1620 case SEC_NET_DISABLE:
1621 case SEC_NS_DISABLE:
1622 case SEC_SP_DISABLE:
1623 case SEC_CP_DISABLE:
1624 dis_facility.result = SIM_INCORRECT_PASSWORD;
1625 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1626 dis_facility.retry_count = attempts_left;
1627 tcore_user_request_send_response(ur, _find_resp_command(ur),
1628 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1631 case SEC_PIN1_ENABLE:
1632 case SEC_PIN2_ENABLE:
1633 case SEC_FDN_ENABLE:
1634 case SEC_SIM_ENABLE:
1635 case SEC_NET_ENABLE:
1639 en_facility.result = SIM_INCORRECT_PASSWORD;
1640 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1641 en_facility.retry_count = attempts_left;
1642 tcore_user_request_send_response(ur, _find_resp_command(ur),
1643 sizeof(struct tresp_sim_enable_facility), &en_facility);
1647 dbg("not handled sec op[%d]", sp->current_sec_op);
1650 tcore_at_tok_free(tokens);
1652 dbg(" Function exit");
1655 static gboolean _get_sim_type(CoreObject *o)
1657 TcoreHal *hal = NULL;
1658 TcoreATRequest *req = NULL;
1659 TcorePending *pending = NULL;
1660 UserRequest *ur = NULL;
1661 char *cmd_str = NULL;
1663 dbg(" Function entry ");
1665 hal = tcore_object_get_hal(o);
1666 pending = tcore_pending_new(o, 0);
1668 cmd_str = g_strdup_printf("AT+XUICC?");
1669 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1671 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1673 tcore_pending_set_request_data(pending, 0, req);
1674 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1675 tcore_pending_link_user_request(pending, ur);
1676 tcore_hal_send_request(hal, pending);
1679 dbg(" Function exit");
1683 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1685 TcoreHal *hal = NULL;
1686 TcorePending *pending = NULL;
1687 struct s_sim_property file_meta = {0, };
1688 char *cmd_str = NULL;
1689 TReturn ret = TCORE_RETURN_FAILURE;
1692 dbg(" Function entry ");
1694 file_meta.file_id = ef;
1695 dbg("file_meta.file_id: %d", file_meta.file_id);
1696 hal = tcore_object_get_hal(o);
1697 dbg("hal: %x", hal);
1699 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1700 dbg("trt[%d]", trt);
1701 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1702 dbg("cmd_str: %s", cmd_str);
1704 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1705 tcore_pending_link_user_request(pending, ur);
1706 ret = tcore_hal_send_request(hal, pending);
1707 if (TCORE_RETURN_SUCCESS != ret) {
1708 tcore_user_request_free(ur);
1711 dbg(" Function exit");
1712 return TCORE_RETURN_SUCCESS;
1715 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1717 TcoreHal *hal = NULL;
1718 TcoreATRequest *req = NULL;
1719 TcorePending *pending = NULL;
1720 char *cmd_str = NULL;
1725 dbg(" Function entry ");
1726 hal = tcore_object_get_hal(o);
1727 pending = tcore_pending_new(o, 0);
1729 dbg("file_id: %x", ef);
1731 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1732 p2 = (unsigned char) offset & 0x00FF; // offset low
1733 p3 = (unsigned char) length;
1735 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1737 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1739 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1741 tcore_pending_set_request_data(pending, 0, req);
1742 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1743 tcore_pending_link_user_request(pending, ur);
1744 tcore_hal_send_request(hal, pending);
1747 dbg(" Function exit");
1751 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1753 TcoreHal *hal = NULL;
1754 TcoreATRequest *req = NULL;
1755 TcorePending *pending = NULL;
1756 char *cmd_str = NULL;
1761 dbg(" Function entry ");
1763 hal = tcore_object_get_hal(o);
1764 pending = tcore_pending_new(o, 0);
1766 p1 = (unsigned char) index;
1767 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1768 p3 = (unsigned char) length;
1770 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1772 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1774 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1776 tcore_pending_set_request_data(pending, 0, req);
1777 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1778 tcore_pending_link_user_request(pending, ur);
1779 tcore_hal_send_request(hal, pending);
1782 dbg(" Function exit");
1786 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1788 TcoreHal *hal = NULL;
1789 TcoreATRequest *req = NULL;
1790 TcorePending *pending = NULL;
1791 char *cmd_str = NULL;
1793 struct s_sim_property *sp = NULL;
1794 const struct treq_sim_get_lock_info *req_data = NULL;
1796 dbg(" Function entry ");
1798 hal = tcore_object_get_hal(o);
1799 pending = tcore_pending_new(o, 0);
1800 req_data = tcore_user_request_ref_data(ur, NULL);
1801 sp = tcore_sim_ref_userdata(o);
1803 switch (sp->current_sec_op) {
1804 case SEC_PIN1_VERIFY:
1805 case SEC_PIN1_CHANGE:
1806 case SEC_PIN1_ENABLE:
1807 case SEC_PIN1_DISABLE:
1811 case SEC_PIN2_VERIFY:
1812 case SEC_PIN2_CHANGE:
1813 case SEC_PIN2_ENABLE:
1814 case SEC_PIN2_DISABLE:
1815 case SEC_FDN_ENABLE:
1816 case SEC_FDN_DISABLE:
1820 case SEC_PUK1_VERIFY:
1824 case SEC_PUK2_VERIFY:
1828 case SEC_NET_ENABLE:
1829 case SEC_NET_DISABLE:
1834 case SEC_NS_DISABLE:
1839 case SEC_SP_DISABLE:
1844 case SEC_CP_DISABLE:
1848 case SEC_ADM_VERIFY:
1856 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1857 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1858 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1860 tcore_pending_set_request_data(pending, 0, req);
1861 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1862 tcore_pending_link_user_request(pending, ur);
1863 tcore_hal_send_request(hal, pending);
1866 dbg(" Function exit");
1867 return TCORE_RETURN_SUCCESS;
1871 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1873 struct s_sim_property *sp = NULL;
1875 GSList *tokens = NULL;
1876 GSList *lines = NULL;
1878 dbg("Function entry");
1881 sp = tcore_sim_ref_userdata(o);
1882 lines = (GSList *) event_info;
1883 if (1 != g_slist_length(lines)) {
1884 dbg("unsolicited msg but multiple line");
1887 line = (char *) (lines->data);
1888 tokens = tcore_at_tok_new(line);
1889 if (g_slist_length(tokens) != 1) {
1890 msg("invalid message");
1891 tcore_at_tok_free(tokens);
1896 dbg(" Function exit");
1898 tcore_at_tok_free(tokens);
1903 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1906 struct s_sim_property *sp = NULL;
1907 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1908 GSList *tokens = NULL;
1909 GSList *lines = NULL;
1910 const char *line = NULL;
1913 dbg(" Function entry ");
1915 sp = tcore_sim_ref_userdata(o);
1917 lines = (GSList *) event_info;
1918 if (1 != g_slist_length(lines)) {
1919 dbg("unsolicited msg but multiple line");
1922 line = (char *) (lines->data);
1924 tokens = tcore_at_tok_new(line);
1926 if (g_slist_length(tokens) == 4) {
1927 sim_state = atoi(g_slist_nth_data(tokens, 1));
1928 } else if (g_slist_length(tokens) == 1)
1929 sim_state = atoi(g_slist_nth_data(tokens, 0));
1931 msg("invalid message");
1932 tcore_at_tok_free(tokens);
1936 switch (sim_state) {
1937 case 0: // sim state = SIM not present
1938 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1942 case 1: // sim state = PIN verification needed
1943 sim_status = SIM_STATUS_PIN_REQUIRED;
1944 dbg(" PIN required");
1947 case 2: // sim state = PIN verification not needed \96 Ready
1948 case 3: // sim state = PIN verified \96 Ready
1949 sim_status = SIM_STATUS_INITIALIZING;
1950 dbg(" Inside PIN disabled at BOOT UP");
1953 case 4: // sim state = PUK verification needed
1954 sim_status = SIM_STATUS_PUK_REQUIRED;
1955 dbg(" PUK required");
1958 case 5: // sim state = SIM permanently blocked
1959 sim_status = SIM_STATUS_CARD_BLOCKED;
1960 dbg(" Card permanently blocked");
1963 case 6: // sim state = SIM error
1964 sim_status = SIM_STATUS_CARD_ERROR;
1965 dbg("SIM card error ");
1968 case 7: // sim state = ready for attach (+COPS)
1969 sim_status = SIM_STATUS_INIT_COMPLETED;
1970 dbg("Modem init completed");
1973 case 8: // sim state = SIM Technical Problem
1974 sim_status = SIM_STATUS_CARD_ERROR;
1975 dbg("SIM unavailable");
1978 case 9: // sim state = SIM removed
1979 sim_status = SIM_STATUS_CARD_REMOVED;
1983 case 99: // sim state = SIM State Unknown
1984 sim_status = SIM_STATUS_UNKNOWN;
1985 dbg("SIM State Unknown");
1989 dbg("SIM Status : %d", sim_status);
1993 dbg(" not handled SEC lock type ");
1997 switch (sim_status) {
1998 case SIM_STATUS_INIT_COMPLETED:
1999 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
2000 _get_file_info(o, ur, SIM_EF_IMSI);
2003 case SIM_STATUS_INITIALIZING:
2004 case SIM_STATUS_PIN_REQUIRED:
2005 case SIM_STATUS_PUK_REQUIRED:
2006 case SIM_STATUS_CARD_BLOCKED:
2007 case SIM_STATUS_NCK_REQUIRED:
2008 case SIM_STATUS_NSCK_REQUIRED:
2009 case SIM_STATUS_SPCK_REQUIRED:
2010 case SIM_STATUS_CCK_REQUIRED:
2011 case SIM_STATUS_LOCK_REQUIRED:
2012 if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
2013 dbg("first received sim status[%d]", sim_status);
2014 sp->first_recv_status = sim_status;
2017 dbg("second or later received lock status[%d]", sim_status);
2018 if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
2019 dbg("sim is not init complete in telephony side yet");
2020 _sim_status_update(o, sim_status);
2025 case SIM_STATUS_CARD_REMOVED:
2026 case SIM_STATUS_CARD_NOT_PRESENT:
2027 case SIM_STATUS_CARD_ERROR:
2028 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
2029 dbg("[SIM]SIM CARD REMOVED!!");
2030 sim_status = SIM_STATUS_CARD_REMOVED;
2032 _sim_status_update(o, sim_status);
2036 dbg("not handled status[%d]", sim_status);
2041 dbg(" Function exit");
2043 tcore_at_tok_free(tokens);
2047 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2049 const TcoreATResponse *resp = data;
2050 CoreObject *co_sim = NULL;
2052 dbg(" Function entry ");
2054 co_sim = tcore_pending_ref_core_object(p);
2056 if (resp->success > 0) {
2059 on_event_pin_status(co_sim, resp->lines, NULL);
2061 dbg("RESPONSE NOK");
2064 dbg(" Function exit");
2067 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2068 unsigned int data_len, void *data, void *user_data)
2070 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2071 CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2074 return TCORE_HOOK_RETURN_CONTINUE;
2076 dbg("Get SIM status");
2078 sim_prepare_and_send_pending_request(co_sim, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2080 return TCORE_HOOK_RETURN_CONTINUE;
2083 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2085 const TcoreATResponse *resp = data;
2086 UserRequest *ur = NULL;
2087 CoreObject *co_sim = NULL;
2088 struct s_sim_property *sp = NULL;
2089 GSList *tokens = NULL;
2090 struct tresp_sim_verify_pins res;
2091 GQueue *queue = NULL;
2095 dbg(" Function entry ");
2097 co_sim = tcore_pending_ref_core_object(p);
2098 sp = tcore_sim_ref_userdata(co_sim);
2099 ur = tcore_pending_ref_user_request(p);
2101 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2103 if (resp->success > 0) {
2105 res.result = SIM_PIN_OPERATION_SUCCESS;
2106 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2107 if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
2108 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
2109 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2111 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2113 dbg("RESPONSE NOK");
2114 line = (const char *) resp->final_response;
2115 tokens = tcore_at_tok_new(line);
2116 if (g_slist_length(tokens) < 1) {
2117 dbg("err cause not specified or string corrupted");
2118 res.result = TCORE_RETURN_3GPP_ERROR;
2119 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2121 err = atoi(g_slist_nth_data(tokens, 0));
2122 dbg("on_response_verify_pins: err = %d", err);
2123 queue = tcore_object_ref_user_data(co_sim);
2124 ur = tcore_user_request_ref(ur);
2125 _get_retry_count(co_sim, ur);
2127 tcore_at_tok_free(tokens);
2129 dbg(" Function exit");
2132 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2134 const TcoreATResponse *resp = data;
2135 UserRequest *ur = NULL;
2136 CoreObject *co_sim = NULL;
2137 struct s_sim_property *sp = NULL;
2138 GSList *tokens = NULL;
2139 struct tresp_sim_verify_puks res;
2140 GQueue *queue = NULL;
2144 dbg(" Function entry ");
2146 co_sim = tcore_pending_ref_core_object(p);
2147 sp = tcore_sim_ref_userdata(co_sim);
2148 ur = tcore_pending_ref_user_request(p);
2150 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2152 if (resp->success > 0) {
2154 res.result = SIM_PIN_OPERATION_SUCCESS;
2155 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2156 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2158 dbg("RESPONSE NOK");
2159 line = (const char *) resp->final_response;
2160 tokens = tcore_at_tok_new(line);
2162 if (g_slist_length(tokens) < 1) {
2163 dbg("err cause not specified or string corrupted");
2164 res.result = TCORE_RETURN_3GPP_ERROR;
2165 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2167 err = atoi(g_slist_nth_data(tokens, 0));
2168 queue = tcore_object_ref_user_data(co_sim);
2169 ur = tcore_user_request_ref(ur);
2170 _get_retry_count(co_sim, ur);
2172 tcore_at_tok_free(tokens);
2174 dbg(" Function exit");
2177 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2179 const TcoreATResponse *resp = data;
2180 UserRequest *ur = NULL;
2181 CoreObject *co_sim = NULL;
2182 struct s_sim_property *sp = NULL;
2183 GSList *tokens = NULL;
2184 struct tresp_sim_change_pins res;
2189 dbg(" Function entry ");
2191 co_sim = tcore_pending_ref_core_object(p);
2192 sp = tcore_sim_ref_userdata(co_sim);
2193 ur = tcore_pending_ref_user_request(p);
2195 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2197 if (resp->success > 0) {
2199 res.result = SIM_PIN_OPERATION_SUCCESS;
2200 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2201 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2203 dbg("RESPONSE NOK");
2204 line = (const char *) resp->final_response;
2205 tokens = tcore_at_tok_new(line);
2207 if (g_slist_length(tokens) < 1) {
2208 dbg("err cause not specified or string corrupted");
2209 res.result = TCORE_RETURN_3GPP_ERROR;
2210 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2212 err = atoi(g_slist_nth_data(tokens, 0));
2213 queue = tcore_object_ref_user_data(co_sim);
2214 ur = tcore_user_request_ref(ur);
2215 _get_retry_count(co_sim, ur);
2217 tcore_at_tok_free(tokens);
2219 dbg(" Function exit");
2222 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2224 const TcoreATResponse *resp = data;
2225 UserRequest *ur = NULL;
2226 CoreObject *co_sim = NULL;
2227 struct s_sim_property *sp = NULL;
2228 GSList *tokens = NULL;
2229 struct tresp_sim_get_facility_status res;
2232 dbg(" Function entry ");
2234 co_sim = tcore_pending_ref_core_object(p);
2235 sp = tcore_sim_ref_userdata(co_sim);
2236 ur = tcore_pending_ref_user_request(p);
2238 memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
2240 res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2241 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2243 if (resp->success > 0) {
2246 line = (const char *) resp->lines->data;
2247 tokens = tcore_at_tok_new(line);
2248 if (g_slist_length(tokens) != 1) {
2249 msg("invalid message");
2253 res.b_enable = atoi(g_slist_nth_data(tokens, 0));
2255 dbg("RESPONSE NOK");
2259 tcore_user_request_send_response(ur, _find_resp_command(ur),
2260 sizeof(struct tresp_sim_get_facility_status), &res);
2262 tcore_at_tok_free(tokens);
2263 dbg(" Function exit");
2266 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2268 const TcoreATResponse *resp = data;
2269 UserRequest *ur = NULL;
2270 CoreObject *co_sim = NULL;
2271 struct s_sim_property *sp = NULL;
2272 GSList *tokens = NULL;
2273 struct tresp_sim_enable_facility res;
2277 dbg(" Function entry ");
2279 co_sim = tcore_pending_ref_core_object(p);
2280 sp = tcore_sim_ref_userdata(co_sim);
2281 ur = tcore_pending_ref_user_request(p);
2283 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2285 res.result = SIM_CARD_ERROR;
2286 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2288 if (resp->success > 0) {
2291 line = (const char *) resp->lines->data;
2292 tokens = tcore_at_tok_new(line);
2293 if (g_slist_length(tokens) != 1) {
2294 msg("invalid message");
2295 tcore_user_request_send_response(ur, _find_resp_command(ur),
2296 sizeof(struct tresp_sim_enable_facility), &res);
2297 tcore_at_tok_free(tokens);
2301 res.result = SIM_PIN_OPERATION_SUCCESS;
2303 tcore_user_request_send_response(ur, _find_resp_command(ur),
2304 sizeof(struct tresp_sim_enable_facility), &res);
2306 tcore_at_tok_free(tokens);
2308 dbg("RESPONSE NOK");
2309 queue = tcore_object_ref_user_data(co_sim);
2310 ur = tcore_user_request_ref(ur);
2311 _get_retry_count(co_sim, ur);
2313 dbg(" Function exit");
2316 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2318 const TcoreATResponse *resp = data;
2319 UserRequest *ur = NULL;
2320 CoreObject *co_sim = NULL;
2321 struct s_sim_property *sp = NULL;
2322 GSList *tokens = NULL;
2323 struct tresp_sim_disable_facility res;
2327 dbg(" Function entry ");
2329 co_sim = tcore_pending_ref_core_object(p);
2330 sp = tcore_sim_ref_userdata(co_sim);
2331 ur = tcore_pending_ref_user_request(p);
2333 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2335 res.result = SIM_CARD_ERROR;
2336 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2338 if (resp->success > 0) {
2341 line = (const char *) resp->lines->data;
2342 tokens = tcore_at_tok_new(line);
2343 if (g_slist_length(tokens) != 1) {
2344 msg("invalid message");
2345 tcore_user_request_send_response(ur, _find_resp_command(ur),
2346 sizeof(struct tresp_sim_disable_facility), &res);
2347 tcore_at_tok_free(tokens);
2351 res.result = SIM_PIN_OPERATION_SUCCESS;
2353 tcore_user_request_send_response(ur, _find_resp_command(ur),
2354 sizeof(struct tresp_sim_disable_facility), &res);
2356 tcore_at_tok_free(tokens);
2358 dbg("RESPONSE NOK");
2359 queue = tcore_object_ref_user_data(co_sim);
2360 ur = tcore_user_request_ref(ur);
2361 _get_retry_count(co_sim, ur);
2363 dbg(" Function exit");
2366 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2368 const TcoreATResponse *resp = data;
2369 UserRequest *ur = NULL;
2370 CoreObject *co_sim = NULL;
2371 struct s_sim_property *sp = NULL;
2372 GSList *tokens = NULL;
2374 struct tresp_sim_verify_pins v_pin = {0, };
2375 struct tresp_sim_verify_puks v_puk = {0, };
2376 struct tresp_sim_change_pins change_pin = {0, };
2377 struct tresp_sim_disable_facility dis_facility = {0, };
2378 struct tresp_sim_enable_facility en_facility = {0, };
2380 int attempts_left = 0;
2381 int time_penalty = 0;
2383 dbg(" Function entry ");
2385 co_sim = tcore_pending_ref_core_object(p);
2386 sp = tcore_sim_ref_userdata(co_sim);
2387 ur = tcore_pending_ref_user_request(p);
2389 if (resp->success > 0) {
2392 line = (const char *) resp->lines->data;
2393 tokens = tcore_at_tok_new(line);
2394 if (g_slist_length(tokens) != 3) {
2395 msg("invalid message");
2396 tcore_at_tok_free(tokens);
2400 lock_type = atoi(g_slist_nth_data(tokens, 0));
2401 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2402 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2404 switch (sp->current_sec_op) {
2405 case SEC_PIN1_VERIFY:
2406 case SEC_PIN2_VERIFY:
2407 case SEC_SIM_VERIFY:
2408 case SEC_ADM_VERIFY:
2409 v_pin.result = SIM_INCORRECT_PASSWORD;
2410 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2411 v_pin.retry_count = attempts_left;
2412 tcore_user_request_send_response(ur, _find_resp_command(ur),
2413 sizeof(struct tresp_sim_verify_pins), &v_pin);
2416 case SEC_PUK1_VERIFY:
2417 case SEC_PUK2_VERIFY:
2418 v_puk.result = SIM_INCORRECT_PASSWORD;
2419 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2420 v_puk.retry_count = attempts_left;
2421 tcore_user_request_send_response(ur, _find_resp_command(ur),
2422 sizeof(struct tresp_sim_verify_puks), &v_puk);
2425 case SEC_PIN1_CHANGE:
2426 case SEC_PIN2_CHANGE:
2427 change_pin.result = SIM_INCORRECT_PASSWORD;
2428 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2429 change_pin.retry_count = attempts_left;
2430 tcore_user_request_send_response(ur, _find_resp_command(ur),
2431 sizeof(struct tresp_sim_change_pins), &change_pin);
2434 case SEC_PIN1_DISABLE:
2435 case SEC_PIN2_DISABLE:
2436 case SEC_FDN_DISABLE:
2437 case SEC_SIM_DISABLE:
2438 case SEC_NET_DISABLE:
2439 case SEC_NS_DISABLE:
2440 case SEC_SP_DISABLE:
2441 case SEC_CP_DISABLE:
2442 dis_facility.result = SIM_INCORRECT_PASSWORD;
2443 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2444 dis_facility.retry_count = attempts_left;
2445 tcore_user_request_send_response(ur, _find_resp_command(ur),
2446 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2449 case SEC_PIN1_ENABLE:
2450 case SEC_PIN2_ENABLE:
2451 case SEC_FDN_ENABLE:
2452 case SEC_SIM_ENABLE:
2453 case SEC_NET_ENABLE:
2457 en_facility.result = SIM_INCORRECT_PASSWORD;
2458 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2459 en_facility.retry_count = attempts_left;
2460 tcore_user_request_send_response(ur, _find_resp_command(ur),
2461 sizeof(struct tresp_sim_enable_facility), &en_facility);
2465 dbg("not handled sec op[%d]", sp->current_sec_op);
2468 tcore_at_tok_free(tokens);
2470 dbg(" Function exit");
2473 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2475 const TcoreATResponse *resp = data;
2476 UserRequest *ur = NULL;
2477 CoreObject *co_sim = NULL;
2478 struct tresp_sim_set_data resp_cf = {0, };
2479 struct tresp_sim_set_data resp_language = {0, };
2480 struct s_sim_property *sp = NULL;
2481 GSList *tokens = NULL;
2482 enum tel_sim_access_result result = SIM_CARD_ERROR;
2487 dbg(" Function entry ");
2489 co_sim = tcore_pending_ref_core_object(p);
2490 ur = tcore_pending_ref_user_request(p);
2491 sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
2493 if (resp->success > 0) {
2496 line = (const char *) resp->lines->data;
2497 tokens = tcore_at_tok_new(line);
2498 if (g_slist_length(tokens) != 2) {
2499 msg("invalid message");
2503 sw1 = atoi(g_slist_nth_data(tokens, 0));
2504 sw2 = atoi(g_slist_nth_data(tokens, 1));
2506 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2507 result = SIM_ACCESS_SUCCESS;
2509 result = _decode_status_word(sw1, sw2);
2512 dbg("RESPONSE NOK");
2513 result = SIM_ACCESS_FAILED;
2516 switch (sp->file_id) {
2517 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2518 case SIM_EF_USIM_CFIS:
2519 resp_cf.result = result;
2520 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_cf);
2525 case SIM_EF_USIM_LI:
2526 case SIM_EF_USIM_PL:
2527 resp_language.result = result;
2528 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_language);
2532 dbg("Invalid File ID - %d", sp->file_id)
2535 tcore_at_tok_free(tokens);
2536 dbg(" Function exit");
2539 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2541 const TcoreATResponse *resp = data;
2542 UserRequest *ur = NULL;
2543 CoreObject *co_sim = NULL;
2544 GSList *tokens = NULL;
2545 struct tresp_sim_transmit_apdu res;
2548 dbg(" Function entry ");
2550 co_sim = tcore_pending_ref_core_object(p);
2551 ur = tcore_pending_ref_user_request(p);
2553 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2554 res.result = SIM_ACCESS_FAILED;
2556 if (resp->success > 0) {
2560 char *decoded_data = NULL;
2561 line = (const char *) resp->lines->data;
2562 tokens = tcore_at_tok_new(line);
2563 if (g_slist_length(tokens) != 2) {
2564 msg("invalid message");
2567 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
2569 tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
2570 decoded_data = util_hexStringToBytes(tmp);
2572 memcpy((char *) res.apdu_resp, decoded_data, res.apdu_resp_length);
2575 res.result = SIM_ACCESS_SUCCESS;
2578 dbg("RESPONSE NOK");
2582 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
2584 tcore_at_tok_free(tokens);
2585 dbg(" Function exit");
2588 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
2590 const TcoreATResponse *resp = data;
2591 UserRequest *ur = NULL;
2592 GSList *tokens = NULL;
2593 struct tresp_sim_get_atr res;
2596 dbg(" Function entry ");
2598 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
2599 ur = tcore_pending_ref_user_request(p);
2601 res.result = SIM_ACCESS_FAILED;
2602 if (resp->success > 0) {
2606 char *decoded_data = NULL;
2607 line = (const char *) resp->lines->data;
2608 tokens = tcore_at_tok_new(line);
2609 if (g_slist_length(tokens) < 1) {
2610 msg("invalid message");
2614 tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
2615 decoded_data = util_hexStringToBytes(tmp);
2617 res.atr_length = strlen(decoded_data);
2618 memcpy((char *) res.atr, decoded_data, res.atr_length);
2621 res.result = SIM_ACCESS_SUCCESS;
2624 dbg("RESPONSE NOK");
2629 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_get_atr), &res);
2631 tcore_at_tok_free(tokens);
2632 dbg(" Function exit");
2635 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2637 TcoreHal *hal = NULL;
2638 TcoreATRequest *req = NULL;
2639 TcorePending *pending = NULL;
2640 char *cmd_str = NULL;
2641 const struct treq_sim_verify_pins *req_data = NULL;
2642 struct s_sim_property *sp = NULL;
2643 TReturn ret = TCORE_RETURN_FAILURE;
2645 dbg(" Function entry ");
2648 return TCORE_RETURN_EINVAL;
2650 hal = tcore_object_get_hal(o);
2651 if(FALSE == tcore_hal_get_power_state(hal)){
2652 dbg("cp not ready/n");
2653 return TCORE_RETURN_ENOSYS;
2656 sp = tcore_sim_ref_userdata(o);
2657 pending = tcore_pending_new(o, 0);
2658 req_data = tcore_user_request_ref_data(ur, NULL);
2660 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2661 sp->current_sec_op = SEC_PIN1_VERIFY;
2662 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2663 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2664 sp->current_sec_op = SEC_PIN2_VERIFY;
2665 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
2666 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
2667 sp->current_sec_op = SEC_SIM_VERIFY;
2668 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2669 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
2670 sp->current_sec_op = SEC_ADM_VERIFY;
2671 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2673 return TCORE_RETURN_EINVAL;
2676 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2678 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2680 tcore_pending_set_request_data(pending, 0, req);
2681 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
2682 tcore_pending_link_user_request(pending, ur);
2683 ret = tcore_hal_send_request(hal, pending);
2686 dbg(" Function exit");
2690 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2692 TcoreHal *hal = NULL;
2693 TcoreATRequest *req = NULL;
2694 TcorePending *pending = NULL;
2695 char *cmd_str = NULL;
2696 const struct treq_sim_verify_puks *req_data;
2697 struct s_sim_property *sp = NULL;
2698 TReturn ret = TCORE_RETURN_FAILURE;
2700 dbg(" Function entry ");
2703 return TCORE_RETURN_EINVAL;
2705 hal = tcore_object_get_hal(o);
2706 if(FALSE == tcore_hal_get_power_state(hal)){
2707 dbg("cp not ready/n");
2708 return TCORE_RETURN_ENOSYS;
2711 sp = tcore_sim_ref_userdata(o);
2712 pending = tcore_pending_new(o, 0);
2713 req_data = tcore_user_request_ref_data(ur, NULL);
2715 if (req_data->puk_type == SIM_PTYPE_PUK1) {
2716 sp->current_sec_op = SEC_PUK1_VERIFY;
2717 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2718 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
2719 sp->current_sec_op = SEC_PUK2_VERIFY;
2720 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2722 return TCORE_RETURN_EINVAL;
2724 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2726 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2728 tcore_pending_set_request_data(pending, 0, req);
2729 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
2730 tcore_pending_link_user_request(pending, ur);
2731 ret = tcore_hal_send_request(hal, pending);
2734 dbg(" Function exit");
2738 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2740 TcoreHal *hal = NULL;
2741 TcoreATRequest *req = NULL;
2742 TcorePending *pending = NULL;
2743 char *cmd_str = NULL;
2744 const struct treq_sim_change_pins *req_data;
2745 struct s_sim_property *sp = NULL;
2748 TReturn ret = TCORE_RETURN_FAILURE;
2750 dbg(" Function entry ");
2753 return TCORE_RETURN_EINVAL;
2755 hal = tcore_object_get_hal(o);
2756 if(FALSE == tcore_hal_get_power_state(hal)){
2757 dbg("cp not ready/n");
2758 return TCORE_RETURN_ENOSYS;
2761 sp = tcore_sim_ref_userdata(o);
2762 pending = tcore_pending_new(o, 0);
2763 req_data = tcore_user_request_ref_data(ur, NULL);
2765 if (req_data->type == SIM_PTYPE_PIN1) {
2766 sp->current_sec_op = SEC_PIN1_CHANGE;
2767 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
2768 } else if (req_data->type == SIM_PTYPE_PIN2) {
2769 sp->current_sec_op = SEC_PIN2_CHANGE;
2770 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
2772 return TCORE_RETURN_EINVAL;
2774 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2776 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2778 tcore_pending_set_request_data(pending, 0, req);
2779 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
2780 tcore_pending_link_user_request(pending, ur);
2781 ret = tcore_hal_send_request(hal, pending);
2784 dbg(" Function exit");
2788 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2790 TcoreHal *hal = NULL;
2791 TcoreATRequest *req = NULL;
2792 TcorePending *pending = NULL;
2793 char *cmd_str = NULL;
2794 const struct treq_sim_get_facility_status *req_data;
2796 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
2797 TReturn ret = TCORE_RETURN_FAILURE;
2799 dbg(" Function entry ");
2802 return TCORE_RETURN_EINVAL;
2804 hal = tcore_object_get_hal(o);
2805 if(FALSE == tcore_hal_get_power_state(hal)){
2806 dbg("cp not ready/n");
2807 return TCORE_RETURN_ENOSYS;
2810 pending = tcore_pending_new(o, 0);
2811 req_data = tcore_user_request_ref_data(ur, NULL);
2813 if (req_data->type == SIM_FACILITY_PS) {
2814 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2815 } else if (req_data->type == SIM_FACILITY_SC) {
2816 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2817 } else if (req_data->type == SIM_FACILITY_FD) {
2818 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2819 } else if (req_data->type == SIM_FACILITY_PN) {
2820 fac = "PN"; /*Network Personalization*/
2821 } else if (req_data->type == SIM_FACILITY_PU) {
2822 fac = "PU"; /*network sUbset Personalization*/
2823 } else if (req_data->type == SIM_FACILITY_PP) {
2824 fac = "PP"; /*service Provider Personalization*/
2825 } else if (req_data->type == SIM_FACILITY_PC) {
2826 fac = "PC"; /*Corporate Personalization*/
2828 return TCORE_RETURN_EINVAL;
2830 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
2831 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2833 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2835 tcore_pending_set_request_data(pending, 0, req);
2836 tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
2837 tcore_pending_link_user_request(pending, ur);
2838 ret = tcore_hal_send_request(hal, pending);
2841 dbg(" Function exit");
2845 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2847 TcoreHal *hal = NULL;
2848 TcoreATRequest *req = NULL;
2849 TcorePending *pending = NULL;
2850 char *cmd_str = NULL;
2851 const struct treq_sim_enable_facility *req_data;
2852 struct s_sim_property *sp = NULL;
2854 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
2855 TReturn ret = TCORE_RETURN_FAILURE;
2857 dbg(" Function entry ");
2860 return TCORE_RETURN_EINVAL;
2862 hal = tcore_object_get_hal(o);
2863 if(FALSE == tcore_hal_get_power_state(hal)){
2864 dbg("cp not ready/n");
2865 return TCORE_RETURN_ENOSYS;
2868 sp = tcore_sim_ref_userdata(o);
2869 pending = tcore_pending_new(o, 0);
2870 req_data = tcore_user_request_ref_data(ur, NULL);
2872 if (req_data->type == SIM_FACILITY_PS) {
2873 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2874 sp->current_sec_op = SEC_SIM_ENABLE;
2875 } else if (req_data->type == SIM_FACILITY_SC) {
2876 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2877 sp->current_sec_op = SEC_PIN1_ENABLE;
2878 } else if (req_data->type == SIM_FACILITY_FD) {
2879 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2880 sp->current_sec_op = SEC_FDN_ENABLE;
2881 } else if (req_data->type == SIM_FACILITY_PN) {
2882 fac = "PN"; /*Network Personalization*/
2883 sp->current_sec_op = SEC_NET_ENABLE;
2884 } else if (req_data->type == SIM_FACILITY_PU) {
2885 fac = "PU"; /*network sUbset Personalization*/
2886 sp->current_sec_op = SEC_NS_ENABLE;
2887 } else if (req_data->type == SIM_FACILITY_PP) {
2888 fac = "PP"; /*service Provider Personalization*/
2889 sp->current_sec_op = SEC_SP_ENABLE;
2890 } else if (req_data->type == SIM_FACILITY_PC) {
2891 fac = "PC"; /*Corporate Personalization*/
2892 sp->current_sec_op = SEC_CP_ENABLE;
2894 return TCORE_RETURN_EINVAL;
2896 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2897 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2899 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2901 tcore_pending_set_request_data(pending, 0, req);
2902 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
2903 tcore_pending_link_user_request(pending, ur);
2904 ret = tcore_hal_send_request(hal, pending);
2907 dbg(" Function exit");
2911 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2914 TcoreATRequest *req;
2915 TcorePending *pending = NULL;
2916 char *cmd_str = NULL;
2917 const struct treq_sim_enable_facility *req_data;
2918 struct s_sim_property *sp = NULL;
2920 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
2921 TReturn ret = TCORE_RETURN_FAILURE;
2923 dbg(" Function entry ");
2926 return TCORE_RETURN_EINVAL;
2928 hal = tcore_object_get_hal(o);
2929 if(FALSE == tcore_hal_get_power_state(hal)){
2930 dbg("cp not ready/n");
2931 return TCORE_RETURN_ENOSYS;
2934 sp = tcore_sim_ref_userdata(o);
2935 pending = tcore_pending_new(o, 0);
2936 req_data = tcore_user_request_ref_data(ur, NULL);
2938 if (req_data->type == SIM_FACILITY_PS) {
2939 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2940 sp->current_sec_op = SEC_SIM_DISABLE;
2941 } else if (req_data->type == SIM_FACILITY_SC) {
2942 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2943 sp->current_sec_op = SEC_PIN1_DISABLE;
2944 } else if (req_data->type == SIM_FACILITY_FD) {
2945 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2946 sp->current_sec_op = SEC_FDN_DISABLE;
2947 } else if (req_data->type == SIM_FACILITY_PN) {
2948 fac = "PN"; /*Network Personalization*/
2949 sp->current_sec_op = SEC_NET_DISABLE;
2950 } else if (req_data->type == SIM_FACILITY_PU) {
2951 fac = "PU"; /*network sUbset Personalization*/
2952 sp->current_sec_op = SEC_NS_DISABLE;
2953 } else if (req_data->type == SIM_FACILITY_PP) {
2954 fac = "PP"; /*service Provider Personalization*/
2955 sp->current_sec_op = SEC_SP_DISABLE;
2956 } else if (req_data->type == SIM_FACILITY_PC) {
2957 fac = "PC"; /*Corporate Personalization*/
2958 sp->current_sec_op = SEC_CP_DISABLE;
2960 return TCORE_RETURN_EINVAL;
2962 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2963 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2965 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2967 tcore_pending_set_request_data(pending, 0, req);
2968 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
2969 tcore_pending_link_user_request(pending, ur);
2970 ret = tcore_hal_send_request(hal, pending);
2973 dbg(" Function exit");
2977 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
2979 TcoreHal *hal = NULL;
2980 TcoreATRequest *req = NULL;
2981 TcorePending *pending = NULL;
2982 char *cmd_str = NULL;
2983 char *lock_type = NULL;
2984 const struct treq_sim_get_lock_info *req_data;
2985 TReturn ret = TCORE_RETURN_FAILURE;
2987 dbg(" Function entry ");
2990 return TCORE_RETURN_EINVAL;
2992 hal = tcore_object_get_hal(o);
2993 if(FALSE == tcore_hal_get_power_state(hal)){
2994 dbg("cp not ready/n");
2995 return TCORE_RETURN_ENOSYS;
2997 pending = tcore_pending_new(o, 0);
2998 req_data = tcore_user_request_ref_data(ur, NULL);
3000 switch (req_data->type) {
3001 case SIM_FACILITY_PS:
3005 case SIM_FACILITY_SC:
3009 case SIM_FACILITY_FD:
3013 case SIM_FACILITY_PN:
3017 case SIM_FACILITY_PU:
3021 case SIM_FACILITY_PP:
3025 case SIM_FACILITY_PC:
3032 cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
3033 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
3035 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3037 tcore_pending_set_request_data(pending, 0, req);
3038 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
3039 tcore_pending_link_user_request(pending, ur);
3040 ret = tcore_hal_send_request(hal, pending);
3043 dbg(" Function exit");
3047 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
3049 TReturn api_ret = TCORE_RETURN_SUCCESS;
3050 enum tcore_request_command command;
3052 dbg(" Function entry ");
3055 return TCORE_RETURN_EINVAL;
3057 command = tcore_user_request_get_command(ur);
3058 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
3059 dbg("cp not ready/n");
3060 return TCORE_RETURN_ENOSYS;
3064 case TREQ_SIM_GET_ECC:
3065 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
3068 case TREQ_SIM_GET_LANGUAGE:
3069 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
3070 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
3071 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
3072 api_ret = _get_file_info(o, ur, SIM_EF_LP);
3074 api_ret = TCORE_RETURN_ENOSYS;
3077 case TREQ_SIM_GET_ICCID:
3078 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
3081 case TREQ_SIM_GET_MAILBOX:
3082 if (tcore_sim_get_cphs_status(o))
3083 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3085 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
3088 case TREQ_SIM_GET_CALLFORWARDING:
3089 if (tcore_sim_get_cphs_status(o))
3090 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3092 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3095 case TREQ_SIM_GET_MESSAGEWAITING:
3096 if (tcore_sim_get_cphs_status(o))
3097 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3099 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3102 case TREQ_SIM_GET_CPHS_INFO:
3103 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3106 case TREQ_SIM_GET_MSISDN:
3107 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3110 case TREQ_SIM_GET_SPN:
3111 dbg("enter case SPN");
3112 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3115 case TREQ_SIM_GET_SPDI:
3116 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3119 case TREQ_SIM_GET_OPL:
3120 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3123 case TREQ_SIM_GET_PNN:
3124 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3127 case TREQ_SIM_GET_CPHS_NETNAME:
3128 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3131 case TREQ_SIM_GET_OPLMNWACT:
3132 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3136 dbg("error - not handled read treq command[%d]", command);
3137 api_ret = TCORE_RETURN_EINVAL;
3140 dbg(" Function exit");
3144 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
3147 TcoreATRequest *req;
3148 TcorePending *pending = NULL;
3149 char *cmd_str = NULL;
3150 TReturn ret = TCORE_RETURN_SUCCESS;
3151 char *encoded_data = NULL;
3152 int encoded_len = 0;
3153 enum tcore_request_command command;
3154 enum tel_sim_file_id ef = SIM_EF_INVALID;
3155 const struct treq_sim_set_callforwarding *cf;
3156 const struct treq_sim_set_language *cl;
3157 struct s_sim_property file_meta = {0, };
3164 struct tel_sim_language sim_language;
3168 command = tcore_user_request_get_command(ur);
3170 dbg(" Function entry ");
3173 return TCORE_RETURN_EINVAL;
3176 hal = tcore_object_get_hal(o);
3177 if(FALSE == tcore_hal_get_power_state(hal)){
3178 dbg("cp not ready/n");
3179 return TCORE_RETURN_ENOSYS;
3182 pending = tcore_pending_new(o, 0);
3185 case TREQ_SIM_SET_LANGUAGE:
3186 cl = tcore_user_request_ref_data(ur, NULL);
3187 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
3190 sim_language.language_count = 1;
3191 sim_language.language[0] = cl->language;
3192 dbg("language %d", cl->language);
3194 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
3197 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
3199 encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
3200 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
3201 result = util_byte_to_hex(tmp, encoded_data, out_length);
3206 dbg("encoded_data - %s ---", encoded_data);
3207 dbg("out_length - %d ---", out_length);
3208 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
3211 tmp = tcore_sim_encode_li(&out_length, &sim_language);
3213 encoded_data = (char *) malloc(2 * (out_length) + 1);
3214 memset(encoded_data, 0x00, (2 * out_length) + 1);
3215 result = util_byte_to_hex(tmp, encoded_data, out_length);
3220 dbg("encoded_data - %s ---", encoded_data);
3221 dbg("out_length - %d ---", out_length);
3223 ret = TCORE_RETURN_ENOSYS;
3227 case TREQ_SIM_SET_CALLFORWARDING:
3228 cf = tcore_user_request_ref_data(ur, NULL);
3229 if (tcore_sim_get_cphs_status(o)) {
3230 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
3231 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
3235 encoded_data = (char *) malloc(2 * (p3) + 1);
3236 memset(encoded_data, 0x00, (2 *p3) + 1);
3237 result = util_byte_to_hex(tmp, encoded_data, p3);
3238 cmd = 214; /*command - 214 : UPDATE BINARY*/
3240 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
3241 ef = SIM_EF_USIM_CFIS;
3245 encoded_data = (char *) malloc(2 * (encoded_len) + 1);
3246 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
3247 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3248 cmd = 220; /*command - 220 : UPDATE RECORD*/
3253 dbg("error - not handled update treq command[%d]", command);
3254 ret = TCORE_RETURN_EINVAL;
3257 file_meta.file_id = ef;
3258 dbg("file_meta.file_id: %d", file_meta.file_id);
3260 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
3261 dbg("trt[%d]", trt);
3263 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3264 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3266 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3268 tcore_pending_set_request_data(pending, 0, req);
3269 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
3270 tcore_pending_link_user_request(pending, ur);
3271 ret = tcore_hal_send_request(hal, pending);
3273 if (NULL != encoded_data) {
3274 g_free(encoded_data);
3282 dbg(" Function exit");
3286 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3288 TcoreHal *hal = NULL;
3289 TcoreATRequest *req = NULL;
3290 TcorePending *pending = NULL;
3291 char *cmd_str = NULL;
3295 const struct treq_sim_transmit_apdu *req_data;
3296 TReturn ret = TCORE_RETURN_FAILURE;
3298 dbg(" Function entry ");
3301 return TCORE_RETURN_EINVAL;
3303 hal = tcore_object_get_hal(o);
3304 if(FALSE == tcore_hal_get_power_state(hal)){
3305 dbg("cp not ready/n");
3306 return TCORE_RETURN_ENOSYS;
3309 pending = tcore_pending_new(o, 0);
3310 req_data = tcore_user_request_ref_data(ur, NULL);
3312 apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
3313 memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
3314 result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
3315 apdu_len = strlen(apdu);
3316 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", apdu_len, apdu);
3317 req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
3318 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3320 tcore_pending_set_request_data(pending, 0, req);
3321 tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
3322 tcore_pending_link_user_request(pending, ur);
3323 ret = tcore_hal_send_request(hal, pending);
3327 dbg(" Function exit");
3331 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
3333 TcoreHal *hal = NULL;
3334 TcoreATRequest *req = NULL;
3335 TcorePending *pending = NULL;
3336 char *cmd_str = NULL;
3337 TReturn ret = TCORE_RETURN_FAILURE;
3339 dbg(" Function entry ");
3342 return TCORE_RETURN_EINVAL;
3344 hal = tcore_object_get_hal(o);
3345 if(FALSE == tcore_hal_get_power_state(hal)) {
3346 dbg("cp not ready/n");
3347 return TCORE_RETURN_ENOSYS;
3349 pending = tcore_pending_new(o, 0);
3351 cmd_str = g_strdup_printf("AT+XGATR");
3352 req = tcore_at_request_new(cmd_str, "+XGATR:", TCORE_AT_SINGLELINE);
3353 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3355 tcore_pending_set_request_data(pending, 0, req);
3356 tcore_pending_set_response_callback(pending, on_response_get_atr, hal);
3357 tcore_pending_link_user_request(pending, ur);
3358 ret = tcore_hal_send_request(hal, pending);
3361 dbg(" Function exit");
3365 static struct tcore_sim_operations sim_ops = {
3366 .verify_pins = s_verify_pins,
3367 .verify_puks = s_verify_puks,
3368 .change_pins = s_change_pins,
3369 .get_facility_status = s_get_facility_status,
3370 .enable_facility = s_enable_facility,
3371 .disable_facility = s_disable_facility,
3372 .get_lock_info = s_get_lock_info,
3373 .read_file = s_read_file,
3374 .update_file = s_update_file,
3375 .transmit_apdu = s_transmit_apdu,
3376 .get_atr = s_get_atr,
3377 .req_authentication = NULL,
3380 gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim)
3382 struct s_sim_property *file_meta;
3386 tcore_sim_override_ops(co_sim, &sim_ops);
3388 file_meta = g_try_new0(struct s_sim_property, 1);
3392 tcore_sim_link_userdata(co_sim, file_meta);
3394 tcore_object_override_callback(co_sim, "+XLOCK", on_event_facility_lock_status, NULL);
3395 tcore_object_override_callback(co_sim, "+XSIM", on_event_pin_status, NULL);
3397 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
3404 void s_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
3406 struct s_sim_property *file_meta;
3408 file_meta = tcore_sim_ref_userdata(co_sim);