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>
33 #include <user_request.h>
36 #include <ss_manager.h>
38 #include "imc_common.h"
42 #define ID_RESERVED_AT 0x0229
43 #define SIM_PIN_MAX_RETRY_COUNT 3
44 #define SMS_STATE_READY 1
46 #define SIM_SSM_GROUP_ID "secure-storage::telephony_sim"
47 #define SIM_SSM_FILE_IMSI1 "imsi1"
49 #define SWAPBYTES16(x) \
51 unsigned short int data = *(unsigned short int *)&(x); \
52 data = ((data & 0xff00) >> 8) | \
53 ((data & 0x00ff) << 8); \
54 *(unsigned short int *)&(x) = data; \
57 enum imc_sim_sec_op_e {
69 SEC_PIN2_DISABLE, /* 10 */
79 SEC_CP_DISABLE, /* 20 */
90 SEC_SIM_UNKNOWN = 0xff
93 struct imc_sim_property {
94 gboolean b_valid; /**< Valid or not */
95 enum tel_sim_file_id file_id; /**< File identifier */
96 enum tcore_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 imc_sim_sec_op_e current_sec_op; /**< current index to read */
102 int mb_count; /**< Number of MB records in file */
103 struct tel_sim_mbi_list mbi_list;
104 struct tel_sim_mailbox mb_data;
105 struct tresp_sim_read files;
108 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data);
109 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
110 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
111 static gboolean _get_sim_type(CoreObject *o);
112 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
113 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
114 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
115 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
116 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
118 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)
120 TcoreATRequest *req = NULL;
121 TcoreHal *hal = NULL;
122 TcorePending *pending = NULL;
126 hal = tcore_object_get_hal(co);
129 pending = tcore_pending_new(co, 0);
131 dbg("Pending is NULL");
134 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
136 tcore_pending_free(pending);
140 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
142 tcore_pending_set_request_data(pending, 0, req);
143 tcore_pending_set_response_callback(pending, callback, NULL);
144 tcore_pending_link_user_request(pending, NULL); /* set user request to NULL - this is internal request */
145 ret = tcore_hal_send_request(hal, pending);
146 if (ret != TCORE_RETURN_SUCCESS) {
147 err("error: [0x%x]", ret);
148 tcore_pending_free(pending);
149 tcore_at_request_free(req);
155 static enum tcore_response_command _find_resp_command(UserRequest *ur)
157 enum tcore_request_command command;
159 command = tcore_user_request_get_command(ur);
161 case TREQ_SIM_VERIFY_PINS:
162 return TRESP_SIM_VERIFY_PINS;
165 case TREQ_SIM_VERIFY_PUKS:
166 return TRESP_SIM_VERIFY_PUKS;
169 case TREQ_SIM_CHANGE_PINS:
170 return TRESP_SIM_CHANGE_PINS;
173 case TREQ_SIM_GET_FACILITY_STATUS:
174 return TRESP_SIM_GET_FACILITY_STATUS;
177 case TREQ_SIM_DISABLE_FACILITY:
178 return TRESP_SIM_DISABLE_FACILITY;
181 case TREQ_SIM_ENABLE_FACILITY:
182 return TRESP_SIM_ENABLE_FACILITY;
185 case TREQ_SIM_GET_LOCK_INFO:
186 return TRESP_SIM_GET_LOCK_INFO;
189 case TREQ_SIM_TRANSMIT_APDU:
190 return TRESP_SIM_TRANSMIT_APDU;
193 case TREQ_SIM_GET_ATR:
194 return TRESP_SIM_GET_ATR;
197 case TREQ_SIM_GET_ECC:
198 return TRESP_SIM_GET_ECC;
201 case TREQ_SIM_GET_LANGUAGE:
202 return TRESP_SIM_GET_LANGUAGE;
205 case TREQ_SIM_SET_LANGUAGE:
206 return TRESP_SIM_SET_LANGUAGE;
209 case TREQ_SIM_GET_ICCID:
210 return TRESP_SIM_GET_ICCID;
213 case TREQ_SIM_GET_MAILBOX:
214 return TRESP_SIM_GET_MAILBOX;
217 case TREQ_SIM_SET_MAILBOX:
218 return TRESP_SIM_SET_MAILBOX;
221 case TREQ_SIM_GET_CALLFORWARDING:
222 return TRESP_SIM_GET_CALLFORWARDING;
225 case TREQ_SIM_SET_CALLFORWARDING:
226 return TRESP_SIM_SET_CALLFORWARDING;
229 case TREQ_SIM_GET_MESSAGEWAITING:
230 return TRESP_SIM_GET_MESSAGEWAITING;
233 case TREQ_SIM_SET_MESSAGEWAITING:
234 return TRESP_SIM_SET_MESSAGEWAITING;
237 case TREQ_SIM_GET_CPHS_INFO:
238 return TRESP_SIM_GET_CPHS_INFO;
241 case TREQ_SIM_GET_MSISDN:
242 return TRESP_SIM_GET_MSISDN;
245 case TREQ_SIM_GET_SPN:
246 return TRESP_SIM_GET_SPN;
249 case TREQ_SIM_GET_SPDI:
250 return TRESP_SIM_GET_SPDI;
253 case TREQ_SIM_GET_OPL:
254 return TRESP_SIM_GET_OPL;
257 case TREQ_SIM_GET_PNN:
258 return TRESP_SIM_GET_PNN;
261 case TREQ_SIM_GET_CPHS_NETNAME:
262 return TRESP_SIM_GET_CPHS_NETNAME;
265 case TREQ_SIM_GET_OPLMNWACT:
266 return TRESP_SIM_GET_OPLMNWACT;
269 case TREQ_SIM_REQ_AUTHENTICATION:
270 return TRESP_SIM_REQ_AUTHENTICATION;
273 case TREQ_SIM_GET_SERVICE_TABLE:
274 return TRESP_SIM_GET_SERVICE_TABLE;
280 return TRESP_UNKNOWN;
283 static int _sim_get_current_pin_facility(enum imc_sim_sec_op_e op)
287 dbg("current sec_op[%d]", op);
290 case SEC_PIN1_VERIFY:
291 case SEC_PIN1_CHANGE:
292 ret_type = SIM_PTYPE_PIN1;
295 case SEC_PIN2_VERIFY:
296 case SEC_PIN2_CHANGE:
297 ret_type = SIM_PTYPE_PIN2;
300 case SEC_PUK1_VERIFY:
301 ret_type = SIM_PTYPE_PUK1;
304 case SEC_PUK2_VERIFY:
305 ret_type = SIM_PTYPE_PUK2;
309 ret_type = SIM_PTYPE_SIM;
313 ret_type = SIM_PTYPE_ADM;
316 case SEC_PIN1_ENABLE:
317 case SEC_PIN1_DISABLE:
318 case SEC_PIN1_STATUS:
319 ret_type = SIM_FACILITY_SC;
323 case SEC_SIM_DISABLE:
325 ret_type = SIM_FACILITY_PS;
329 case SEC_NET_DISABLE:
331 ret_type = SIM_FACILITY_PN;
337 ret_type = SIM_FACILITY_PU;
343 ret_type = SIM_FACILITY_PP;
349 ret_type = SIM_FACILITY_PC;
353 case SEC_FDN_DISABLE:
355 ret_type = SIM_FACILITY_FD;
359 dbg("not handled current sec op[%d]", op);
365 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
367 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
369 if (status_word1 == 0x93 && status_word2 == 0x00) {
370 rst = SIM_ACCESS_FAILED;
371 /*Failed SIM request command*/
372 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
373 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
374 rst = SIM_ACCESS_FAILED;
375 /*Failed SIM request command*/
376 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
377 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
378 rst = SIM_ACCESS_FAILED;
379 /*Failed SIM request command*/
380 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
381 status_word1, status_word2);
382 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
383 rst = SIM_ACCESS_FILE_NOT_FOUND;
384 /*Failed SIM request command*/
385 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
386 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
387 rst = SIM_ACCESS_FAILED; /* MOdem not support */
388 /*Failed SIM request command*/
389 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
390 status_word1, status_word2);
391 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
392 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
393 /*Failed SIM request command*/
394 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
395 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
396 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
397 /*Failed SIM request command*/
398 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
399 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
400 status_word1, status_word2);
401 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
402 status_word1, status_word2);
403 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
404 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
405 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
406 /*Failed SIM request command*/
407 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
408 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
409 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
410 /*Failed SIM request command*/
411 dbg("error - Contradiction with invalidation status [%x][%x]",
412 status_word1, status_word2);
413 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
414 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
415 /*Failed SIM request command*/
416 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
417 status_word1, status_word2);
418 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
419 status_word1, status_word2);
420 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
421 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
422 rst = SIM_ACCESS_FAILED;
423 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
424 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
425 rst = SIM_ACCESS_FAILED;
426 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
427 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
428 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
429 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
430 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
431 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
432 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
433 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
434 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
435 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
436 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
437 rst = SIM_ACCESS_FAILED;
438 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
439 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
440 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
441 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
442 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
443 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
444 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
446 rst = SIM_ACCESS_CARD_ERROR;
447 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
453 static gboolean _sim_check_identity(CoreObject *co_sim, struct tel_sim_imsi *imsi)
455 gboolean is_changed = TRUE;
456 char new_imsi[16 + 1]; /* IMSI is 15 digit, but for distingushing between plmn and msin, define as 16 bytes. */
457 char *imsi_buf = NULL;
466 memset(new_imsi, 0x5F, 16);
467 memcpy(new_imsi, imsi->plmn, strlen(imsi->plmn));
468 memcpy(&new_imsi[6], imsi->msin, strlen(imsi->msin));
469 new_imsi[6 + strlen(imsi->msin)] = '\0';
471 ret_val = ssa_get(SIM_SSM_FILE_IMSI1, &imsi_buf, SIM_SSM_GROUP_ID, NULL);
472 if (ret_val >= 0 && imsi_buf != NULL) {
473 if (strncmp(imsi_buf, new_imsi, 16) == 0)
481 ret_val = ssa_put(SIM_SSM_FILE_IMSI1, new_imsi, strlen(new_imsi) + 1, SIM_SSM_GROUP_ID, NULL);
483 err("ssa_put failed. ret_val=[%d]", ret_val);
486 /* Update sim identification */
487 tcore_sim_set_identification(co_sim, is_changed);
492 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
493 char *encoded_data, unsigned int encoded_len, int rec_index)
495 TcoreHal *hal = NULL;
496 TcoreATRequest *req = NULL;
497 TcorePending *pending = NULL;
498 char *cmd_str = NULL;
499 struct imc_sim_property *meta_info = NULL;
507 hal = tcore_object_get_hal(o);
508 pending = tcore_pending_new(o, 0);
510 err("Pending is NULL");
511 return TCORE_RETURN_FAILURE;
513 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
515 meta_info->file_id = ef;
516 dbg("File ID: [0x%x]", meta_info->file_id);
519 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
522 case SIM_EF_CPHS_VOICE_MSG_WAITING:
529 case SIM_EF_USIM_CFIS:
530 case SIM_EF_USIM_MWIS:
531 case SIM_EF_CPHS_MAILBOX_NUMBERS:
533 case SIM_EF_USIM_MBI:
541 err("Unhandled File ID[0x%04x]", ef);
542 tcore_pending_free(pending);
543 return TCORE_RETURN_EINVAL;
546 cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d, \"%s\"", cmd, ef, p1, p2, p3, encoded_data);
548 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
550 tcore_pending_free(pending);
552 return TCORE_RETURN_FAILURE;
556 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
557 req->cmd, req->prefix, strlen(req->cmd));
559 tcore_pending_set_request_data(pending, 0, req);
560 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
561 tcore_pending_link_user_request(pending, ur);
562 tcore_hal_send_request(hal, pending);
569 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
571 struct imc_sim_property *meta_info = NULL;
572 TReturn ret_code = TCORE_RETURN_FAILURE;
574 enum tcore_request_command command;
576 char *encoded_data = NULL;
582 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
583 return TCORE_RETURN_EINVAL;
585 command = tcore_user_request_get_command(ur);
586 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
589 case TREQ_SIM_SET_LANGUAGE: {
590 const struct treq_sim_set_language *lang = NULL;
591 struct tel_sim_language language = {0, };
593 lang = tcore_user_request_ref_data(ur, NULL);
594 language.language_count = 1;
595 language.language[0] = lang->language;
596 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP) {
597 dbg("Encoding EF-LP, language[%d]", lang->language);
598 tmp = tcore_sim_encode_lp(&encoded_len, &language);
600 dbg("Encoding EF-ELP, language[%d]", lang->language);
601 tmp = tcore_sim_encode_li(&encoded_len, &language);
606 case TREQ_SIM_SET_CALLFORWARDING: {
607 const struct treq_sim_set_callforwarding *cf = NULL;
609 cf = tcore_user_request_ref_data(ur, NULL);
610 if (ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
612 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cf->cphs_cf, meta_info->data_size);
614 /* Convert 3GPP data to CPHS data */
615 struct tel_sim_cphs_cf cphs_cf;
617 dbg("Convert 3GPP data to CPHS data");
618 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
619 if (cf->cf.cfu_status & 0x01)
620 cphs_cf.b_line1 = TRUE;
622 if (cf->cf.cfu_status & 0x02)
623 cphs_cf.b_fax = TRUE;
625 if (cf->cf.cfu_status & 0x04)
626 cphs_cf.b_data = TRUE;
628 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cphs_cf, meta_info->data_size);
632 encoded_len = strlen(tmp);
634 err("NULL Encoding Data[%p].. No Updating EF", tmp);
637 } else if (ef == SIM_EF_USIM_CFIS) {
638 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis *)&cf->cf);
639 rec_index = cf->cf.rec_index;
641 err("Invalid File ID[0x%04x]", ef);
647 case TREQ_SIM_SET_MESSAGEWAITING: {
648 const struct treq_sim_set_messagewaiting *mw = NULL;
650 mw = tcore_user_request_ref_data(ur, NULL);
651 if (ef == SIM_EF_CPHS_VOICE_MSG_WAITING) {
653 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&mw->cphs_mw, meta_info->data_size);
655 /* Convert 3GPP data to CPHS data */
656 struct tel_sim_cphs_mw cphs_mw;
658 dbg("Convert 3GPP data to CPHS data");
659 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
661 if (mw->mw.indicator_status & 0x01)
662 cphs_mw.b_voice1 = TRUE;
664 if (mw->mw.indicator_status & 0x02)
665 cphs_mw.b_fax = TRUE;
667 if (mw->mw.indicator_status & 0x04)
668 cphs_mw.b_data = TRUE;
670 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&cphs_mw, meta_info->data_size);
672 } else if (ef == SIM_EF_USIM_MWIS) {
673 tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw *)&mw->mw, meta_info->rec_length);
674 rec_index = mw->mw.rec_index;
676 encoded_len = meta_info->rec_length;
678 err("Invalid File ID[0x%04x]", ef);
684 case TREQ_SIM_SET_MAILBOX: {
685 const struct treq_sim_set_mailbox *mb = NULL;
687 mb = tcore_user_request_ref_data(ur, NULL);
688 if (ef == SIM_EF_USIM_MBI) {
689 gboolean mbi_changed = FALSE;
690 struct tel_sim_mbi mbi;
693 meta_info->current_index++;
694 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
696 switch (mb->mb_info.mb_type) {
697 case SIM_MAILBOX_VOICE:
698 if (mbi.voice_index != mb->mb_info.rec_index) {
700 mbi.voice_index = mb->mb_info.rec_index;
704 case SIM_MAILBOX_FAX:
705 if (mbi.fax_index != mb->mb_info.rec_index) {
707 mbi.fax_index = mb->mb_info.rec_index;
711 case SIM_MAILBOX_EMAIL:
712 if (mbi.email_index != mb->mb_info.rec_index) {
714 mbi.email_index = mb->mb_info.rec_index;
718 case SIM_MAILBOX_OTHER:
719 if (mbi.other_index != mb->mb_info.rec_index) {
721 mbi.other_index = mb->mb_info.rec_index;
725 case SIM_MAILBOX_VIDEO:
726 if (mbi.video_index != mb->mb_info.rec_index) {
728 mbi.video_index = mb->mb_info.rec_index;
732 case SIM_MAILBOX_DATA:
737 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
738 mbi_changed, meta_info->mbi_list.profile_count,
739 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
740 } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
742 if (mbi_changed == TRUE) {
743 rec_index = meta_info->current_index;
744 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
746 encoded_len = meta_info->rec_length;
748 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
749 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
750 rec_index = mb->mb_info.rec_index;
752 encoded_len = meta_info->rec_length;
753 } else if (ef == SIM_EF_MBDN) {
754 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
755 rec_index = mb->mb_info.rec_index;
757 encoded_len = meta_info->rec_length;
759 err("Invalid File ID[0x%04x]", ef);
766 err("Unhandled update REQUEST command[%d]", command);
767 ret_code = TCORE_RETURN_EINVAL;
772 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
773 if (encoded_data == NULL) {
774 err("Memory allocation failed!!");
779 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
780 util_byte_to_hex(tmp, encoded_data, encoded_len);
783 err("Failed to Encode data");
787 dbg("Encoded Data length =[%d]", encoded_len);
788 tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
791 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
794 case SIM_EF_CPHS_VOICE_MSG_WAITING:
795 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
798 case SIM_EF_USIM_CFIS:
799 case SIM_EF_USIM_MWIS:
800 case SIM_EF_CPHS_MAILBOX_NUMBERS:
802 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
805 case SIM_EF_USIM_MBI:
807 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
809 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
813 err("Unhandled File ID[0x%04x]", ef);
814 ret_code = TCORE_RETURN_EINVAL;
827 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
829 struct tresp_sim_read resp = {0, };
830 struct imc_sim_property *meta_info = NULL;
831 enum tcore_request_command command = TREQ_UNKNOWN;
832 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
834 dbg("EF[0x%x] access Result[%d]", ef, rt);
837 memset(&resp.data, 0x00, sizeof(resp.data));
838 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
839 command = tcore_user_request_get_command(ur);
840 sim_type = tcore_sim_get_type(o);
842 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
843 && (rt != SIM_ACCESS_SUCCESS)) {
844 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
850 if (rt == SIM_ACCESS_SUCCESS) {
851 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
852 if (command == TREQ_SIM_SET_LANGUAGE)
853 __set_file_data(o, ur, ef);
855 _get_file_data(o, ur, ef, 0, meta_info->data_size);
857 if (sim_type == SIM_TYPE_GSM) {
858 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
859 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
860 _get_file_info(o, ur, SIM_EF_LP);
861 } else if (sim_type == SIM_TYPE_USIM) {
863 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05), EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
864 /* EFELPand EFLI not present at this point. */
865 /* po->language.lang_cnt = 0;*/
866 tcore_user_request_send_response(ur, _find_resp_command(ur),
867 sizeof(struct tresp_sim_read), &resp);
873 case SIM_EF_LP: /* same with SIM_EF_USIM_LI */
874 if (rt == SIM_ACCESS_SUCCESS) {
875 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
876 if (command == TREQ_SIM_SET_LANGUAGE)
877 __set_file_data(o, ur, ef);
879 _get_file_data(o, ur, ef, 0, meta_info->data_size);
881 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
883 if (sim_type == SIM_TYPE_GSM) {
884 tcore_user_request_send_response(ur, _find_resp_command(ur),
885 sizeof(struct tresp_sim_read), &resp);
888 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
889 else if (sim_type == SIM_TYPE_USIM) {
890 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
891 _get_file_info(o, ur, SIM_EF_ELP);
897 if (rt == SIM_ACCESS_SUCCESS) {
898 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
899 if (command == TREQ_SIM_SET_LANGUAGE)
900 __set_file_data(o, ur, ef);
902 _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
904 /* EFELIand EFPL not present, so set language count as zero and select ECC */
905 dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
906 tcore_user_request_send_response(ur, _find_resp_command(ur),
907 sizeof(struct tresp_sim_read), &resp);
913 if (sim_type == SIM_TYPE_GSM) {
914 _get_file_data(o, ur, ef, 0, meta_info->data_size);
915 } else if (sim_type == SIM_TYPE_USIM) {
916 if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX)
917 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
919 meta_info->current_index++;
920 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
929 case SIM_EF_CPHS_VOICE_MSG_WAITING:
930 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
931 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
932 case SIM_EF_CPHS_DYNAMICFLAGS:
933 case SIM_EF_CPHS_DYNAMIC2FLAG:
934 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
935 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
936 case SIM_EF_OPLMN_ACT:
937 _get_file_data(o, ur, ef, 0, meta_info->data_size);
940 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
941 if (command == TREQ_SIM_SET_CALLFORWARDING)
942 __set_file_data(o, ur, ef);
944 _get_file_data(o, ur, ef, 0, meta_info->data_size);
947 case SIM_EF_CPHS_CPHS_INFO:
948 if (rt == SIM_ACCESS_SUCCESS) {
949 tcore_sim_set_cphs_status(o, TRUE);
950 if (!tcore_user_request_ref_communicator(ur)) {
951 dbg("internal CPHS INFO request before sim status update");
952 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
954 dbg("external CPHS INFO request");
955 _get_file_data(o, ur, ef, 0, meta_info->data_size);
958 tcore_sim_set_cphs_status(o, FALSE);
959 if (!tcore_user_request_ref_communicator(ur)) {
960 dbg("internal CPHS INFO request before sim status update");
961 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
963 dbg("external CPHS INFO request");
964 tcore_user_request_send_response(ur, _find_resp_command(ur),
965 sizeof(struct tresp_sim_read), &resp);
970 case SIM_EF_USIM_CFIS:
971 if (command == TREQ_SIM_SET_CALLFORWARDING) {
972 __set_file_data(o, ur, ef);
974 if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX)
975 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
977 meta_info->current_index++;
978 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
982 case SIM_EF_USIM_MWIS:
983 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
984 __set_file_data(o, ur, ef);
986 meta_info->current_index++;
987 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
991 case SIM_EF_USIM_MBI:
992 if (command == TREQ_SIM_SET_MAILBOX) {
993 __set_file_data(o, ur, ef);
995 meta_info->current_index++;
996 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1002 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1004 meta_info->current_index++;
1005 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1009 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1010 if (command == TREQ_SIM_SET_MAILBOX) {
1011 /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1012 if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1013 err("Cyclic File ID. No update & return error.");
1014 meta_info->files.result = SIM_ACCESS_FAILED;
1015 tcore_user_request_send_response(ur, _find_resp_command(ur),
1016 sizeof(struct tresp_sim_read), &meta_info->files);
1019 __set_file_data(o, ur, ef);
1023 meta_info->mb_count = 0;
1024 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1025 if (meta_info->current_index == 0) {
1026 err("Invalid MBDN index");
1027 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1028 tcore_user_request_send_response(ur, _find_resp_command(ur),
1029 sizeof(struct tresp_sim_read), &meta_info->files);
1031 ur = tcore_user_request_ref(ur);
1032 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1034 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1039 dbg("error - File id for get file info [0x%x]", ef);
1044 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1046 struct imc_sim_property *meta_info = NULL;
1050 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1051 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1052 switch (meta_info->file_id) {
1054 case SIM_EF_USIM_PL:
1056 case SIM_EF_USIM_LI:
1057 if (decode_ret == TRUE) {
1059 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1060 /* po->language_file = SIM_EF_LP;*/
1061 else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL)
1062 /* po->language_file = SIM_EF_ELP;*/
1064 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1067 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1068 - EFELP is not available;
1069 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1070 - the ME does not support any of the languages in EFELP.
1073 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1074 - if the EFLI has the value 'FFFF' in its highest priority position
1075 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1077 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1078 if (meta_info->file_id == SIM_EF_LP)
1079 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1081 _get_file_info(o, ur, SIM_EF_LP);
1082 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1083 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1084 _get_file_info(o, ur, SIM_EF_ELP);
1086 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1092 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1093 if (meta_info->current_index == meta_info->rec_count) {
1094 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1096 meta_info->current_index++;
1097 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1099 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1100 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1102 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1107 ur = tcore_user_request_new(NULL, NULL); /* this is for using ur metainfo set/ref functionality. */
1108 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1112 if (meta_info->current_index == meta_info->rec_count) {
1113 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1115 meta_info->current_index++;
1116 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1121 if (meta_info->current_index == meta_info->rec_count) {
1122 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1124 meta_info->current_index++;
1125 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1130 if (meta_info->current_index == meta_info->rec_count) {
1131 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1133 meta_info->current_index++;
1134 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1138 case SIM_EF_USIM_MBI:
1139 if (meta_info->current_index == meta_info->rec_count) {
1140 _get_file_info(0, ur, SIM_EF_MBDN);
1142 meta_info->current_index++;
1143 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1148 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1149 if (meta_info->mb_count == meta_info->mb_data.count) {
1150 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1151 tcore_user_request_send_response(ur, _find_resp_command(ur),
1152 sizeof(struct tresp_sim_read), &meta_info->files);
1154 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1155 if (meta_info->current_index == 0) {
1156 err("Invalid MBDN index");
1157 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1158 tcore_user_request_send_response(ur, _find_resp_command(ur),
1159 sizeof(struct tresp_sim_read), &meta_info->files);
1161 ur = tcore_user_request_ref(ur);
1162 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1167 case SIM_EF_USIM_CFIS:
1168 case SIM_EF_USIM_MWIS:
1169 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1170 if (meta_info->current_index == meta_info->rec_count) {
1171 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1173 meta_info->current_index++;
1174 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1178 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1179 meta_info->files.result = rt;
1180 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1183 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1184 if (rt == SIM_ACCESS_SUCCESS)
1185 meta_info->files.result = SIM_ACCESS_SUCCESS;
1187 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1194 case SIM_EF_OPLMN_ACT:
1195 case SIM_EF_CPHS_CPHS_INFO:
1196 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1197 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1198 case SIM_EF_CPHS_DYNAMICFLAGS:
1199 case SIM_EF_CPHS_DYNAMIC2FLAG:
1200 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1201 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1202 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1206 dbg("File id not handled [0x%x]", meta_info->file_id);
1211 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1213 struct tnoti_sim_status noti_data = {0, };
1215 if (sim_status != tcore_sim_get_status(o)) {
1216 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1217 tcore_sim_get_status(o), sim_status);
1219 /* Update SIM Status */
1220 tcore_sim_set_status(o, sim_status);
1221 noti_data.sim_status = sim_status;
1223 /* Send notification */
1224 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1225 o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
1229 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1231 const TcoreATResponse *resp = data;
1232 UserRequest *ur = NULL;
1233 CoreObject *o = NULL;
1234 GSList *tokens = NULL;
1235 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1241 o = tcore_pending_ref_core_object(p);
1242 ur = tcore_pending_ref_user_request(p);
1244 if (resp->success > 0) {
1247 line = (const char *)resp->lines->data;
1248 tokens = tcore_at_tok_new(line);
1249 if (g_slist_length(tokens) != 1) {
1250 msg("Invalid message");
1251 tcore_at_tok_free(tokens);
1255 state = atoi(g_slist_nth_data(tokens, 0));
1256 dbg("SIM Type is %d", state);
1259 sim_type = SIM_TYPE_GSM;
1260 tcore_sim_set_app_list(o, SIM_APP_TYPE_SIM);
1261 } else if (state == 1) {
1262 sim_type = SIM_TYPE_USIM;
1263 tcore_sim_set_app_list(o, SIM_APP_TYPE_USIM);
1265 sim_type = SIM_TYPE_UNKNOWN;
1268 dbg("RESPONSE NOK");
1269 sim_type = SIM_TYPE_UNKNOWN;
1272 tcore_sim_set_type(o, sim_type);
1274 if (sim_type != SIM_TYPE_UNKNOWN) {
1275 /* set user request for using ur metainfo set/ref functionality */
1276 ur = tcore_user_request_new(NULL, NULL);
1277 _get_file_info(o, ur, SIM_EF_IMSI);
1280 tcore_at_tok_free(tokens);
1284 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1286 const TcoreATResponse *resp = data;
1287 UserRequest *ur = NULL;
1288 CoreObject *o = NULL;
1289 struct imc_sim_property *meta_info = NULL;
1290 GSList *tokens = NULL;
1291 enum tel_sim_access_result rt;
1292 const char *line = NULL;
1298 o = tcore_pending_ref_core_object(p);
1299 ur = tcore_pending_ref_user_request(p);
1300 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1302 if (resp->success > 0) {
1305 line = (const char *)resp->lines->data;
1306 tokens = tcore_at_tok_new(line);
1307 if (g_slist_length(tokens) < 2) {
1308 err("Invalid message");
1309 tcore_at_tok_free(tokens);
1313 sw1 = atoi(g_slist_nth_data(tokens, 0));
1314 sw2 = atoi(g_slist_nth_data(tokens, 1));
1316 /*1. SIM access success case*/
1317 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1318 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1319 unsigned short record_len = 0;
1320 char num_of_records = 0;
1321 unsigned char file_id_len = 0;
1322 unsigned short file_id = 0;
1323 unsigned short file_size = 0;
1324 unsigned short file_type = 0;
1325 unsigned short arr_file_id = 0;
1327 /* handling only last 3 bits */
1328 unsigned char file_type_tag = 0x07;
1329 unsigned char *ptr_data;
1333 char *recordData = NULL;
1334 hexData = g_slist_nth_data(tokens, 2);
1335 dbg("hexData: %s", hexData);
1336 dbg("hexData: %s", hexData + 1);
1338 tmp = tcore_at_tok_extract(hexData);
1339 recordData = util_hexStringToBytes(tmp);
1341 err("util_hexStringToBytes Failed!!");
1342 tcore_at_tok_free(tokens);
1345 tcore_util_hex_dump(" ", strlen(hexData) / 2, recordData);
1348 ptr_data = (unsigned char *)recordData;
1349 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1351 ETSI TS 102 221 v7.9.0
1353 '62' FCP template tag
1354 - Response for an EF
1355 '82' M File Descriptor
1356 '83' M File Identifier
1357 'A5' O Proprietary information
1358 '8A' M Life Cycle Status Integer
1359 '8B', '8C' or 'AB' C1 Security attributes
1361 '81' O Total file size
1362 '88' O Short File Identifier (SFI)
1365 /* rsim.res_len has complete data length received */
1367 /* FCP template tag - File Control Parameters tag*/
1368 if (*ptr_data == 0x62) {
1369 /* parse complete FCP tag*/
1370 /* increment to next byte */
1372 tag_len = *ptr_data++;
1373 dbg("tag_len: %02x", tag_len);
1374 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1375 if (*ptr_data == 0x82) {
1376 /* increment to next byte */
1380 /* unsigned char file_desc_len = *ptr_data++;*/
1381 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1382 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1383 /* consider only last 3 bits*/
1384 dbg("file_type_tag: %02x", file_type_tag);
1385 file_type_tag = file_type_tag & (*ptr_data);
1386 dbg("file_type_tag: %02x", file_type_tag);
1388 switch (file_type_tag) {
1389 /* increment to next byte */
1391 dbg("Getting FileType: [Transparent file type]");
1392 file_type = SIM_FTYPE_TRANSPARENT;
1394 /* increment to next byte */
1396 /* increment to next byte */
1401 dbg("Getting FileType: [Linear fixed file type]");
1402 /* increment to next byte */
1404 /* data coding byte - value 21 */
1407 memcpy(&record_len, ptr_data, 2);
1409 SWAPBYTES16(record_len);
1410 ptr_data = ptr_data + 2;
1411 num_of_records = *ptr_data++;
1412 /* Data lossy conversation from enum (int) to unsigned char */
1413 file_type = SIM_FTYPE_LINEAR_FIXED;
1417 dbg("Cyclic fixed file type");
1418 /* increment to next byte */
1420 /* data coding byte - value 21 */
1423 memcpy(&record_len, ptr_data, 2);
1425 SWAPBYTES16(record_len);
1426 ptr_data = ptr_data + 2;
1427 num_of_records = *ptr_data++;
1428 file_type = SIM_FTYPE_CYCLIC;
1432 dbg("not handled file type [0x%x]", *ptr_data);
1436 dbg("INVALID FCP received - DEbug!");
1437 tcore_at_tok_free(tokens);
1443 * File identifier - file id??
1445 * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1447 if (*ptr_data == 0x83) {
1448 /* increment to next byte */
1450 file_id_len = *ptr_data++;
1451 dbg("file_id_len: %02x", file_id_len);
1453 memcpy(&file_id, ptr_data, file_id_len);
1454 dbg("file_id: %x", file_id);
1457 SWAPBYTES16(file_id);
1458 dbg("file_id: %x", file_id);
1460 ptr_data = ptr_data + 2;
1461 dbg("Getting FileID=[0x%x]", file_id);
1463 dbg("INVALID FCP received - DEbug!");
1464 tcore_at_tok_free(tokens);
1469 /* proprietary information */
1470 if (*ptr_data == 0xA5) {
1471 unsigned short prop_len;
1472 /* increment to next byte */
1476 prop_len = *ptr_data;
1477 dbg("prop_len: %02x", prop_len);
1480 ptr_data = ptr_data + prop_len + 1;
1482 dbg("INVALID FCP received - DEbug!");
1485 /* life cycle status integer [8A][length:0x01][status]*/
1488 00000000 : No information given
1489 00000001 : creation state
1490 00000011 : initialization state
1491 000001-1 : operation state -activated
1492 000001-0 : operation state -deactivated
1493 000011-- : Termination state
1494 b8~b5 !=0, b4~b1=X : Proprietary
1495 Any other value : RFU
1497 if (*ptr_data == 0x8A) {
1498 /* increment to next byte */
1500 /* length - value 1 */
1503 switch (*ptr_data) {
1506 dbg("<RX> operation state -deactivated");
1512 dbg("<RX> operation state -activated");
1517 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1523 /* related to security attributes : currently not handled*/
1524 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1525 /* increment to next byte */
1527 /* if tag length is 3 */
1528 if (*ptr_data == 0x03) {
1529 /* increment to next byte */
1532 memcpy(&arr_file_id, ptr_data, 2);
1534 SWAPBYTES16(arr_file_id);
1535 ptr_data = ptr_data + 2;
1536 ptr_data++; /*arr_file_id_rec_num = *ptr_data++; */
1538 /* if tag length is not 3 */
1539 /* ignoring bytes */
1540 dbg("Useless security attributes, so jump to next tag");
1541 ptr_data = ptr_data + (*ptr_data + 1);
1544 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1545 tcore_at_tok_free(tokens);
1550 dbg("Current ptr_data value is [%x]", *ptr_data);
1552 /* file size excluding structural info*/
1553 if (*ptr_data == 0x80) {
1554 /* for EF file size is body of file and for Linear or cyclic it is
1555 * number of recXsizeof(one record)
1557 /* increment to next byte */
1559 /* length is 1 byte - value is 2 bytes or more */
1561 memcpy(&file_size, ptr_data, 2);
1563 SWAPBYTES16(file_size);
1564 ptr_data = ptr_data + 2;
1566 dbg("INVALID FCP received - DEbug!");
1567 tcore_at_tok_free(tokens);
1572 /* total file size including structural info*/
1573 if (*ptr_data == 0x81) {
1575 /* increment to next byte */
1578 /* len = *ptr_data; */
1580 ptr_data = ptr_data + 3;
1582 dbg("INVALID FCP received - DEbug!");
1583 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1586 /*short file identifier ignored*/
1587 if (*ptr_data == 0x88) {
1588 dbg("0x88: Do Nothing");
1592 dbg("INVALID FCP received - DEbug!");
1593 tcore_at_tok_free(tokens);
1597 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1598 unsigned char gsm_specific_file_data_len = 0;
1599 /* ignore RFU byte1 and byte2 */
1603 memcpy(&file_size, ptr_data, 2);
1605 SWAPBYTES16(file_size);
1606 /* parsed file size */
1607 ptr_data = ptr_data + 2;
1609 memcpy(&file_id, ptr_data, 2);
1610 SWAPBYTES16(file_id);
1611 dbg("FILE id --> [%x]", file_id);
1612 ptr_data = ptr_data + 2;
1613 /* save file type - transparent, linear fixed or cyclic */
1614 file_type_tag = (*(ptr_data + 7));
1616 switch (*ptr_data) {
1619 dbg("RFU file type- not handled - Debug!");
1624 dbg("MF file type - not handled - Debug!");
1629 dbg("DF file type - not handled - Debug!");
1634 dbg("EF file type [%d] ", file_type_tag);
1635 /* increment to next byte */
1638 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1639 /* increament to next byte as this byte is RFU */
1642 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1644 /* increment to next byte */
1646 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1647 /* the INCREASE command is allowed on the selected cyclic file. */
1648 file_type = SIM_FTYPE_CYCLIC;
1650 /* bytes 9 to 11 give SIM file access conditions */
1652 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1654 /* byte 11 is invalidate and rehabilate nibbles */
1656 /* byte 12 - file status */
1658 /* byte 13 - GSM specific data */
1659 gsm_specific_file_data_len = *ptr_data;
1660 dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1662 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1664 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1665 record_len = *ptr_data;
1666 dbg("record length[%d], file size[%d]", record_len, file_size);
1668 if (record_len != 0)
1669 num_of_records = (file_size / record_len);
1671 dbg("Number of records [%d]", num_of_records);
1675 dbg("not handled file type");
1679 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1682 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1683 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1685 meta_info->file_type = file_type;
1686 meta_info->data_size = file_size;
1687 meta_info->rec_length = record_len;
1688 meta_info->rec_count = num_of_records;
1689 meta_info->current_index = 0; /* reset for new record type EF */
1690 rt = SIM_ACCESS_SUCCESS;
1693 /*2. SIM access fail case*/
1694 dbg("error to get ef[0x%x]", meta_info->file_id);
1695 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1696 rt = _decode_status_word(sw1, sw2);
1698 ur = tcore_user_request_ref(ur);
1700 dbg("Calling _next_from_get_file_info");
1701 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1702 tcore_at_tok_free(tokens);
1704 dbg("RESPONSE NOK");
1705 dbg("error to get ef[0x%x]", meta_info->file_id);
1706 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1707 rt = SIM_ACCESS_FAILED;
1709 ur = tcore_user_request_ref(ur);
1710 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1715 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1717 const TcoreATResponse *resp = data;
1718 UserRequest *ur = NULL;
1719 CoreObject *o = NULL;
1720 struct imc_sim_property *meta_info = NULL;
1721 GSList *tokens = NULL;
1722 enum tel_sim_access_result rt;
1723 gboolean dr = FALSE;
1724 const char *line = NULL;
1733 o = tcore_pending_ref_core_object(p);
1734 ur = tcore_pending_ref_user_request(p);
1735 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1737 if (resp->success > 0) {
1740 line = (const char *)resp->lines->data;
1741 tokens = tcore_at_tok_new(line);
1742 if (g_slist_length(tokens) != 3) {
1743 msg("Invalid message");
1744 tcore_at_tok_free(tokens);
1748 sw1 = atoi(g_slist_nth_data(tokens, 0));
1749 sw2 = atoi(g_slist_nth_data(tokens, 1));
1750 res = g_slist_nth_data(tokens, 2);
1752 tmp = tcore_at_tok_extract(res);
1755 res = util_hexStringToBytes(tmp);
1756 res_len = strlen(tmp) / 2;
1757 dbg("Response: [%s] Response length: [%d]", res, res_len);
1759 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1760 rt = SIM_ACCESS_SUCCESS;
1761 meta_info->files.result = rt;
1763 dbg("File ID: [0x%x]", meta_info->file_id);
1764 switch (meta_info->file_id) {
1767 struct tel_sim_imsi *imsi = NULL;
1769 dbg("Data: [%s]", res);
1770 imsi = g_try_new0(struct tel_sim_imsi, 1);
1771 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1773 err("IMSI decoding failed");
1775 //_sim_check_identity(o, imsi);
1776 tcore_sim_set_imsi(o, imsi);
1785 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1788 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1789 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1790 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1791 case SIM_EF_LP: /* 1 byte encoding */
1792 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1793 && (meta_info->file_id == SIM_EF_LP)) {
1795 * 2G LP(0x6F05) has 1 byte for each language
1797 dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1798 (unsigned char *)res, res_len);
1801 * 3G LI(0x6F05)/PL(0x2F05),
1802 * 2G ELP(0x2F05) has 2 bytes for each language
1804 dr = tcore_sim_decode_li(meta_info->file_id,
1805 &meta_info->files.data.language,
1806 (unsigned char *)res, res_len);
1811 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1812 (unsigned char *)res, res_len);
1816 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1817 (unsigned char *)res, res_len);
1820 case SIM_EF_SST: /* EF UST has same address */
1822 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1823 dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1825 dbg("SST decoding failed");
1826 tcore_sim_set_service_table(o, NULL);
1828 int i = 0, size = sizeof(struct tel_sim_sst);
1830 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1831 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1832 memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1833 for (i = 0; i < size; i++) {
1839 dbg("svct.table.sst=[%s]", temp);
1842 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1844 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1845 dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1847 dbg("SST decoding failed");
1848 tcore_sim_set_service_table(o, NULL);
1850 int i = 0, size = sizeof(struct tel_sim_ust);
1852 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1853 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1854 memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1855 for (i = 0; i < size; i++) {
1861 dbg("svct.table.ust=[%s]", temp);
1864 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1867 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(o));
1874 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1875 dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1876 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1877 struct tel_sim_ecc *ecc = NULL;
1879 ecc = g_try_new0(struct tel_sim_ecc, 1);
1880 dbg("Index [%d]", meta_info->current_index);
1882 dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1884 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1885 meta_info->files.data.ecc.ecc_count++;
1891 dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1898 struct tel_sim_msisdn *msisdn = NULL;
1900 dbg("Index [%d]", meta_info->current_index);
1901 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1902 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1904 memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1905 msisdn, sizeof(struct tel_sim_msisdn));
1907 meta_info->files.data.msisdn_list.count++;
1917 struct tel_sim_opl *opl = NULL;
1919 dbg("decode w/ index [%d]", meta_info->current_index);
1921 opl = g_try_new0(struct tel_sim_opl, 1);
1922 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1924 memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1925 opl, sizeof(struct tel_sim_opl));
1926 meta_info->files.data.opl.opl_count++;
1936 struct tel_sim_pnn *pnn = NULL;
1938 dbg("decode w/ index [%d]", meta_info->current_index);
1940 pnn = g_try_new0(struct tel_sim_pnn, 1);
1941 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1943 memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1944 pnn, sizeof(struct tel_sim_pnn));
1946 meta_info->files.data.pnn.pnn_count++;
1954 case SIM_EF_OPLMN_ACT:
1955 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1956 (unsigned char *)res, res_len);
1959 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1960 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1963 case SIM_EF_USIM_MBI: /* linear type */
1965 struct tel_sim_mbi *mbi = NULL;
1967 mbi = g_try_new0(struct tel_sim_mbi, 1);
1968 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
1970 memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
1971 mbi, sizeof(struct tel_sim_mbi));
1972 meta_info->mbi_list.profile_count++;
1974 dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
1975 dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].voice_index);
1976 dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].fax_index);
1977 dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].email_index);
1978 dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].other_index);
1979 dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].video_index);
1987 case SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1988 case SIM_EF_MBDN: /* linear type */
1989 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
1990 (unsigned char *)res, res_len);
1991 meta_info->mb_count++;
1994 case SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1995 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
1996 (unsigned char *)res, res_len);
1999 case SIM_EF_USIM_MWIS: /* linear type */
2001 struct tel_sim_mw *mw = NULL;
2003 mw = g_try_new0(struct tel_sim_mw, 1);
2005 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
2007 memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
2008 meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
2009 meta_info->files.data.mw.mw_list.profile_count++;
2017 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
2018 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2019 (unsigned char *)res, res_len);
2022 case SIM_EF_USIM_CFIS: /* linear type */
2024 struct tel_sim_cfis *cf = NULL;
2026 cf = g_try_new0(struct tel_sim_cfis, 1);
2027 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2029 memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2030 cf, sizeof(struct tel_sim_cfis));
2032 meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2033 meta_info->files.data.cf.cf_list.profile_count++;
2041 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2042 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2045 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2046 dr = tcore_sim_decode_ons((unsigned char *)&meta_info->files.data.cphs_net.full_name,
2047 (unsigned char *)res, res_len);
2048 dbg("meta_info->files.result[%d], meta_info->files.data.cphs_net.full_name[%s]",
2049 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2052 case SIM_EF_CPHS_DYNAMICFLAGS:
2053 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2054 p_data->response, p_data->response_len);*/
2057 case SIM_EF_CPHS_DYNAMIC2FLAG:
2058 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2059 p_data->response_len);*/
2062 case SIM_EF_CPHS_CPHS_INFO:
2063 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2064 (unsigned char *)res, res_len);
2067 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2068 dr = tcore_sim_decode_short_ons((unsigned char *)&meta_info->files.data.cphs_net.short_name,
2069 (unsigned char *)res, res_len);
2072 case SIM_EF_CPHS_INFORMATION_NUMBERS:
2073 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2077 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2082 rt = _decode_status_word(sw1, sw2);
2083 meta_info->files.result = rt;
2091 tcore_at_tok_free(tokens);
2093 dbg("RESPONSE NOK");
2094 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2095 rt = SIM_ACCESS_FAILED;
2098 /* Reference User Request */
2099 ur = tcore_user_request_ref(ur);
2102 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2107 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2109 const TcoreATResponse *resp = data;
2110 UserRequest *ur = NULL;
2111 CoreObject *o = NULL;
2112 struct imc_sim_property *sp = NULL;
2113 GSList *tokens = NULL;
2114 const char *line = NULL;
2116 int attempts_left = 0;
2117 int time_penalty = 0;
2121 o = tcore_pending_ref_core_object(p);
2122 sp = tcore_sim_ref_userdata(o);
2124 err("user data is null");
2127 ur = tcore_pending_ref_user_request(p);
2129 if (resp->success > 0) {
2132 line = (const char *)resp->lines->data;
2133 tokens = tcore_at_tok_new(line);
2134 if (g_slist_length(tokens) < 3) {
2135 msg("Invalid message");
2136 tcore_at_tok_free(tokens);
2140 lock_type = atoi(g_slist_nth_data(tokens, 0));
2141 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2142 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2144 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2145 lock_type, attempts_left, time_penalty);
2147 switch (sp->current_sec_op) {
2148 case SEC_PIN1_VERIFY:
2149 case SEC_PIN2_VERIFY:
2150 case SEC_SIM_VERIFY:
2151 case SEC_ADM_VERIFY:
2153 struct tresp_sim_verify_pins v_pin = {0, };
2155 v_pin.result = SIM_INCORRECT_PASSWORD;
2156 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2157 v_pin.retry_count = attempts_left;
2158 tcore_user_request_send_response(ur, _find_resp_command(ur),
2159 sizeof(struct tresp_sim_verify_pins), &v_pin);
2163 case SEC_PUK1_VERIFY:
2164 case SEC_PUK2_VERIFY:
2166 struct tresp_sim_verify_puks v_puk = {0, };
2168 v_puk.result = SIM_INCORRECT_PASSWORD;
2169 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2170 v_puk.retry_count = attempts_left;
2171 tcore_user_request_send_response(ur, _find_resp_command(ur),
2172 sizeof(struct tresp_sim_verify_puks), &v_puk);
2176 case SEC_PIN1_CHANGE:
2177 case SEC_PIN2_CHANGE:
2179 struct tresp_sim_change_pins change_pin = {0, };
2181 change_pin.result = SIM_INCORRECT_PASSWORD;
2182 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2183 change_pin.retry_count = attempts_left;
2184 tcore_user_request_send_response(ur, _find_resp_command(ur),
2185 sizeof(struct tresp_sim_change_pins), &change_pin);
2189 case SEC_PIN1_DISABLE:
2190 case SEC_PIN2_DISABLE:
2191 case SEC_FDN_DISABLE:
2192 case SEC_SIM_DISABLE:
2193 case SEC_NET_DISABLE:
2194 case SEC_NS_DISABLE:
2195 case SEC_SP_DISABLE:
2196 case SEC_CP_DISABLE:
2198 struct tresp_sim_disable_facility dis_facility = {0, };
2200 dis_facility.result = SIM_INCORRECT_PASSWORD;
2201 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2202 dis_facility.retry_count = attempts_left;
2203 tcore_user_request_send_response(ur, _find_resp_command(ur),
2204 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2208 case SEC_PIN1_ENABLE:
2209 case SEC_PIN2_ENABLE:
2210 case SEC_FDN_ENABLE:
2211 case SEC_SIM_ENABLE:
2212 case SEC_NET_ENABLE:
2217 struct tresp_sim_enable_facility en_facility = {0, };
2219 en_facility.result = SIM_INCORRECT_PASSWORD;
2220 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2221 en_facility.retry_count = attempts_left;
2222 tcore_user_request_send_response(ur, _find_resp_command(ur),
2223 sizeof(struct tresp_sim_enable_facility), &en_facility);
2228 dbg("not handled sec op[%d]", sp->current_sec_op);
2233 tcore_at_tok_free(tokens);
2239 static gboolean _get_sim_type(CoreObject *o)
2241 TcoreHal *hal = NULL;
2242 TcoreATRequest *req = NULL;
2243 TcorePending *pending = NULL;
2244 UserRequest *ur = NULL;
2245 char *cmd_str = NULL;
2249 hal = tcore_object_get_hal(o);
2250 pending = tcore_pending_new(o, 0);
2252 err("Pending is NULL");
2255 cmd_str = g_strdup_printf("AT+XUICC?");
2256 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2258 tcore_pending_free(pending);
2264 dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2265 req->cmd, req->prefix, strlen(req->cmd));
2267 tcore_pending_set_request_data(pending, 0, req);
2268 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2269 tcore_pending_link_user_request(pending, ur);
2270 tcore_hal_send_request(hal, pending);
2276 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2278 TcoreHal *hal = NULL;
2279 TcorePending *pending = NULL;
2280 struct imc_sim_property meta_info = {0, };
2281 char *cmd_str = NULL;
2282 TReturn ret = TCORE_RETURN_FAILURE;
2287 meta_info.file_id = ef;
2288 dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2289 hal = tcore_object_get_hal(o);
2290 dbg("hal: %x", hal);
2292 trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2293 dbg("trt[%d]", trt);
2294 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
2295 dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2297 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2298 tcore_pending_link_user_request(pending, ur);
2299 ret = tcore_hal_send_request(hal, pending);
2300 if (TCORE_RETURN_SUCCESS != ret)
2301 tcore_user_request_free(ur);
2305 return TCORE_RETURN_SUCCESS;
2308 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2310 TcoreHal *hal = NULL;
2311 TcoreATRequest *req = NULL;
2312 TcorePending *pending = NULL;
2313 char *cmd_str = NULL;
2319 hal = tcore_object_get_hal(o);
2320 pending = tcore_pending_new(o, 0);
2322 err("Pending is NULL");
2326 dbg("file_id: %x", ef);
2328 p1 = (unsigned char) (offset & 0xFF00) >> 8;
2329 p2 = (unsigned char) offset & 0x00FF; /* offset low */
2330 p3 = (unsigned char) length;
2332 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
2334 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2336 tcore_pending_free(pending);
2342 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2343 req->cmd, req->prefix, strlen(req->cmd));
2345 tcore_pending_set_request_data(pending, 0, req);
2346 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2347 tcore_pending_link_user_request(pending, ur);
2348 tcore_hal_send_request(hal, pending);
2354 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2356 TcoreHal *hal = NULL;
2357 TcoreATRequest *req = NULL;
2358 TcorePending *pending = NULL;
2359 char *cmd_str = NULL;
2366 hal = tcore_object_get_hal(o);
2367 pending = tcore_pending_new(o, 0);
2369 err("Pending is NULL");
2373 p1 = (unsigned char) index;
2374 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
2375 p3 = (unsigned char) length;
2377 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
2379 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2381 tcore_pending_free(pending);
2387 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2388 req->cmd, req->prefix, strlen(req->cmd));
2390 tcore_pending_set_request_data(pending, 0, req);
2391 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2392 tcore_pending_link_user_request(pending, ur);
2393 tcore_hal_send_request(hal, pending);
2399 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2401 TcoreHal *hal = NULL;
2402 TcoreATRequest *req = NULL;
2403 TcorePending *pending = NULL;
2404 char *cmd_str = NULL;
2406 struct imc_sim_property *sp = NULL;
2410 hal = tcore_object_get_hal(o);
2411 pending = tcore_pending_new(o, 0);
2413 err("Pending is NULL");
2414 return TCORE_RETURN_FAILURE;
2416 sp = tcore_sim_ref_userdata(o);
2418 err("user data is null");
2419 tcore_pending_free(pending);
2420 return TCORE_RETURN_FAILURE;
2423 switch (sp->current_sec_op) {
2424 case SEC_PIN1_VERIFY:
2425 case SEC_PIN1_CHANGE:
2426 case SEC_PIN1_ENABLE:
2427 case SEC_PIN1_DISABLE:
2431 case SEC_PIN2_VERIFY:
2432 case SEC_PIN2_CHANGE:
2433 case SEC_PIN2_ENABLE:
2434 case SEC_PIN2_DISABLE:
2435 case SEC_FDN_ENABLE:
2436 case SEC_FDN_DISABLE:
2440 case SEC_PUK1_VERIFY:
2444 case SEC_PUK2_VERIFY:
2448 case SEC_NET_ENABLE:
2449 case SEC_NET_DISABLE:
2454 case SEC_NS_DISABLE:
2459 case SEC_SP_DISABLE:
2464 case SEC_CP_DISABLE:
2468 case SEC_ADM_VERIFY:
2476 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2477 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2479 tcore_pending_free(pending);
2481 return TCORE_RETURN_FAILURE;
2485 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2486 req->cmd, req->prefix, strlen(req->cmd));
2488 tcore_pending_set_request_data(pending, 0, req);
2489 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2490 tcore_pending_link_user_request(pending, ur);
2491 tcore_hal_send_request(hal, pending);
2494 return TCORE_RETURN_SUCCESS;
2497 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2500 GSList *tokens = NULL;
2501 GSList *lines = NULL;
2503 dbg("Function entry");
2505 lines = (GSList *)event_info;
2506 if (1 != g_slist_length(lines)) {
2507 dbg("unsolicited msg but multiple line");
2510 line = (char *)(lines->data);
2511 tokens = tcore_at_tok_new(line);
2512 if (g_slist_length(tokens) != 1) {
2513 msg("Invalid message");
2514 tcore_at_tok_free(tokens);
2521 tcore_at_tok_free(tokens);
2525 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2526 unsigned int sms_ready)
2528 Server *server = tcore_plugin_ref_server(plugin);
2529 struct tnoti_sms_ready_status sms_ready_noti;
2534 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2535 if (co_sms == NULL) {
2536 err("Can't find SMS core object");
2540 if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2543 tcore_sms_set_ready_status(co_sms, sms_ready);
2545 if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2546 sms_ready_noti.status = sms_ready;
2547 tcore_server_send_notification(server, co_sms,
2548 TNOTI_SMS_DEVICE_READY,
2549 sizeof(sms_ready_noti),
2556 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2558 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2559 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2560 GSList *tokens = NULL;
2564 enum telephony_sms_ready_status sms_state = 0;
2568 lines = (GSList *)event_info;
2569 if (g_slist_length(lines) != 1) {
2570 err("Unsolicited message BUT multiple lines");
2576 /* Create 'tokens' */
2577 tokens = tcore_at_tok_new(line);
2580 if (g_slist_length(tokens) == 4) {
2581 sim_state = atoi(g_slist_nth_data(tokens, 1));
2582 sms_state = atoi(g_slist_nth_data(tokens, 3));
2584 notify_sms_state(plugin, o, sms_state);
2585 } else if (g_slist_length(tokens) == 1) {
2586 sim_state = atoi(g_slist_nth_data(tokens, 0));
2588 err("Invalid message");
2592 switch (sim_state) {
2594 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2599 sim_status = SIM_STATUS_PIN_REQUIRED;
2600 dbg("PIN REQUIRED");
2604 sim_status = SIM_STATUS_INITIALIZING;
2605 dbg("PIN DISABLED AT BOOT UP");
2609 sim_status = SIM_STATUS_INITIALIZING;
2610 dbg("PIN VERIFIED");
2614 sim_status = SIM_STATUS_PUK_REQUIRED;
2615 dbg("PUK REQUIRED");
2619 sim_status = SIM_STATUS_CARD_BLOCKED;
2620 dbg("CARD PERMANENTLY BLOCKED");
2624 sim_status = SIM_STATUS_CARD_ERROR;
2625 dbg("SIM CARD ERROR");
2629 sim_status = SIM_STATUS_INIT_COMPLETED;
2630 dbg("SIM INIT COMPLETED");
2634 sim_status = SIM_STATUS_CARD_ERROR;
2635 dbg("SIM CARD ERROR");
2639 sim_status = SIM_STATUS_CARD_REMOVED;
2644 dbg("SIM SMS Ready");
2645 notify_sms_state(plugin, o, SMS_STATE_READY);
2649 sim_status = SIM_STATUS_UNKNOWN;
2650 dbg("SIM STATE UNKNOWN");
2654 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2658 switch (sim_status) {
2659 case SIM_STATUS_INIT_COMPLETED:
2660 dbg("[SIM] SIM INIT COMPLETED");
2661 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2668 case SIM_STATUS_CARD_REMOVED:
2669 dbg("[SIM] SIM CARD REMOVED");
2670 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2673 case SIM_STATUS_CARD_NOT_PRESENT:
2674 dbg("[SIM] SIM CARD NOT PRESENT");
2675 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2678 case SIM_STATUS_CARD_ERROR:
2679 dbg("[SIM] SIM CARD ERROR");
2680 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2684 dbg("SIM Status: [0x%02x]", sim_status);
2688 _sim_status_update(o, sim_status);
2691 tcore_at_tok_free(tokens);
2697 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2699 const TcoreATResponse *resp = data;
2700 CoreObject *o = NULL;
2704 o = tcore_pending_ref_core_object(p);
2706 if (resp->success > 0) {
2709 on_event_pin_status(o, resp->lines, NULL);
2711 dbg("RESPONSE NOK");
2717 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2718 unsigned int data_len, void *data, void *user_data)
2720 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2721 CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2724 return TCORE_HOOK_RETURN_CONTINUE;
2726 dbg("Get SIM status");
2728 sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2730 return TCORE_HOOK_RETURN_CONTINUE;
2733 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2735 const TcoreATResponse *resp = data;
2736 UserRequest *ur = NULL;
2737 CoreObject *co_sim = NULL;
2738 struct imc_sim_property *sp = NULL;
2739 GSList *tokens = NULL;
2740 struct tresp_sim_verify_pins res;
2746 co_sim = tcore_pending_ref_core_object(p);
2747 sp = tcore_sim_ref_userdata(co_sim);
2749 err("user data is null");
2753 ur = tcore_pending_ref_user_request(p);
2755 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2757 if (resp->success > 0) {
2759 res.result = SIM_PIN_OPERATION_SUCCESS;
2761 /* Get PIN facility */
2762 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2763 if ((res.pin_type == SIM_PTYPE_PIN1)
2764 || (res.pin_type == SIM_PTYPE_SIM)) {
2765 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2766 /* Update SIM Status */
2767 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2772 tcore_user_request_send_response(ur, _find_resp_command(ur),
2773 sizeof(struct tresp_sim_verify_pins), &res);
2775 dbg("RESPONSE NOK");
2776 line = (const char *)resp->final_response;
2777 tokens = tcore_at_tok_new(line);
2778 if (g_slist_length(tokens) < 1) {
2779 dbg("Unkown Error OR String corrupted");
2780 res.result = TCORE_RETURN_3GPP_ERROR;
2783 tcore_user_request_send_response(ur, _find_resp_command(ur),
2784 sizeof(struct tresp_sim_verify_pins), &res);
2786 err = atoi(g_slist_nth_data(tokens, 0));
2787 dbg("Error: [%d]", err);
2789 ur = tcore_user_request_ref(ur);
2791 /* Get retry count */
2792 _get_retry_count(co_sim, ur);
2796 tcore_at_tok_free(tokens);
2802 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2804 const TcoreATResponse *resp = data;
2805 UserRequest *ur = NULL;
2806 CoreObject *co_sim = NULL;
2807 struct imc_sim_property *sp = NULL;
2808 GSList *tokens = NULL;
2809 struct tresp_sim_verify_puks res;
2815 co_sim = tcore_pending_ref_core_object(p);
2816 sp = tcore_sim_ref_userdata(co_sim);
2818 err("user data is null");
2822 ur = tcore_pending_ref_user_request(p);
2824 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2826 if (resp->success > 0) {
2828 res.result = SIM_PIN_OPERATION_SUCCESS;
2829 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2832 tcore_user_request_send_response(ur, _find_resp_command(ur),
2833 sizeof(struct tresp_sim_verify_pins), &res);
2835 dbg("RESPONSE NOK");
2836 line = (const char *)resp->final_response;
2837 tokens = tcore_at_tok_new(line);
2839 if (g_slist_length(tokens) < 1) {
2840 dbg("Unkown Error OR String corrupted");
2841 res.result = TCORE_RETURN_3GPP_ERROR;
2844 tcore_user_request_send_response(ur, _find_resp_command(ur),
2845 sizeof(struct tresp_sim_verify_pins), &res);
2847 err = atoi(g_slist_nth_data(tokens, 0));
2848 dbg("Error: [%d]", err);
2849 ur = tcore_user_request_ref(ur);
2850 _get_retry_count(co_sim, ur);
2852 tcore_at_tok_free(tokens);
2857 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2859 const TcoreATResponse *resp = data;
2860 UserRequest *ur = NULL;
2861 CoreObject *co_sim = NULL;
2862 struct imc_sim_property *sp = NULL;
2863 GSList *tokens = NULL;
2864 struct tresp_sim_change_pins res;
2870 co_sim = tcore_pending_ref_core_object(p);
2871 sp = tcore_sim_ref_userdata(co_sim);
2873 err("user data is null");
2877 ur = tcore_pending_ref_user_request(p);
2879 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2881 if (resp->success > 0) {
2883 res.result = SIM_PIN_OPERATION_SUCCESS;
2884 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2887 tcore_user_request_send_response(ur, _find_resp_command(ur),
2888 sizeof(struct tresp_sim_change_pins), &res);
2890 dbg("RESPONSE NOK");
2891 line = (const char *)resp->final_response;
2892 tokens = tcore_at_tok_new(line);
2894 if (g_slist_length(tokens) < 1) {
2895 dbg("Unkown Error OR String corrupted");
2896 res.result = TCORE_RETURN_3GPP_ERROR;
2899 tcore_user_request_send_response(ur, _find_resp_command(ur),
2900 sizeof(struct tresp_sim_change_pins), &res);
2902 err = atoi(g_slist_nth_data(tokens, 0));
2903 dbg("Error: [%d]", err);
2904 ur = tcore_user_request_ref(ur);
2905 _get_retry_count(co_sim, ur);
2909 tcore_at_tok_free(tokens);
2914 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2916 const TcoreATResponse *resp = data;
2917 UserRequest *ur = NULL;
2918 GSList *tokens = NULL;
2919 struct tresp_sim_get_facility_status *res = user_data;
2924 ur = tcore_pending_ref_user_request(p);
2926 res->result = SIM_PIN_OPERATION_SUCCESS;
2928 if (resp->success > 0) {
2931 line = (const char *)resp->lines->data;
2932 tokens = tcore_at_tok_new(line);
2933 if (g_slist_length(tokens) != 1) {
2934 msg("Invalid message");
2935 tcore_at_tok_free(tokens);
2939 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2941 dbg("RESPONSE NOK");
2942 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2947 tcore_user_request_send_response(ur, _find_resp_command(ur),
2948 sizeof(struct tresp_sim_get_facility_status), res);
2950 tcore_at_tok_free(tokens);
2955 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2957 const TcoreATResponse *resp = data;
2958 UserRequest *ur = NULL;
2959 CoreObject *co_sim = NULL;
2960 struct imc_sim_property *sp = NULL;
2961 GSList *tokens = NULL;
2962 struct tresp_sim_enable_facility res;
2967 co_sim = tcore_pending_ref_core_object(p);
2968 sp = tcore_sim_ref_userdata(co_sim);
2970 err("user data is null");
2974 ur = tcore_pending_ref_user_request(p);
2976 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2978 res.result = SIM_CARD_ERROR;
2979 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2981 if (resp->success > 0) {
2984 line = (const char *)resp->lines->data;
2985 tokens = tcore_at_tok_new(line);
2986 if (g_slist_length(tokens) != 1) {
2987 msg("Invalid message");
2990 tcore_user_request_send_response(ur, _find_resp_command(ur),
2991 sizeof(struct tresp_sim_enable_facility), &res);
2992 tcore_at_tok_free(tokens);
2997 res.result = SIM_PIN_OPERATION_SUCCESS;
3001 tcore_user_request_send_response(ur, _find_resp_command(ur),
3002 sizeof(struct tresp_sim_enable_facility), &res);
3006 tcore_at_tok_free(tokens);
3008 dbg("RESPONSE NOK");
3009 ur = tcore_user_request_ref(ur);
3010 _get_retry_count(co_sim, ur);
3015 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
3017 const TcoreATResponse *resp = data;
3018 UserRequest *ur = NULL;
3019 CoreObject *co_sim = NULL;
3020 struct imc_sim_property *sp = NULL;
3021 GSList *tokens = NULL;
3022 struct tresp_sim_disable_facility res;
3027 co_sim = tcore_pending_ref_core_object(p);
3028 sp = tcore_sim_ref_userdata(co_sim);
3030 err("user data is null");
3034 ur = tcore_pending_ref_user_request(p);
3036 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
3038 res.result = SIM_CARD_ERROR;
3039 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3041 if (resp->success > 0) {
3044 line = (const char *)resp->lines->data;
3045 tokens = tcore_at_tok_new(line);
3046 if (g_slist_length(tokens) != 1) {
3047 msg("Invalid message");
3050 tcore_user_request_send_response(ur, _find_resp_command(ur),
3051 sizeof(struct tresp_sim_disable_facility), &res);
3052 tcore_at_tok_free(tokens);
3057 res.result = SIM_PIN_OPERATION_SUCCESS;
3060 tcore_user_request_send_response(ur, _find_resp_command(ur),
3061 sizeof(struct tresp_sim_disable_facility), &res);
3064 tcore_at_tok_free(tokens);
3066 dbg("RESPONSE NOK");
3067 ur = tcore_user_request_ref(ur);
3068 _get_retry_count(co_sim, ur);
3073 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
3075 const TcoreATResponse *response = (TcoreATResponse *)data;
3076 UserRequest *ur = NULL;
3077 GSList *tokens = NULL;
3078 struct treq_sim_get_lock_info *req_data = NULL;
3079 struct tresp_sim_get_lock_info resp;
3081 int pin1_attempts_left = 0;
3082 int puk1_attempts_left = 0;
3083 int pin2_attempts_left = 0;
3084 int puk2_attempts_left = 0;
3085 int length_tokens = 0;
3089 memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3091 ur = tcore_pending_ref_user_request(p);
3093 if (!ur || !response) {
3094 err("NULL data : ur[%p], response[%p]", ur, response);
3095 resp.result = SIM_CARD_ERROR;
3096 tcore_user_request_send_response(ur, _find_resp_command(ur),
3097 sizeof(struct tresp_sim_get_lock_info), &resp);
3101 req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3103 resp.result = SIM_PIN_OPERATION_SUCCESS;
3104 resp.type = req_data->type;
3106 if (response->success > 0) {
3108 if (response->lines) {
3109 line = (const char *)response->lines->data;
3110 tokens = tcore_at_tok_new(line);
3111 length_tokens = g_slist_length(tokens);
3112 dbg("No of Tokens [%d]", length_tokens);
3113 switch (length_tokens) {
3115 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3117 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3119 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3121 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3125 err("Invalid response");
3126 tcore_at_tok_free(tokens);
3127 resp.result = SIM_CARD_ERROR;
3128 tcore_user_request_send_response(ur, _find_resp_command(ur),
3129 sizeof(struct tresp_sim_get_lock_info), &resp);
3134 dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3135 pin1_attempts_left, puk1_attempts_left);
3136 dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3137 pin2_attempts_left, puk2_attempts_left);
3139 resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3141 switch (resp.type) {
3142 case SIM_FACILITY_SC:
3143 resp.retry_count = pin1_attempts_left;
3144 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3145 resp.lock_status = SIM_LOCK_STATUS_PIN;
3146 } else if (pin1_attempts_left == 0) {
3147 if (puk1_attempts_left) {
3148 resp.lock_status = SIM_LOCK_STATUS_PUK;
3149 resp.retry_count = puk1_attempts_left;
3151 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3156 case SIM_FACILITY_FD:
3157 resp.retry_count = pin2_attempts_left;
3158 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3159 resp.lock_status = SIM_LOCK_STATUS_PIN2;
3160 } else if (pin2_attempts_left == 0) {
3161 if (puk2_attempts_left) {
3162 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3163 resp.retry_count = puk2_attempts_left;
3165 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3171 err("Unhandled facility type : [%d]", resp.type);
3174 dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3175 tcore_at_tok_free(tokens);
3178 err("RESPONSE NOK");
3179 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3183 tcore_user_request_send_response(ur, _find_resp_command(ur),
3184 sizeof(struct tresp_sim_get_lock_info), &resp);
3187 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
3189 UserRequest *ur = NULL;
3190 GSList *tokens = NULL;
3191 const char *line = NULL;
3192 const TcoreATResponse *response = (TcoreATResponse *)data;
3193 CoreObject *co_sim = NULL;
3194 struct imc_sim_property *meta_info = NULL;
3195 struct tresp_sim_set_data resp;
3198 gboolean cphs_sim = FALSE;
3199 enum tcore_request_command command;
3202 memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3204 ur = tcore_pending_ref_user_request(p);
3205 command = tcore_user_request_get_command(ur);
3206 co_sim = tcore_pending_ref_core_object(p);
3207 cphs_sim = tcore_sim_get_cphs_status(co_sim);
3208 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3210 if (!ur || !co_sim || !meta_info || !response) {
3211 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3212 resp.result = SIM_CARD_ERROR;
3215 if (response->success > 0) {
3217 if (response->lines) {
3218 line = (const char *)response->lines->data;
3219 tokens = tcore_at_tok_new(line);
3220 if (g_slist_length(tokens) < 2) {
3221 err("Invalid response");
3222 resp.result = SIM_CARD_ERROR;
3224 sw1 = atoi(g_slist_nth_data(tokens, 0));
3225 sw2 = atoi(g_slist_nth_data(tokens, 1));
3227 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
3228 resp.result = SIM_ACCESS_SUCCESS;
3230 resp.result = _decode_status_word(sw1, sw2);
3232 tcore_at_tok_free(tokens);
3235 err("RESPONSE NOK");
3236 resp.result = SIM_ACCESS_FAILED;
3240 if (cphs_sim == FALSE) {
3242 case TREQ_SIM_SET_MAILBOX:
3243 if (meta_info->file_id == SIM_EF_USIM_MBI) {
3244 if (resp.result == SIM_ACCESS_SUCCESS) {
3245 ur = tcore_user_request_ref(ur);
3246 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3248 dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3249 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3250 ur = tcore_user_request_ref(ur);
3251 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3261 case TREQ_SIM_SET_MAILBOX:
3262 if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3263 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3268 case TREQ_SIM_SET_CALLFORWARDING:
3269 if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3270 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3275 case TREQ_SIM_SET_MESSAGEWAITING:
3276 if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3277 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3289 tcore_user_request_send_response(ur, _find_resp_command(ur),
3290 sizeof(struct tresp_sim_set_data), &resp);
3293 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3295 const TcoreATResponse *resp = data;
3296 UserRequest *ur = NULL;
3297 struct tresp_sim_transmit_apdu res;
3302 ur = tcore_pending_ref_user_request(p);
3304 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3305 res.result = SIM_ACCESS_FAILED;
3307 if (resp->success > 0) {
3310 GSList *tokens = NULL;
3312 char *decoded_data = NULL;
3313 line = (const char *)resp->lines->data;
3314 tokens = tcore_at_tok_new(line);
3315 if (g_slist_length(tokens) != 2) {
3316 msg("Invalid message");
3317 tcore_at_tok_free(tokens);
3318 res.result = SIM_CARD_ERROR;
3322 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3324 decoded_data = util_hexStringToBytes(tmp);
3326 res.apdu_resp_length = strlen(tmp) / 2;
3327 res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3328 if (res.apdu_resp == NULL) {
3329 err("Memory allocation failed!!");
3330 tcore_at_tok_free(tokens);
3332 g_free(decoded_data);
3335 memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3337 g_free(decoded_data);
3338 res.result = SIM_ACCESS_SUCCESS;
3339 tcore_at_tok_free(tokens);
3341 err("util_hexStringToBytes Failed!!");
3347 dbg("RESPONSE NOK");
3353 tcore_user_request_send_response(ur, _find_resp_command(ur),
3354 sizeof(struct tresp_sim_transmit_apdu), &res);
3359 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3361 const TcoreATResponse *resp = data;
3362 UserRequest *ur = NULL;
3363 GSList *tokens = NULL;
3364 struct tresp_sim_get_atr res;
3369 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3370 ur = tcore_pending_ref_user_request(p);
3372 res.result = SIM_ACCESS_FAILED;
3373 if (resp->success > 0) {
3377 char *decoded_data = NULL;
3378 line = (const char *)resp->lines->data;
3379 tokens = tcore_at_tok_new(line);
3380 if (g_slist_length(tokens) < 1) {
3381 msg("Invalid message");
3385 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3387 decoded_data = util_hexStringToBytes(tmp);
3388 if (!decoded_data) {
3389 err("util_hexStringToBytes Failed!!");
3393 res.atr_length = strlen(tmp) / 2;
3394 memcpy((char *)res.atr, decoded_data, res.atr_length);
3396 g_free(decoded_data);
3397 res.result = SIM_ACCESS_SUCCESS;
3401 dbg("RESPONSE NOK");
3407 tcore_user_request_send_response(ur, _find_resp_command(ur),
3408 sizeof(struct tresp_sim_get_atr), &res);
3410 tcore_at_tok_free(tokens);
3414 static void on_response_req_authentication(TcorePending *p, int data_len,
3415 const void *data, void *user_data)
3417 const TcoreATResponse *at_resp = data;
3418 GSList *tokens = NULL;
3419 struct tresp_sim_req_authentication resp_auth;
3420 const struct treq_sim_req_authentication *req_data;
3421 UserRequest *ur = tcore_pending_ref_user_request(p);
3425 memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3427 if (at_resp == NULL) {
3428 err("at_resp is NULL");
3429 resp_auth.result = SIM_ACCESS_FAILED;
3430 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3434 req_data = tcore_user_request_ref_data(ur, NULL);
3435 if (req_data == NULL) {
3436 err("req_data is NULL");
3437 resp_auth.result = SIM_ACCESS_FAILED;
3438 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3441 resp_auth.auth_type = req_data->auth_type;
3443 if (at_resp->success == TRUE) {
3448 if (at_resp->lines != NULL) {
3449 line = at_resp->lines->data;
3450 dbg("Received data: [%s]", line);
3452 err("at_resp->lines is NULL");
3453 resp_auth.result = SIM_ACCESS_FAILED;
3454 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3458 tokens = tcore_at_tok_new(line);
3459 if (tokens == NULL) {
3460 err("tokens is NULL");
3461 resp_auth.result = SIM_ACCESS_FAILED;
3462 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3466 status = atoi(g_slist_nth_data(tokens, 0));
3469 dbg("Authentications successful");
3470 resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3473 err("Synchronize fail");
3474 resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3478 resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3481 err("Does not support security context");
3482 resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3485 err("Other failure");
3486 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3490 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3492 char *convert_kc, *convert_sres;
3494 kc = g_slist_nth_data(tokens, 1);
3496 kc = tcore_at_tok_extract(kc);
3497 dbg("Kc: [%s]", kc);
3498 convert_kc = util_hexStringToBytes(kc);
3499 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3500 resp_auth.authentication_key_length = strlen(convert_kc);
3501 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3504 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3510 sres = g_slist_nth_data(tokens, 2);
3512 sres = tcore_at_tok_extract(sres);
3513 dbg("SRES: [%s]", sres);
3514 convert_sres = util_hexStringToBytes(sres);
3515 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3516 resp_auth.resp_length = strlen(convert_sres);
3517 memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3519 err("Invalid SRES");
3520 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3523 g_free(convert_sres);
3525 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3526 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3530 err("RESPONSE NOK");
3531 resp_auth.result = SIM_ACCESS_FAILED;
3532 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3536 tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3537 sizeof(struct tresp_sim_req_authentication), &resp_auth);
3539 tcore_at_tok_free(tokens);
3542 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3544 TcoreHal *hal = NULL;
3545 TcoreATRequest *req = NULL;
3546 TcorePending *pending = NULL;
3547 char *cmd_str = NULL;
3548 const struct treq_sim_verify_pins *req_data = NULL;
3549 struct imc_sim_property *sp = NULL;
3550 TReturn ret = TCORE_RETURN_FAILURE;
3554 if ((o == NULL) || (ur == NULL))
3555 return TCORE_RETURN_EINVAL;
3557 hal = tcore_object_get_hal(o);
3558 if (FALSE == tcore_hal_get_power_state(hal)) {
3559 err("CP NOT READY");
3560 return TCORE_RETURN_ENOSYS;
3563 sp = tcore_sim_ref_userdata(o);
3565 err("user data is null");
3566 return TCORE_RETURN_FAILURE;
3569 pending = tcore_pending_new(o, 0);
3571 err("Pending is NULL");
3572 return TCORE_RETURN_FAILURE;
3575 req_data = tcore_user_request_ref_data(ur, NULL);
3577 if (req_data->pin_type == SIM_PTYPE_PIN1) {
3578 sp->current_sec_op = SEC_PIN1_VERIFY;
3579 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3580 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3581 sp->current_sec_op = SEC_PIN2_VERIFY;
3582 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3583 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3584 sp->current_sec_op = SEC_SIM_VERIFY;
3585 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3586 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3587 sp->current_sec_op = SEC_ADM_VERIFY;
3588 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3590 tcore_pending_free(pending);
3591 return TCORE_RETURN_EINVAL;
3594 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3596 tcore_pending_free(pending);
3598 return TCORE_RETURN_FAILURE;
3602 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3603 req->cmd, req->prefix, strlen(req->cmd));
3605 tcore_pending_set_request_data(pending, 0, req);
3606 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3607 tcore_pending_link_user_request(pending, ur);
3608 ret = tcore_hal_send_request(hal, pending);
3614 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3616 TcoreHal *hal = NULL;
3617 TcoreATRequest *req = NULL;
3618 TcorePending *pending = NULL;
3619 char *cmd_str = NULL;
3620 const struct treq_sim_verify_puks *req_data;
3621 struct imc_sim_property *sp = NULL;
3622 TReturn ret = TCORE_RETURN_FAILURE;
3626 if ((o == NULL) || (ur == NULL))
3627 return TCORE_RETURN_EINVAL;
3629 hal = tcore_object_get_hal(o);
3630 if (FALSE == tcore_hal_get_power_state(hal)) {
3631 err("CP NOT READY");
3632 return TCORE_RETURN_ENOSYS;
3635 sp = tcore_sim_ref_userdata(o);
3637 err("user data is null");
3638 return TCORE_RETURN_FAILURE;
3641 pending = tcore_pending_new(o, 0);
3643 err("Pending is NULL");
3644 return TCORE_RETURN_FAILURE;
3647 req_data = tcore_user_request_ref_data(ur, NULL);
3649 if (req_data->puk_type == SIM_PTYPE_PUK1) {
3650 sp->current_sec_op = SEC_PUK1_VERIFY;
3651 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3652 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3653 sp->current_sec_op = SEC_PUK2_VERIFY;
3654 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3656 tcore_pending_free(pending);
3657 return TCORE_RETURN_EINVAL;
3660 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3662 tcore_pending_free(pending);
3664 return TCORE_RETURN_FAILURE;
3668 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3669 req->cmd, req->prefix, strlen(req->cmd));
3671 tcore_pending_set_request_data(pending, 0, req);
3672 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3673 tcore_pending_link_user_request(pending, ur);
3674 ret = tcore_hal_send_request(hal, pending);
3680 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3682 TcoreHal *hal = NULL;
3683 TcoreATRequest *req = NULL;
3684 TcorePending *pending = NULL;
3685 char *cmd_str = NULL;
3686 const struct treq_sim_change_pins *req_data;
3687 struct imc_sim_property *sp = NULL;
3690 TReturn ret = TCORE_RETURN_FAILURE;
3694 if ((o == NULL) || (ur == NULL))
3695 return TCORE_RETURN_EINVAL;
3697 hal = tcore_object_get_hal(o);
3698 if (FALSE == tcore_hal_get_power_state(hal)) {
3699 err("CP NOT READY");
3700 return TCORE_RETURN_ENOSYS;
3703 sp = tcore_sim_ref_userdata(o);
3705 err("user data is null");
3706 return TCORE_RETURN_FAILURE;
3709 pending = tcore_pending_new(o, 0);
3711 err("Pending is NULL");
3712 return TCORE_RETURN_FAILURE;
3715 req_data = tcore_user_request_ref_data(ur, NULL);
3717 if (req_data->type == SIM_PTYPE_PIN1) {
3718 sp->current_sec_op = SEC_PIN1_CHANGE;
3719 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3720 } else if (req_data->type == SIM_PTYPE_PIN2) {
3721 sp->current_sec_op = SEC_PIN2_CHANGE;
3722 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3724 tcore_pending_free(pending);
3725 return TCORE_RETURN_EINVAL;
3727 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3729 tcore_pending_free(pending);
3731 return TCORE_RETURN_FAILURE;
3735 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3736 req->cmd, req->prefix, strlen(req->cmd));
3738 tcore_pending_set_request_data(pending, 0, req);
3739 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3740 tcore_pending_link_user_request(pending, ur);
3741 ret = tcore_hal_send_request(hal, pending);
3747 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3749 TcoreHal *hal = NULL;
3750 TcoreATRequest *req = NULL;
3751 TcorePending *pending = NULL;
3752 char *cmd_str = NULL;
3753 const struct treq_sim_get_facility_status *req_data;
3754 struct tresp_sim_get_facility_status *res;
3756 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
3757 TReturn ret = TCORE_RETURN_FAILURE;
3761 if ((o == NULL) || (ur == NULL))
3762 return TCORE_RETURN_EINVAL;
3764 hal = tcore_object_get_hal(o);
3765 if (FALSE == tcore_hal_get_power_state(hal)) {
3766 err("CP NOT READY");
3767 return TCORE_RETURN_ENOSYS;
3770 pending = tcore_pending_new(o, 0);
3772 err("Pending is NULL");
3773 return TCORE_RETURN_FAILURE;
3776 req_data = tcore_user_request_ref_data(ur, NULL);
3778 res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3780 tcore_pending_free(pending);
3781 return TCORE_RETURN_ENOMEM;
3784 res->type = req_data->type;
3786 if (req_data->type == SIM_FACILITY_PS)
3787 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3788 else if (req_data->type == SIM_FACILITY_SC)
3789 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3790 else if (req_data->type == SIM_FACILITY_FD)
3791 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3792 else if (req_data->type == SIM_FACILITY_PN)
3793 fac = "PN"; /*Network Personalization*/
3794 else if (req_data->type == SIM_FACILITY_PU)
3795 fac = "PU"; /*network sUbset Personalization*/
3796 else if (req_data->type == SIM_FACILITY_PP)
3797 fac = "PP"; /*service Provider Personalization*/
3798 else if (req_data->type == SIM_FACILITY_PC)
3799 fac = "PC"; /*Corporate Personalization*/
3801 return TCORE_RETURN_EINVAL;
3803 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3804 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3806 tcore_pending_free(pending);
3808 return TCORE_RETURN_FAILURE;
3812 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3813 req->cmd, req->prefix, strlen(req->cmd));
3815 tcore_pending_set_request_data(pending, 0, req);
3816 tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3817 tcore_pending_link_user_request(pending, ur);
3818 ret = tcore_hal_send_request(hal, pending);
3824 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3826 TcoreHal *hal = NULL;
3827 TcoreATRequest *req = NULL;
3828 TcorePending *pending = NULL;
3829 char *cmd_str = NULL;
3830 const struct treq_sim_enable_facility *req_data;
3831 struct imc_sim_property *sp = NULL;
3833 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
3834 TReturn ret = TCORE_RETURN_FAILURE;
3838 if ((o == NULL) || (ur == NULL))
3839 return TCORE_RETURN_EINVAL;
3841 hal = tcore_object_get_hal(o);
3842 if (FALSE == tcore_hal_get_power_state(hal)) {
3843 err("CP NOT READY");
3844 return TCORE_RETURN_ENOSYS;
3847 sp = tcore_sim_ref_userdata(o);
3849 err("user data is null");
3850 return TCORE_RETURN_FAILURE;
3853 pending = tcore_pending_new(o, 0);
3855 err("Pending is NULL");
3856 return TCORE_RETURN_FAILURE;
3859 req_data = tcore_user_request_ref_data(ur, NULL);
3861 if (req_data->type == SIM_FACILITY_PS) {
3862 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3863 sp->current_sec_op = SEC_SIM_ENABLE;
3864 } else if (req_data->type == SIM_FACILITY_SC) {
3865 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3866 sp->current_sec_op = SEC_PIN1_ENABLE;
3867 } else if (req_data->type == SIM_FACILITY_FD) {
3868 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3869 sp->current_sec_op = SEC_FDN_ENABLE;
3870 } else if (req_data->type == SIM_FACILITY_PN) {
3871 fac = "PN"; /*Network Personalization*/
3872 sp->current_sec_op = SEC_NET_ENABLE;
3873 } else if (req_data->type == SIM_FACILITY_PU) {
3874 fac = "PU"; /*network sUbset Personalization*/
3875 sp->current_sec_op = SEC_NS_ENABLE;
3876 } else if (req_data->type == SIM_FACILITY_PP) {
3877 fac = "PP"; /*service Provider Personalization*/
3878 sp->current_sec_op = SEC_SP_ENABLE;
3879 } else if (req_data->type == SIM_FACILITY_PC) {
3880 fac = "PC"; /*Corporate Personalization*/
3881 sp->current_sec_op = SEC_CP_ENABLE;
3883 return TCORE_RETURN_EINVAL;
3885 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3886 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3888 tcore_pending_free(pending);
3890 return TCORE_RETURN_FAILURE;
3894 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3895 req->cmd, req->prefix, strlen(req->cmd));
3897 tcore_pending_set_request_data(pending, 0, req);
3898 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3899 tcore_pending_link_user_request(pending, ur);
3900 ret = tcore_hal_send_request(hal, pending);
3906 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3909 TcoreATRequest *req;
3910 TcorePending *pending = NULL;
3911 char *cmd_str = NULL;
3912 const struct treq_sim_enable_facility *req_data;
3913 struct imc_sim_property *sp = NULL;
3915 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
3916 TReturn ret = TCORE_RETURN_FAILURE;
3920 if ((o == NULL) || (ur == NULL))
3921 return TCORE_RETURN_EINVAL;
3923 hal = tcore_object_get_hal(o);
3924 if (FALSE == tcore_hal_get_power_state(hal)) {
3925 err("CP NOT READY");
3926 return TCORE_RETURN_ENOSYS;
3929 sp = tcore_sim_ref_userdata(o);
3931 err("user data is null");
3932 return TCORE_RETURN_FAILURE;
3935 pending = tcore_pending_new(o, 0);
3937 err("Pending is NULL");
3938 return TCORE_RETURN_FAILURE;
3941 req_data = tcore_user_request_ref_data(ur, NULL);
3943 if (req_data->type == SIM_FACILITY_PS) {
3944 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3945 sp->current_sec_op = SEC_SIM_DISABLE;
3946 } else if (req_data->type == SIM_FACILITY_SC) {
3947 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3948 sp->current_sec_op = SEC_PIN1_DISABLE;
3949 } else if (req_data->type == SIM_FACILITY_FD) {
3950 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3951 sp->current_sec_op = SEC_FDN_DISABLE;
3952 } else if (req_data->type == SIM_FACILITY_PN) {
3953 fac = "PN"; /*Network Personalization*/
3954 sp->current_sec_op = SEC_NET_DISABLE;
3955 } else if (req_data->type == SIM_FACILITY_PU) {
3956 fac = "PU"; /*network sUbset Personalization*/
3957 sp->current_sec_op = SEC_NS_DISABLE;
3958 } else if (req_data->type == SIM_FACILITY_PP) {
3959 fac = "PP"; /*service Provider Personalization*/
3960 sp->current_sec_op = SEC_SP_DISABLE;
3961 } else if (req_data->type == SIM_FACILITY_PC) {
3962 fac = "PC"; /*Corporate Personalization*/
3963 sp->current_sec_op = SEC_CP_DISABLE;
3965 return TCORE_RETURN_EINVAL;
3967 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3968 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3970 tcore_pending_free(pending);
3972 return TCORE_RETURN_FAILURE;
3976 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3977 req->cmd, req->prefix, strlen(req->cmd));
3979 tcore_pending_set_request_data(pending, 0, req);
3980 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
3981 tcore_pending_link_user_request(pending, ur);
3982 ret = tcore_hal_send_request(hal, pending);
3988 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
3990 TcoreHal *hal = NULL;
3991 TcoreATRequest *req = NULL;
3992 TcorePending *pending = NULL;
3996 hal = tcore_object_get_hal(o);
3997 pending = tcore_pending_new(o, 0);
3999 err("Pending is NULL");
4000 return TCORE_RETURN_FAILURE;
4003 if ((o == NULL) || (ur == NULL)) {
4004 tcore_pending_free(pending);
4005 return TCORE_RETURN_EINVAL;
4007 req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
4010 tcore_pending_free(pending);
4011 return TCORE_RETURN_FAILURE;
4014 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4015 req->cmd, req->prefix, strlen(req->cmd));
4017 tcore_pending_set_request_data(pending, 0, req);
4018 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
4019 tcore_pending_link_user_request(pending, ur);
4020 tcore_hal_send_request(hal, pending);
4023 return TCORE_RETURN_SUCCESS;
4026 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
4028 TReturn api_ret = TCORE_RETURN_SUCCESS;
4029 enum tcore_request_command command;
4033 if ((o == NULL) || (ur == NULL))
4034 return TCORE_RETURN_EINVAL;
4036 command = tcore_user_request_get_command(ur);
4037 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
4038 err("CP NOT READY");
4039 return TCORE_RETURN_ENOSYS;
4043 case TREQ_SIM_GET_ECC:
4044 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
4047 case TREQ_SIM_GET_LANGUAGE:
4048 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
4049 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
4050 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
4051 api_ret = _get_file_info(o, ur, SIM_EF_LP);
4053 api_ret = TCORE_RETURN_ENOSYS;
4056 case TREQ_SIM_GET_ICCID:
4057 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
4060 case TREQ_SIM_GET_MAILBOX:
4061 if (tcore_sim_get_cphs_status(o))
4062 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4064 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
4067 case TREQ_SIM_GET_CALLFORWARDING:
4068 if (tcore_sim_get_cphs_status(o))
4069 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4071 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
4074 case TREQ_SIM_GET_MESSAGEWAITING:
4075 if (tcore_sim_get_cphs_status(o))
4076 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4078 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
4081 case TREQ_SIM_GET_CPHS_INFO:
4082 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
4085 case TREQ_SIM_GET_MSISDN:
4086 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
4089 case TREQ_SIM_GET_SPN:
4090 dbg("enter case SPN");
4091 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
4094 case TREQ_SIM_GET_SPDI:
4095 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
4098 case TREQ_SIM_GET_OPL:
4099 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
4102 case TREQ_SIM_GET_PNN:
4103 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
4106 case TREQ_SIM_GET_CPHS_NETNAME:
4107 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
4110 case TREQ_SIM_GET_OPLMNWACT:
4111 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
4114 case TREQ_SIM_GET_SERVICE_TABLE:
4115 api_ret = _get_file_info(o, ur, SIM_EF_SST);
4119 dbg("error - not handled read treq command[%d]", command);
4120 api_ret = TCORE_RETURN_EINVAL;
4128 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
4130 TReturn ret_code = TCORE_RETURN_SUCCESS;
4131 enum tcore_request_command command;
4132 enum tel_sim_file_id ef = SIM_EF_INVALID;
4133 struct imc_sim_property meta_info = {0, };
4134 enum tel_sim_type sim_type;
4135 gboolean cphs_sim = FALSE;
4138 command = tcore_user_request_get_command(ur);
4139 cphs_sim = tcore_sim_get_cphs_status(co_sim);
4140 sim_type = tcore_sim_get_type(co_sim);
4142 if ((co_sim == NULL) || (ur == NULL))
4143 return TCORE_RETURN_EINVAL;
4146 case TREQ_SIM_SET_LANGUAGE:
4147 if (sim_type == SIM_TYPE_GSM)
4148 ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
4149 else if (sim_type == SIM_TYPE_USIM)
4150 ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
4152 ret_code = TCORE_RETURN_ENOSYS;
4155 case TREQ_SIM_SET_MAILBOX:
4157 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4161 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MBDN]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MBDN])) {
4162 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4163 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4165 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
4166 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4170 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4174 case TREQ_SIM_SET_CALLFORWARDING:
4176 const struct treq_sim_set_callforwarding *cf = NULL;
4177 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
4181 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4184 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_CFIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_CFIS])) {
4185 if (cf->b_cphs == FALSE)
4186 ef = SIM_EF_USIM_CFIS;
4188 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4190 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4191 ret_code = _get_file_info(co_sim, ur, ef);
4193 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4194 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4198 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4201 ret_code = TCORE_RETURN_EINVAL;
4206 case TREQ_SIM_SET_MESSAGEWAITING:
4208 const struct treq_sim_set_messagewaiting *mw = NULL;
4209 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4212 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4215 if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MWIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MWIS])) {
4216 if (mw->b_cphs == FALSE)
4217 ef = SIM_EF_USIM_MWIS;
4219 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4221 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4222 ret_code = _get_file_info(co_sim, ur, ef);
4224 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4225 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4229 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4232 ret_code = TCORE_RETURN_EINVAL;
4238 err("Unhandled UPDATE command[%d]", command);
4239 return TCORE_RETURN_EINVAL;
4245 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4247 const struct treq_sim_transmit_apdu *req_data;
4248 TcoreHal *hal = NULL;
4249 char *cmd_str = NULL;
4252 TReturn ret = TCORE_RETURN_FAILURE;
4256 if ((o == NULL) || (ur == NULL))
4257 return TCORE_RETURN_EINVAL;
4259 hal = tcore_object_get_hal(o);
4260 if (FALSE == tcore_hal_get_power_state(hal)) {
4261 err("CP NOT READY");
4262 return TCORE_RETURN_ENOSYS;
4265 req_data = tcore_user_request_ref_data(ur, NULL);
4267 apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4269 err("Memory allocation failed!!");
4270 return TCORE_RETURN_ENOMEM;
4272 result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4273 dbg("result %d", result);
4275 cmd_str = g_strdup_printf("AT+CSIM=%d, \"%s\"", (unsigned int)strlen(apdu), apdu);
4277 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4278 TCORE_AT_SINGLELINE, ur,
4279 on_response_transmit_apdu, hal,
4280 NULL, NULL, 0, NULL, NULL);
4288 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4290 TcoreHal *hal = NULL;
4294 if ((o == NULL) || (ur == NULL)) {
4295 err("Invalid parameters");
4296 return TCORE_RETURN_EINVAL;
4299 hal = tcore_object_get_hal(o);
4300 if (FALSE == tcore_hal_get_power_state(hal)) {
4301 err("CP NOT READY");
4302 return TCORE_RETURN_ENOSYS;
4305 return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4306 TCORE_AT_SINGLELINE, ur,
4307 on_response_get_atr, hal,
4308 NULL, NULL, 0, NULL, NULL);
4311 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4313 const struct treq_sim_req_authentication *req_data;
4314 char *cmd_str = NULL;
4315 enum tel_sim_type sim_type;
4318 TReturn ret = TCORE_RETURN_FAILURE;
4319 char *convert_rand = NULL;
4320 char *convert_autn = NULL;
4324 req_data = tcore_user_request_ref_data(ur, NULL);
4325 if (req_data == NULL) {
4326 err("req_data is NULL");
4330 convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
4331 dbg("Convert RAND hex to string: [%s]", convert_rand);
4333 sim_type = tcore_sim_get_type(co);
4340 err("Not supported");
4341 ret = TCORE_RETURN_ENOSYS;
4345 switch (req_data->auth_type) {
4346 case SIM_AUTH_TYPE_GSM:
4348 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\"", session_id,
4349 context_type, convert_rand);
4351 case SIM_AUTH_TYPE_3G:
4353 convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
4354 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4356 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\", \"%s\"",
4357 session_id, context_type,
4358 convert_rand, convert_autn);
4361 err("Not supported");
4362 ret = TCORE_RETURN_ENOSYS;
4366 ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4367 TCORE_AT_SINGLELINE, ur,
4368 on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4372 g_free(convert_rand);
4373 g_free(convert_autn);
4378 /* SIM Operations */
4379 static struct tcore_sim_operations sim_ops = {
4380 .verify_pins = imc_verify_pins,
4381 .verify_puks = imc_verify_puks,
4382 .change_pins = imc_change_pins,
4383 .get_facility_status = imc_get_facility_status,
4384 .enable_facility = imc_enable_facility,
4385 .disable_facility = imc_disable_facility,
4386 .get_lock_info = imc_get_lock_info,
4387 .read_file = imc_read_file,
4388 .update_file = imc_update_file,
4389 .transmit_apdu = imc_transmit_apdu,
4390 .get_atr = imc_get_atr,
4391 .req_authentication = imc_req_authentication,
4392 .set_powerstate = NULL,
4395 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4397 struct imc_sim_property *meta_info;
4401 /* Set operations */
4402 tcore_sim_set_ops(co_sim, &sim_ops, TCORE_OPS_TYPE_CP);
4404 meta_info = g_try_new0(struct imc_sim_property, 1);
4405 if (meta_info == NULL)
4408 tcore_sim_link_userdata(co_sim, meta_info);
4410 tcore_object_add_callback(co_sim, "+XLOCK:",
4411 on_event_facility_lock_status, NULL);
4412 tcore_object_add_callback(co_sim, "+XSIM:",
4413 on_event_pin_status, NULL);
4415 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4416 TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4423 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4425 struct imc_sim_property *meta_info;
4427 meta_info = tcore_sim_ref_userdata(co_sim);