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 <ckmc/ckmc-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_STORE_ALIAS "telephony_sim_imsi1"
48 #define SWAPBYTES16(x) \
50 unsigned short int data = *(unsigned short int *)&(x); \
51 data = ((data & 0xff00) >> 8) | \
52 ((data & 0x00ff) << 8); \
53 *(unsigned short int *)&(x) = data; \
56 enum imc_sim_sec_op_e {
68 SEC_PIN2_DISABLE, /* 10 */
78 SEC_CP_DISABLE, /* 20 */
89 SEC_SIM_UNKNOWN = 0xff
92 struct imc_sim_property {
93 gboolean b_valid; /**< Valid or not */
94 enum tel_sim_file_id file_id; /**< File identifier */
95 enum tcore_sim_file_type_e file_type; /**< File type and structure */
96 int rec_length; /**< Length of one record in file */
97 int rec_count; /**< Number of records in file */
98 int data_size; /**< File size */
99 int current_index; /**< current index to read */
100 enum imc_sim_sec_op_e current_sec_op; /**< current index to read */
101 int mb_count; /**< Number of MB records in file */
102 struct tel_sim_mbi_list mbi_list;
103 struct tel_sim_mailbox mb_data;
104 struct tresp_sim_read files;
107 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data);
108 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
109 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
110 static gboolean _get_sim_type(CoreObject *o);
111 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
112 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
113 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
114 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
115 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
117 static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
119 TcoreATRequest *req = NULL;
120 TcoreHal *hal = NULL;
121 TcorePending *pending = NULL;
125 hal = tcore_object_get_hal(co);
128 pending = tcore_pending_new(co, 0);
130 dbg("Pending is NULL");
133 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
135 tcore_pending_free(pending);
139 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
141 tcore_pending_set_request_data(pending, 0, req);
142 tcore_pending_set_response_callback(pending, callback, NULL);
143 tcore_pending_link_user_request(pending, NULL); /* set user request to NULL - this is internal request */
144 ret = tcore_hal_send_request(hal, pending);
145 if (ret != TCORE_RETURN_SUCCESS) {
146 err("error: [0x%x]", ret);
147 tcore_pending_free(pending);
148 tcore_at_request_free(req);
154 static enum tcore_response_command _find_resp_command(UserRequest *ur)
156 enum tcore_request_command command;
158 command = tcore_user_request_get_command(ur);
160 case TREQ_SIM_VERIFY_PINS:
161 return TRESP_SIM_VERIFY_PINS;
164 case TREQ_SIM_VERIFY_PUKS:
165 return TRESP_SIM_VERIFY_PUKS;
168 case TREQ_SIM_CHANGE_PINS:
169 return TRESP_SIM_CHANGE_PINS;
172 case TREQ_SIM_GET_FACILITY_STATUS:
173 return TRESP_SIM_GET_FACILITY_STATUS;
176 case TREQ_SIM_DISABLE_FACILITY:
177 return TRESP_SIM_DISABLE_FACILITY;
180 case TREQ_SIM_ENABLE_FACILITY:
181 return TRESP_SIM_ENABLE_FACILITY;
184 case TREQ_SIM_GET_LOCK_INFO:
185 return TRESP_SIM_GET_LOCK_INFO;
188 case TREQ_SIM_TRANSMIT_APDU:
189 return TRESP_SIM_TRANSMIT_APDU;
192 case TREQ_SIM_GET_ATR:
193 return TRESP_SIM_GET_ATR;
196 case TREQ_SIM_GET_ECC:
197 return TRESP_SIM_GET_ECC;
200 case TREQ_SIM_GET_LANGUAGE:
201 return TRESP_SIM_GET_LANGUAGE;
204 case TREQ_SIM_SET_LANGUAGE:
205 return TRESP_SIM_SET_LANGUAGE;
208 case TREQ_SIM_GET_ICCID:
209 return TRESP_SIM_GET_ICCID;
212 case TREQ_SIM_GET_MAILBOX:
213 return TRESP_SIM_GET_MAILBOX;
216 case TREQ_SIM_SET_MAILBOX:
217 return TRESP_SIM_SET_MAILBOX;
220 case TREQ_SIM_GET_CALLFORWARDING:
221 return TRESP_SIM_GET_CALLFORWARDING;
224 case TREQ_SIM_SET_CALLFORWARDING:
225 return TRESP_SIM_SET_CALLFORWARDING;
228 case TREQ_SIM_GET_MESSAGEWAITING:
229 return TRESP_SIM_GET_MESSAGEWAITING;
232 case TREQ_SIM_SET_MESSAGEWAITING:
233 return TRESP_SIM_SET_MESSAGEWAITING;
236 case TREQ_SIM_GET_CPHS_INFO:
237 return TRESP_SIM_GET_CPHS_INFO;
240 case TREQ_SIM_GET_MSISDN:
241 return TRESP_SIM_GET_MSISDN;
244 case TREQ_SIM_GET_SPN:
245 return TRESP_SIM_GET_SPN;
248 case TREQ_SIM_GET_SPDI:
249 return TRESP_SIM_GET_SPDI;
252 case TREQ_SIM_GET_OPL:
253 return TRESP_SIM_GET_OPL;
256 case TREQ_SIM_GET_PNN:
257 return TRESP_SIM_GET_PNN;
260 case TREQ_SIM_GET_CPHS_NETNAME:
261 return TRESP_SIM_GET_CPHS_NETNAME;
264 case TREQ_SIM_GET_OPLMNWACT:
265 return TRESP_SIM_GET_OPLMNWACT;
268 case TREQ_SIM_REQ_AUTHENTICATION:
269 return TRESP_SIM_REQ_AUTHENTICATION;
272 case TREQ_SIM_GET_SERVICE_TABLE:
273 return TRESP_SIM_GET_SERVICE_TABLE;
279 return TRESP_UNKNOWN;
282 static int _sim_get_current_pin_facility(enum imc_sim_sec_op_e op)
286 dbg("current sec_op[%d]", op);
289 case SEC_PIN1_VERIFY:
290 case SEC_PIN1_CHANGE:
291 ret_type = SIM_PTYPE_PIN1;
294 case SEC_PIN2_VERIFY:
295 case SEC_PIN2_CHANGE:
296 ret_type = SIM_PTYPE_PIN2;
299 case SEC_PUK1_VERIFY:
300 ret_type = SIM_PTYPE_PUK1;
303 case SEC_PUK2_VERIFY:
304 ret_type = SIM_PTYPE_PUK2;
308 ret_type = SIM_PTYPE_SIM;
312 ret_type = SIM_PTYPE_ADM;
315 case SEC_PIN1_ENABLE:
316 case SEC_PIN1_DISABLE:
317 case SEC_PIN1_STATUS:
318 ret_type = SIM_FACILITY_SC;
322 case SEC_SIM_DISABLE:
324 ret_type = SIM_FACILITY_PS;
328 case SEC_NET_DISABLE:
330 ret_type = SIM_FACILITY_PN;
336 ret_type = SIM_FACILITY_PU;
342 ret_type = SIM_FACILITY_PP;
348 ret_type = SIM_FACILITY_PC;
352 case SEC_FDN_DISABLE:
354 ret_type = SIM_FACILITY_FD;
358 dbg("not handled current sec op[%d]", op);
364 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
366 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
368 if (status_word1 == 0x93 && status_word2 == 0x00) {
369 rst = SIM_ACCESS_FAILED;
370 /*Failed SIM request command*/
371 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
372 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
373 rst = SIM_ACCESS_FAILED;
374 /*Failed SIM request command*/
375 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
376 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
377 rst = SIM_ACCESS_FAILED;
378 /*Failed SIM request command*/
379 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
380 status_word1, status_word2);
381 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
382 rst = SIM_ACCESS_FILE_NOT_FOUND;
383 /*Failed SIM request command*/
384 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
385 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
386 rst = SIM_ACCESS_FAILED; /* MOdem not support */
387 /*Failed SIM request command*/
388 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
389 status_word1, status_word2);
390 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
391 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
392 /*Failed SIM request command*/
393 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
394 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
395 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
396 /*Failed SIM request command*/
397 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
398 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
399 status_word1, status_word2);
400 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
401 status_word1, status_word2);
402 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
403 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
404 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
405 /*Failed SIM request command*/
406 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
407 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
408 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
409 /*Failed SIM request command*/
410 dbg("error - Contradiction with invalidation status [%x][%x]",
411 status_word1, status_word2);
412 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
413 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
414 /*Failed SIM request command*/
415 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
416 status_word1, status_word2);
417 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
418 status_word1, status_word2);
419 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
420 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
421 rst = SIM_ACCESS_FAILED;
422 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
423 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
424 rst = SIM_ACCESS_FAILED;
425 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
426 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
427 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
428 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
429 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
430 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
431 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
432 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
433 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
434 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
435 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
436 rst = SIM_ACCESS_FAILED;
437 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
438 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
439 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
440 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
441 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
442 rst = SIM_ACCESS_FILE_NOT_FOUND; /* not sure of the SW1 and SW2 meaning here */
443 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
445 rst = SIM_ACCESS_CARD_ERROR;
446 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
451 static gboolean _sim_check_identity(CoreObject *co_sim, struct tel_sim_imsi *imsi)
453 gboolean is_changed = TRUE;
454 char new_imsi[16 + 1]; /* IMSI is 15 digit, but for distingushing between plmn and msin, define as 16 bytes. */
455 char *imsi_buf = NULL;
459 ckmc_raw_buffer_s *ckmc_buffer;
468 memset(new_imsi, 0x5F, 16);
469 memcpy(new_imsi, imsi->plmn, strlen(imsi->plmn));
470 memcpy(&new_imsi[6], imsi->msin, strlen(imsi->msin));
471 new_imsi[6 + strlen(imsi->msin)] = '\0';
473 ret_val = ckmc_get_data(SIM_STORE_ALIAS, passwd, &ckmc_buffer);
474 imsi_buf = (char*)ckmc_buffer->data;
475 if (ret_val == CKMC_ERROR_NONE && imsi_buf != NULL) {
476 if (strncmp(imsi_buf, new_imsi, 16) == 0)
478 ckmc_buffer_free(ckmc_buffer);
482 ckmc_policy_s policy;
483 ckmc_raw_buffer_s store_buffer;
485 policy.password = passwd;
486 policy.extractable = true;
487 store_buffer.data = (unsigned char*)new_imsi;
488 store_buffer.size = strlen(new_imsi) + 1;
492 ret_val = ckmc_save_data(SIM_STORE_ALIAS, store_buffer, policy);
493 if (ret_val != CKMC_ERROR_NONE)
494 err("ckmc_save_data failed. ret_val=[%d]", ret_val);
497 /* Update sim identification */
498 tcore_sim_set_identification(co_sim, is_changed);
502 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
503 char *encoded_data, unsigned int encoded_len, int rec_index)
505 TcoreHal *hal = NULL;
506 TcoreATRequest *req = NULL;
507 TcorePending *pending = NULL;
508 char *cmd_str = NULL;
509 struct imc_sim_property *meta_info = NULL;
517 hal = tcore_object_get_hal(o);
518 pending = tcore_pending_new(o, 0);
520 err("Pending is NULL");
521 return TCORE_RETURN_FAILURE;
523 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
525 meta_info->file_id = ef;
526 dbg("File ID: [0x%x]", meta_info->file_id);
529 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
532 case SIM_EF_CPHS_VOICE_MSG_WAITING:
539 case SIM_EF_USIM_CFIS:
540 case SIM_EF_USIM_MWIS:
541 case SIM_EF_CPHS_MAILBOX_NUMBERS:
543 case SIM_EF_USIM_MBI:
551 err("Unhandled File ID[0x%04x]", ef);
552 tcore_pending_free(pending);
553 return TCORE_RETURN_EINVAL;
556 cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d, \"%s\"", cmd, ef, p1, p2, p3, encoded_data);
558 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
560 tcore_pending_free(pending);
562 return TCORE_RETURN_FAILURE;
566 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
567 req->cmd, req->prefix, strlen(req->cmd));
569 tcore_pending_set_request_data(pending, 0, req);
570 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
571 tcore_pending_link_user_request(pending, ur);
572 tcore_hal_send_request(hal, pending);
579 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
581 struct imc_sim_property *meta_info = NULL;
582 TReturn ret_code = TCORE_RETURN_FAILURE;
584 enum tcore_request_command command;
586 char *encoded_data = NULL;
592 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
593 return TCORE_RETURN_EINVAL;
595 command = tcore_user_request_get_command(ur);
596 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
599 case TREQ_SIM_SET_LANGUAGE: {
600 const struct treq_sim_set_language *lang = NULL;
601 struct tel_sim_language language = {0, };
603 lang = tcore_user_request_ref_data(ur, NULL);
604 language.language_count = 1;
605 language.language[0] = lang->language;
606 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP) {
607 dbg("Encoding EF-LP, language[%d]", lang->language);
608 tmp = tcore_sim_encode_lp(&encoded_len, &language);
610 dbg("Encoding EF-ELP, language[%d]", lang->language);
611 tmp = tcore_sim_encode_li(&encoded_len, &language);
616 case TREQ_SIM_SET_CALLFORWARDING: {
617 const struct treq_sim_set_callforwarding *cf = NULL;
619 cf = tcore_user_request_ref_data(ur, NULL);
620 if (ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
622 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cf->cphs_cf, meta_info->data_size);
624 /* Convert 3GPP data to CPHS data */
625 struct tel_sim_cphs_cf cphs_cf;
627 dbg("Convert 3GPP data to CPHS data");
628 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
629 if (cf->cf.cfu_status & 0x01)
630 cphs_cf.b_line1 = TRUE;
632 if (cf->cf.cfu_status & 0x02)
633 cphs_cf.b_fax = TRUE;
635 if (cf->cf.cfu_status & 0x04)
636 cphs_cf.b_data = TRUE;
638 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cphs_cf, meta_info->data_size);
642 encoded_len = strlen(tmp);
644 err("NULL Encoding Data[%p].. No Updating EF", tmp);
647 } else if (ef == SIM_EF_USIM_CFIS) {
648 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis *)&cf->cf);
649 rec_index = cf->cf.rec_index;
651 err("Invalid File ID[0x%04x]", ef);
657 case TREQ_SIM_SET_MESSAGEWAITING: {
658 const struct treq_sim_set_messagewaiting *mw = NULL;
660 mw = tcore_user_request_ref_data(ur, NULL);
661 if (ef == SIM_EF_CPHS_VOICE_MSG_WAITING) {
663 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&mw->cphs_mw, meta_info->data_size);
665 /* Convert 3GPP data to CPHS data */
666 struct tel_sim_cphs_mw cphs_mw;
668 dbg("Convert 3GPP data to CPHS data");
669 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
671 if (mw->mw.indicator_status & 0x01)
672 cphs_mw.b_voice1 = TRUE;
674 if (mw->mw.indicator_status & 0x02)
675 cphs_mw.b_fax = TRUE;
677 if (mw->mw.indicator_status & 0x04)
678 cphs_mw.b_data = TRUE;
680 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&cphs_mw, meta_info->data_size);
682 } else if (ef == SIM_EF_USIM_MWIS) {
683 tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw *)&mw->mw, meta_info->rec_length);
684 rec_index = mw->mw.rec_index;
686 encoded_len = meta_info->rec_length;
688 err("Invalid File ID[0x%04x]", ef);
694 case TREQ_SIM_SET_MAILBOX: {
695 const struct treq_sim_set_mailbox *mb = NULL;
697 mb = tcore_user_request_ref_data(ur, NULL);
698 if (ef == SIM_EF_USIM_MBI) {
699 gboolean mbi_changed = FALSE;
700 struct tel_sim_mbi mbi;
703 meta_info->current_index++;
704 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
706 switch (mb->mb_info.mb_type) {
707 case SIM_MAILBOX_VOICE:
708 if (mbi.voice_index != mb->mb_info.rec_index) {
710 mbi.voice_index = mb->mb_info.rec_index;
714 case SIM_MAILBOX_FAX:
715 if (mbi.fax_index != mb->mb_info.rec_index) {
717 mbi.fax_index = mb->mb_info.rec_index;
721 case SIM_MAILBOX_EMAIL:
722 if (mbi.email_index != mb->mb_info.rec_index) {
724 mbi.email_index = mb->mb_info.rec_index;
728 case SIM_MAILBOX_OTHER:
729 if (mbi.other_index != mb->mb_info.rec_index) {
731 mbi.other_index = mb->mb_info.rec_index;
735 case SIM_MAILBOX_VIDEO:
736 if (mbi.video_index != mb->mb_info.rec_index) {
738 mbi.video_index = mb->mb_info.rec_index;
742 case SIM_MAILBOX_DATA:
747 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
748 mbi_changed, meta_info->mbi_list.profile_count,
749 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
750 } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
752 if (mbi_changed == TRUE) {
753 rec_index = meta_info->current_index;
754 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
756 encoded_len = meta_info->rec_length;
758 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
759 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
760 rec_index = mb->mb_info.rec_index;
762 encoded_len = meta_info->rec_length;
763 } else if (ef == SIM_EF_MBDN) {
764 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
765 rec_index = mb->mb_info.rec_index;
767 encoded_len = meta_info->rec_length;
769 err("Invalid File ID[0x%04x]", ef);
776 err("Unhandled update REQUEST command[%d]", command);
777 ret_code = TCORE_RETURN_EINVAL;
782 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
783 if (encoded_data == NULL) {
784 err("Memory allocation failed!!");
789 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
790 util_byte_to_hex(tmp, encoded_data, encoded_len);
793 err("Failed to Encode data");
797 dbg("Encoded Data length =[%d]", encoded_len);
798 tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
801 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
804 case SIM_EF_CPHS_VOICE_MSG_WAITING:
805 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
808 case SIM_EF_USIM_CFIS:
809 case SIM_EF_USIM_MWIS:
810 case SIM_EF_CPHS_MAILBOX_NUMBERS:
812 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
815 case SIM_EF_USIM_MBI:
817 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
819 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
823 err("Unhandled File ID[0x%04x]", ef);
824 ret_code = TCORE_RETURN_EINVAL;
837 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
839 struct tresp_sim_read resp = {0, };
840 struct imc_sim_property *meta_info = NULL;
841 enum tcore_request_command command = TREQ_UNKNOWN;
842 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
844 dbg("EF[0x%x] access Result[%d]", ef, rt);
847 memset(&resp.data, 0x00, sizeof(resp.data));
848 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
849 command = tcore_user_request_get_command(ur);
850 sim_type = tcore_sim_get_type(o);
852 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
853 && (rt != SIM_ACCESS_SUCCESS)) {
854 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
860 if (rt == SIM_ACCESS_SUCCESS) {
861 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
862 if (command == TREQ_SIM_SET_LANGUAGE)
863 __set_file_data(o, ur, ef);
865 _get_file_data(o, ur, ef, 0, meta_info->data_size);
867 if (sim_type == SIM_TYPE_GSM) {
868 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
869 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
870 _get_file_info(o, ur, SIM_EF_LP);
871 } else if (sim_type == SIM_TYPE_USIM) {
873 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05), EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
874 /* EFELPand EFLI not present at this point. */
875 /* po->language.lang_cnt = 0;*/
876 tcore_user_request_send_response(ur, _find_resp_command(ur),
877 sizeof(struct tresp_sim_read), &resp);
883 case SIM_EF_LP: /* same with SIM_EF_USIM_LI */
884 if (rt == SIM_ACCESS_SUCCESS) {
885 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
886 if (command == TREQ_SIM_SET_LANGUAGE)
887 __set_file_data(o, ur, ef);
889 _get_file_data(o, ur, ef, 0, meta_info->data_size);
891 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
893 if (sim_type == SIM_TYPE_GSM) {
894 tcore_user_request_send_response(ur, _find_resp_command(ur),
895 sizeof(struct tresp_sim_read), &resp);
898 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
899 else if (sim_type == SIM_TYPE_USIM) {
900 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
901 _get_file_info(o, ur, SIM_EF_ELP);
907 if (rt == SIM_ACCESS_SUCCESS) {
908 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
909 if (command == TREQ_SIM_SET_LANGUAGE)
910 __set_file_data(o, ur, ef);
912 _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
914 /* EFELIand EFPL not present, so set language count as zero and select ECC */
915 dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
916 tcore_user_request_send_response(ur, _find_resp_command(ur),
917 sizeof(struct tresp_sim_read), &resp);
923 if (sim_type == SIM_TYPE_GSM) {
924 _get_file_data(o, ur, ef, 0, meta_info->data_size);
925 } else if (sim_type == SIM_TYPE_USIM) {
926 if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX)
927 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
929 meta_info->current_index++;
930 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
939 case SIM_EF_CPHS_VOICE_MSG_WAITING:
940 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
941 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
942 case SIM_EF_CPHS_DYNAMICFLAGS:
943 case SIM_EF_CPHS_DYNAMIC2FLAG:
944 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
945 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
946 case SIM_EF_OPLMN_ACT:
947 _get_file_data(o, ur, ef, 0, meta_info->data_size);
950 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
951 if (command == TREQ_SIM_SET_CALLFORWARDING)
952 __set_file_data(o, ur, ef);
954 _get_file_data(o, ur, ef, 0, meta_info->data_size);
957 case SIM_EF_CPHS_CPHS_INFO:
958 if (rt == SIM_ACCESS_SUCCESS) {
959 tcore_sim_set_cphs_status(o, TRUE);
960 if (!tcore_user_request_ref_communicator(ur)) {
961 dbg("internal CPHS INFO request before sim status update");
962 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
964 dbg("external CPHS INFO request");
965 _get_file_data(o, ur, ef, 0, meta_info->data_size);
968 tcore_sim_set_cphs_status(o, FALSE);
969 if (!tcore_user_request_ref_communicator(ur)) {
970 dbg("internal CPHS INFO request before sim status update");
971 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
973 dbg("external CPHS INFO request");
974 tcore_user_request_send_response(ur, _find_resp_command(ur),
975 sizeof(struct tresp_sim_read), &resp);
980 case SIM_EF_USIM_CFIS:
981 if (command == TREQ_SIM_SET_CALLFORWARDING) {
982 __set_file_data(o, ur, ef);
984 if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX)
985 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
987 meta_info->current_index++;
988 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
992 case SIM_EF_USIM_MWIS:
993 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
994 __set_file_data(o, ur, ef);
996 meta_info->current_index++;
997 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1001 case SIM_EF_USIM_MBI:
1002 if (command == TREQ_SIM_SET_MAILBOX) {
1003 __set_file_data(o, ur, ef);
1005 meta_info->current_index++;
1006 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1012 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1014 meta_info->current_index++;
1015 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1019 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1020 if (command == TREQ_SIM_SET_MAILBOX) {
1021 /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1022 if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1023 err("Cyclic File ID. No update & return error.");
1024 meta_info->files.result = SIM_ACCESS_FAILED;
1025 tcore_user_request_send_response(ur, _find_resp_command(ur),
1026 sizeof(struct tresp_sim_read), &meta_info->files);
1029 __set_file_data(o, ur, ef);
1033 meta_info->mb_count = 0;
1034 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1035 if (meta_info->current_index == 0) {
1036 err("Invalid MBDN index");
1037 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1038 tcore_user_request_send_response(ur, _find_resp_command(ur),
1039 sizeof(struct tresp_sim_read), &meta_info->files);
1041 ur = tcore_user_request_ref(ur);
1042 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1044 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1049 dbg("error - File id for get file info [0x%x]", ef);
1054 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1056 struct imc_sim_property *meta_info = NULL;
1060 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1061 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1062 switch (meta_info->file_id) {
1064 case SIM_EF_USIM_PL:
1066 case SIM_EF_USIM_LI:
1067 if (decode_ret == TRUE) {
1069 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1070 /* po->language_file = SIM_EF_LP;*/
1071 else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL)
1072 /* po->language_file = SIM_EF_ELP;*/
1074 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1077 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1078 - EFELP is not available;
1079 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1080 - the ME does not support any of the languages in EFELP.
1083 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1084 - if the EFLI has the value 'FFFF' in its highest priority position
1085 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1087 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1088 if (meta_info->file_id == SIM_EF_LP)
1089 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1091 _get_file_info(o, ur, SIM_EF_LP);
1092 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1093 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1094 _get_file_info(o, ur, SIM_EF_ELP);
1096 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1102 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1103 if (meta_info->current_index == meta_info->rec_count) {
1104 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1106 meta_info->current_index++;
1107 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1109 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1110 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1112 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1117 ur = tcore_user_request_new(NULL, NULL); /* this is for using ur metainfo set/ref functionality. */
1118 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1122 if (meta_info->current_index == meta_info->rec_count) {
1123 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1125 meta_info->current_index++;
1126 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1131 if (meta_info->current_index == meta_info->rec_count) {
1132 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1134 meta_info->current_index++;
1135 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1140 if (meta_info->current_index == meta_info->rec_count) {
1141 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1143 meta_info->current_index++;
1144 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1148 case SIM_EF_USIM_MBI:
1149 if (meta_info->current_index == meta_info->rec_count) {
1150 _get_file_info(0, ur, SIM_EF_MBDN);
1152 meta_info->current_index++;
1153 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1158 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1159 if (meta_info->mb_count == meta_info->mb_data.count) {
1160 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1161 tcore_user_request_send_response(ur, _find_resp_command(ur),
1162 sizeof(struct tresp_sim_read), &meta_info->files);
1164 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1165 if (meta_info->current_index == 0) {
1166 err("Invalid MBDN index");
1167 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1168 tcore_user_request_send_response(ur, _find_resp_command(ur),
1169 sizeof(struct tresp_sim_read), &meta_info->files);
1171 ur = tcore_user_request_ref(ur);
1172 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1177 case SIM_EF_USIM_CFIS:
1178 case SIM_EF_USIM_MWIS:
1179 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1180 if (meta_info->current_index == meta_info->rec_count) {
1181 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1183 meta_info->current_index++;
1184 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1188 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1189 meta_info->files.result = rt;
1190 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1193 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1194 if (rt == SIM_ACCESS_SUCCESS)
1195 meta_info->files.result = SIM_ACCESS_SUCCESS;
1197 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1204 case SIM_EF_OPLMN_ACT:
1205 case SIM_EF_CPHS_CPHS_INFO:
1206 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1207 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1208 case SIM_EF_CPHS_DYNAMICFLAGS:
1209 case SIM_EF_CPHS_DYNAMIC2FLAG:
1210 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1211 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1212 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1216 dbg("File id not handled [0x%x]", meta_info->file_id);
1221 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1223 struct tnoti_sim_status noti_data = {0, };
1225 if (sim_status != tcore_sim_get_status(o)) {
1226 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1227 tcore_sim_get_status(o), sim_status);
1229 /* Update SIM Status */
1230 tcore_sim_set_status(o, sim_status);
1231 noti_data.sim_status = sim_status;
1233 /* Send notification */
1234 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1235 o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
1239 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1241 const TcoreATResponse *resp = data;
1242 UserRequest *ur = NULL;
1243 CoreObject *o = NULL;
1244 GSList *tokens = NULL;
1245 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1251 o = tcore_pending_ref_core_object(p);
1252 ur = tcore_pending_ref_user_request(p);
1254 if (resp->success > 0) {
1257 line = (const char *)resp->lines->data;
1258 tokens = tcore_at_tok_new(line);
1259 if (g_slist_length(tokens) != 1) {
1260 msg("Invalid message");
1261 tcore_at_tok_free(tokens);
1265 state = atoi(g_slist_nth_data(tokens, 0));
1266 dbg("SIM Type is %d", state);
1269 sim_type = SIM_TYPE_GSM;
1270 tcore_sim_set_app_list(o, SIM_APP_TYPE_SIM);
1271 } else if (state == 1) {
1272 sim_type = SIM_TYPE_USIM;
1273 tcore_sim_set_app_list(o, SIM_APP_TYPE_USIM);
1275 sim_type = SIM_TYPE_UNKNOWN;
1278 dbg("RESPONSE NOK");
1279 sim_type = SIM_TYPE_UNKNOWN;
1282 tcore_sim_set_type(o, sim_type);
1284 if (sim_type != SIM_TYPE_UNKNOWN) {
1285 /* set user request for using ur metainfo set/ref functionality */
1286 ur = tcore_user_request_new(NULL, NULL);
1287 _get_file_info(o, ur, SIM_EF_IMSI);
1290 tcore_at_tok_free(tokens);
1294 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1296 const TcoreATResponse *resp = data;
1297 UserRequest *ur = NULL;
1298 CoreObject *o = NULL;
1299 struct imc_sim_property *meta_info = NULL;
1300 GSList *tokens = NULL;
1301 enum tel_sim_access_result rt;
1302 const char *line = NULL;
1308 o = tcore_pending_ref_core_object(p);
1309 ur = tcore_pending_ref_user_request(p);
1310 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1312 if (resp->success > 0) {
1315 line = (const char *)resp->lines->data;
1316 tokens = tcore_at_tok_new(line);
1317 if (g_slist_length(tokens) < 2) {
1318 err("Invalid message");
1319 tcore_at_tok_free(tokens);
1323 sw1 = atoi(g_slist_nth_data(tokens, 0));
1324 sw2 = atoi(g_slist_nth_data(tokens, 1));
1326 /*1. SIM access success case*/
1327 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1328 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1329 unsigned short record_len = 0;
1330 char num_of_records = 0;
1331 unsigned char file_id_len = 0;
1332 unsigned short file_id = 0;
1333 unsigned short file_size = 0;
1334 unsigned short file_type = 0;
1335 unsigned short arr_file_id = 0;
1337 /* handling only last 3 bits */
1338 unsigned char file_type_tag = 0x07;
1339 unsigned char *ptr_data;
1343 char *recordData = NULL;
1344 hexData = g_slist_nth_data(tokens, 2);
1345 dbg("hexData: %s", hexData);
1346 dbg("hexData: %s", hexData + 1);
1348 tmp = tcore_at_tok_extract(hexData);
1349 recordData = util_hexStringToBytes(tmp);
1351 err("util_hexStringToBytes Failed!!");
1352 tcore_at_tok_free(tokens);
1355 tcore_util_hex_dump(" ", strlen(hexData) / 2, recordData);
1358 ptr_data = (unsigned char *)recordData;
1359 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1361 ETSI TS 102 221 v7.9.0
1363 '62' FCP template tag
1364 - Response for an EF
1365 '82' M File Descriptor
1366 '83' M File Identifier
1367 'A5' O Proprietary information
1368 '8A' M Life Cycle Status Integer
1369 '8B', '8C' or 'AB' C1 Security attributes
1371 '81' O Total file size
1372 '88' O Short File Identifier (SFI)
1375 /* rsim.res_len has complete data length received */
1377 /* FCP template tag - File Control Parameters tag*/
1378 if (*ptr_data == 0x62) {
1379 /* parse complete FCP tag*/
1380 /* increment to next byte */
1382 tag_len = *ptr_data++;
1383 dbg("tag_len: %02x", tag_len);
1384 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1385 if (*ptr_data == 0x82) {
1386 /* increment to next byte */
1390 /* unsigned char file_desc_len = *ptr_data++;*/
1391 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1392 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1393 /* consider only last 3 bits*/
1394 dbg("file_type_tag: %02x", file_type_tag);
1395 file_type_tag = file_type_tag & (*ptr_data);
1396 dbg("file_type_tag: %02x", file_type_tag);
1398 switch (file_type_tag) {
1399 /* increment to next byte */
1401 dbg("Getting FileType: [Transparent file type]");
1402 file_type = SIM_FTYPE_TRANSPARENT;
1404 /* increment to next byte */
1406 /* increment to next byte */
1411 dbg("Getting FileType: [Linear fixed file type]");
1412 /* increment to next byte */
1414 /* data coding byte - value 21 */
1417 memcpy(&record_len, ptr_data, 2);
1419 SWAPBYTES16(record_len);
1420 ptr_data = ptr_data + 2;
1421 num_of_records = *ptr_data++;
1422 /* Data lossy conversation from enum (int) to unsigned char */
1423 file_type = SIM_FTYPE_LINEAR_FIXED;
1427 dbg("Cyclic fixed file type");
1428 /* increment to next byte */
1430 /* data coding byte - value 21 */
1433 memcpy(&record_len, ptr_data, 2);
1435 SWAPBYTES16(record_len);
1436 ptr_data = ptr_data + 2;
1437 num_of_records = *ptr_data++;
1438 file_type = SIM_FTYPE_CYCLIC;
1442 dbg("not handled file type [0x%x]", *ptr_data);
1446 dbg("INVALID FCP received - DEbug!");
1447 tcore_at_tok_free(tokens);
1453 * File identifier - file id??
1455 * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1457 if (*ptr_data == 0x83) {
1458 /* increment to next byte */
1460 file_id_len = *ptr_data++;
1461 dbg("file_id_len: %02x", file_id_len);
1463 memcpy(&file_id, ptr_data, file_id_len);
1464 dbg("file_id: %x", file_id);
1467 SWAPBYTES16(file_id);
1468 dbg("file_id: %x", file_id);
1470 ptr_data = ptr_data + 2;
1471 dbg("Getting FileID=[0x%x]", file_id);
1473 dbg("INVALID FCP received - DEbug!");
1474 tcore_at_tok_free(tokens);
1479 /* proprietary information */
1480 if (*ptr_data == 0xA5) {
1481 unsigned short prop_len;
1482 /* increment to next byte */
1486 prop_len = *ptr_data;
1487 dbg("prop_len: %02x", prop_len);
1490 ptr_data = ptr_data + prop_len + 1;
1492 dbg("INVALID FCP received - DEbug!");
1495 /* life cycle status integer [8A][length:0x01][status]*/
1498 00000000 : No information given
1499 00000001 : creation state
1500 00000011 : initialization state
1501 000001-1 : operation state -activated
1502 000001-0 : operation state -deactivated
1503 000011-- : Termination state
1504 b8~b5 !=0, b4~b1=X : Proprietary
1505 Any other value : RFU
1507 if (*ptr_data == 0x8A) {
1508 /* increment to next byte */
1510 /* length - value 1 */
1513 switch (*ptr_data) {
1516 dbg("<RX> operation state -deactivated");
1522 dbg("<RX> operation state -activated");
1527 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1533 /* related to security attributes : currently not handled*/
1534 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1535 /* increment to next byte */
1537 /* if tag length is 3 */
1538 if (*ptr_data == 0x03) {
1539 /* increment to next byte */
1542 memcpy(&arr_file_id, ptr_data, 2);
1544 SWAPBYTES16(arr_file_id);
1545 ptr_data = ptr_data + 2;
1546 ptr_data++; /*arr_file_id_rec_num = *ptr_data++; */
1548 /* if tag length is not 3 */
1549 /* ignoring bytes */
1550 dbg("Useless security attributes, so jump to next tag");
1551 ptr_data = ptr_data + (*ptr_data + 1);
1554 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1555 tcore_at_tok_free(tokens);
1560 dbg("Current ptr_data value is [%x]", *ptr_data);
1562 /* file size excluding structural info*/
1563 if (*ptr_data == 0x80) {
1564 /* for EF file size is body of file and for Linear or cyclic it is
1565 * number of recXsizeof(one record)
1567 /* increment to next byte */
1569 /* length is 1 byte - value is 2 bytes or more */
1571 memcpy(&file_size, ptr_data, 2);
1573 SWAPBYTES16(file_size);
1574 ptr_data = ptr_data + 2;
1576 dbg("INVALID FCP received - DEbug!");
1577 tcore_at_tok_free(tokens);
1582 /* total file size including structural info*/
1583 if (*ptr_data == 0x81) {
1585 /* increment to next byte */
1588 /* len = *ptr_data; */
1590 ptr_data = ptr_data + 3;
1592 dbg("INVALID FCP received - DEbug!");
1593 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1596 /*short file identifier ignored*/
1597 if (*ptr_data == 0x88) {
1598 dbg("0x88: Do Nothing");
1602 dbg("INVALID FCP received - DEbug!");
1603 tcore_at_tok_free(tokens);
1607 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1608 unsigned char gsm_specific_file_data_len = 0;
1609 /* ignore RFU byte1 and byte2 */
1613 memcpy(&file_size, ptr_data, 2);
1615 SWAPBYTES16(file_size);
1616 /* parsed file size */
1617 ptr_data = ptr_data + 2;
1619 memcpy(&file_id, ptr_data, 2);
1620 SWAPBYTES16(file_id);
1621 dbg("FILE id --> [%x]", file_id);
1622 ptr_data = ptr_data + 2;
1623 /* save file type - transparent, linear fixed or cyclic */
1624 file_type_tag = (*(ptr_data + 7));
1626 switch (*ptr_data) {
1629 dbg("RFU file type- not handled - Debug!");
1634 dbg("MF file type - not handled - Debug!");
1639 dbg("DF file type - not handled - Debug!");
1644 dbg("EF file type [%d] ", file_type_tag);
1645 /* increment to next byte */
1648 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1649 /* increament to next byte as this byte is RFU */
1652 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1654 /* increment to next byte */
1656 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1657 /* the INCREASE command is allowed on the selected cyclic file. */
1658 file_type = SIM_FTYPE_CYCLIC;
1660 /* bytes 9 to 11 give SIM file access conditions */
1662 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1664 /* byte 11 is invalidate and rehabilate nibbles */
1666 /* byte 12 - file status */
1668 /* byte 13 - GSM specific data */
1669 gsm_specific_file_data_len = *ptr_data;
1670 dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1672 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1674 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1675 record_len = *ptr_data;
1676 dbg("record length[%d], file size[%d]", record_len, file_size);
1678 if (record_len != 0)
1679 num_of_records = (file_size / record_len);
1681 dbg("Number of records [%d]", num_of_records);
1685 dbg("not handled file type");
1689 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1692 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1693 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1695 meta_info->file_type = file_type;
1696 meta_info->data_size = file_size;
1697 meta_info->rec_length = record_len;
1698 meta_info->rec_count = num_of_records;
1699 meta_info->current_index = 0; /* reset for new record type EF */
1700 rt = SIM_ACCESS_SUCCESS;
1703 /*2. SIM access fail case*/
1704 dbg("error to get ef[0x%x]", meta_info->file_id);
1705 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1706 rt = _decode_status_word(sw1, sw2);
1708 ur = tcore_user_request_ref(ur);
1710 dbg("Calling _next_from_get_file_info");
1711 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1712 tcore_at_tok_free(tokens);
1714 dbg("RESPONSE NOK");
1715 dbg("error to get ef[0x%x]", meta_info->file_id);
1716 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1717 rt = SIM_ACCESS_FAILED;
1719 ur = tcore_user_request_ref(ur);
1720 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1725 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1727 const TcoreATResponse *resp = data;
1728 UserRequest *ur = NULL;
1729 CoreObject *o = NULL;
1730 struct imc_sim_property *meta_info = NULL;
1731 GSList *tokens = NULL;
1732 enum tel_sim_access_result rt;
1733 gboolean dr = FALSE;
1734 const char *line = NULL;
1743 o = tcore_pending_ref_core_object(p);
1744 ur = tcore_pending_ref_user_request(p);
1745 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1747 if (resp->success > 0) {
1750 line = (const char *)resp->lines->data;
1751 tokens = tcore_at_tok_new(line);
1752 if (g_slist_length(tokens) != 3) {
1753 msg("Invalid message");
1754 tcore_at_tok_free(tokens);
1758 sw1 = atoi(g_slist_nth_data(tokens, 0));
1759 sw2 = atoi(g_slist_nth_data(tokens, 1));
1760 res = g_slist_nth_data(tokens, 2);
1762 tmp = tcore_at_tok_extract(res);
1765 res = util_hexStringToBytes(tmp);
1766 res_len = strlen(tmp) / 2;
1767 dbg("Response: [%s] Response length: [%d]", res, res_len);
1769 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1770 rt = SIM_ACCESS_SUCCESS;
1771 meta_info->files.result = rt;
1773 dbg("File ID: [0x%x]", meta_info->file_id);
1774 switch (meta_info->file_id) {
1777 struct tel_sim_imsi *imsi = NULL;
1779 dbg("Data: [%s]", res);
1780 imsi = g_try_new0(struct tel_sim_imsi, 1);
1781 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1783 err("IMSI decoding failed");
1785 _sim_check_identity(o, imsi);
1786 tcore_sim_set_imsi(o, imsi);
1795 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1798 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1799 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1800 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1801 case SIM_EF_LP: /* 1 byte encoding */
1802 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1803 && (meta_info->file_id == SIM_EF_LP)) {
1805 * 2G LP(0x6F05) has 1 byte for each language
1807 dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1808 (unsigned char *)res, res_len);
1811 * 3G LI(0x6F05)/PL(0x2F05),
1812 * 2G ELP(0x2F05) has 2 bytes for each language
1814 dr = tcore_sim_decode_li(meta_info->file_id,
1815 &meta_info->files.data.language,
1816 (unsigned char *)res, res_len);
1821 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1822 (unsigned char *)res, res_len);
1826 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1827 (unsigned char *)res, res_len);
1830 case SIM_EF_SST: /* EF UST has same address */
1832 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1833 dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1835 dbg("SST decoding failed");
1836 tcore_sim_set_service_table(o, NULL);
1838 int i = 0, size = sizeof(struct tel_sim_sst);
1840 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1841 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1842 memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1843 for (i = 0; i < size; i++) {
1849 dbg("svct.table.sst=[%s]", temp);
1852 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1854 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1855 dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1857 dbg("SST decoding failed");
1858 tcore_sim_set_service_table(o, NULL);
1860 int i = 0, size = sizeof(struct tel_sim_ust);
1862 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1863 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1864 memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1865 for (i = 0; i < size; i++) {
1871 dbg("svct.table.ust=[%s]", temp);
1874 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1877 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(o));
1884 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1885 dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1886 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1887 struct tel_sim_ecc *ecc = NULL;
1889 ecc = g_try_new0(struct tel_sim_ecc, 1);
1890 dbg("Index [%d]", meta_info->current_index);
1892 dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1894 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1895 meta_info->files.data.ecc.ecc_count++;
1901 dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1908 struct tel_sim_msisdn *msisdn = NULL;
1910 dbg("Index [%d]", meta_info->current_index);
1911 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1912 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1914 memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1915 msisdn, sizeof(struct tel_sim_msisdn));
1917 meta_info->files.data.msisdn_list.count++;
1927 struct tel_sim_opl *opl = NULL;
1929 dbg("decode w/ index [%d]", meta_info->current_index);
1931 opl = g_try_new0(struct tel_sim_opl, 1);
1932 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1934 memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1935 opl, sizeof(struct tel_sim_opl));
1936 meta_info->files.data.opl.opl_count++;
1946 struct tel_sim_pnn *pnn = NULL;
1948 dbg("decode w/ index [%d]", meta_info->current_index);
1950 pnn = g_try_new0(struct tel_sim_pnn, 1);
1951 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1953 memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1954 pnn, sizeof(struct tel_sim_pnn));
1956 meta_info->files.data.pnn.pnn_count++;
1964 case SIM_EF_OPLMN_ACT:
1965 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1966 (unsigned char *)res, res_len);
1969 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1970 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1973 case SIM_EF_USIM_MBI: /* linear type */
1975 struct tel_sim_mbi *mbi = NULL;
1977 mbi = g_try_new0(struct tel_sim_mbi, 1);
1978 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
1980 memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
1981 mbi, sizeof(struct tel_sim_mbi));
1982 meta_info->mbi_list.profile_count++;
1984 dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
1985 dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].voice_index);
1986 dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].fax_index);
1987 dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].email_index);
1988 dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].other_index);
1989 dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].video_index);
1997 case SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1998 case SIM_EF_MBDN: /* linear type */
1999 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
2000 (unsigned char *)res, res_len);
2001 meta_info->mb_count++;
2004 case SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
2005 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
2006 (unsigned char *)res, res_len);
2009 case SIM_EF_USIM_MWIS: /* linear type */
2011 struct tel_sim_mw *mw = NULL;
2013 mw = g_try_new0(struct tel_sim_mw, 1);
2015 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
2017 memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
2018 meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
2019 meta_info->files.data.mw.mw_list.profile_count++;
2027 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
2028 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2029 (unsigned char *)res, res_len);
2032 case SIM_EF_USIM_CFIS: /* linear type */
2034 struct tel_sim_cfis *cf = NULL;
2036 cf = g_try_new0(struct tel_sim_cfis, 1);
2037 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2039 memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2040 cf, sizeof(struct tel_sim_cfis));
2042 meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2043 meta_info->files.data.cf.cf_list.profile_count++;
2051 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2052 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2055 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2056 dr = tcore_sim_decode_ons((unsigned char *)&meta_info->files.data.cphs_net.full_name,
2057 (unsigned char *)res, res_len);
2058 dbg("meta_info->files.result[%d], meta_info->files.data.cphs_net.full_name[%s]",
2059 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2062 case SIM_EF_CPHS_DYNAMICFLAGS:
2063 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2064 p_data->response, p_data->response_len);*/
2067 case SIM_EF_CPHS_DYNAMIC2FLAG:
2068 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2069 p_data->response_len);*/
2072 case SIM_EF_CPHS_CPHS_INFO:
2073 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2074 (unsigned char *)res, res_len);
2077 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2078 dr = tcore_sim_decode_short_ons((unsigned char *)&meta_info->files.data.cphs_net.short_name,
2079 (unsigned char *)res, res_len);
2082 case SIM_EF_CPHS_INFORMATION_NUMBERS:
2083 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2087 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2092 rt = _decode_status_word(sw1, sw2);
2093 meta_info->files.result = rt;
2101 tcore_at_tok_free(tokens);
2103 dbg("RESPONSE NOK");
2104 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2105 rt = SIM_ACCESS_FAILED;
2108 /* Reference User Request */
2109 ur = tcore_user_request_ref(ur);
2112 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2117 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2119 const TcoreATResponse *resp = data;
2120 UserRequest *ur = NULL;
2121 CoreObject *o = NULL;
2122 struct imc_sim_property *sp = NULL;
2123 GSList *tokens = NULL;
2124 const char *line = NULL;
2126 int attempts_left = 0;
2127 int time_penalty = 0;
2131 o = tcore_pending_ref_core_object(p);
2132 sp = tcore_sim_ref_userdata(o);
2134 err("user data is null");
2137 ur = tcore_pending_ref_user_request(p);
2139 if (resp->success > 0) {
2142 line = (const char *)resp->lines->data;
2143 tokens = tcore_at_tok_new(line);
2144 if (g_slist_length(tokens) < 3) {
2145 msg("Invalid message");
2146 tcore_at_tok_free(tokens);
2150 lock_type = atoi(g_slist_nth_data(tokens, 0));
2151 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2152 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2154 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2155 lock_type, attempts_left, time_penalty);
2157 switch (sp->current_sec_op) {
2158 case SEC_PIN1_VERIFY:
2159 case SEC_PIN2_VERIFY:
2160 case SEC_SIM_VERIFY:
2161 case SEC_ADM_VERIFY:
2163 struct tresp_sim_verify_pins v_pin = {0, };
2165 v_pin.result = SIM_INCORRECT_PASSWORD;
2166 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2167 v_pin.retry_count = attempts_left;
2168 tcore_user_request_send_response(ur, _find_resp_command(ur),
2169 sizeof(struct tresp_sim_verify_pins), &v_pin);
2173 case SEC_PUK1_VERIFY:
2174 case SEC_PUK2_VERIFY:
2176 struct tresp_sim_verify_puks v_puk = {0, };
2178 v_puk.result = SIM_INCORRECT_PASSWORD;
2179 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2180 v_puk.retry_count = attempts_left;
2181 tcore_user_request_send_response(ur, _find_resp_command(ur),
2182 sizeof(struct tresp_sim_verify_puks), &v_puk);
2186 case SEC_PIN1_CHANGE:
2187 case SEC_PIN2_CHANGE:
2189 struct tresp_sim_change_pins change_pin = {0, };
2191 change_pin.result = SIM_INCORRECT_PASSWORD;
2192 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2193 change_pin.retry_count = attempts_left;
2194 tcore_user_request_send_response(ur, _find_resp_command(ur),
2195 sizeof(struct tresp_sim_change_pins), &change_pin);
2199 case SEC_PIN1_DISABLE:
2200 case SEC_PIN2_DISABLE:
2201 case SEC_FDN_DISABLE:
2202 case SEC_SIM_DISABLE:
2203 case SEC_NET_DISABLE:
2204 case SEC_NS_DISABLE:
2205 case SEC_SP_DISABLE:
2206 case SEC_CP_DISABLE:
2208 struct tresp_sim_disable_facility dis_facility = {0, };
2210 dis_facility.result = SIM_INCORRECT_PASSWORD;
2211 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2212 dis_facility.retry_count = attempts_left;
2213 tcore_user_request_send_response(ur, _find_resp_command(ur),
2214 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2218 case SEC_PIN1_ENABLE:
2219 case SEC_PIN2_ENABLE:
2220 case SEC_FDN_ENABLE:
2221 case SEC_SIM_ENABLE:
2222 case SEC_NET_ENABLE:
2227 struct tresp_sim_enable_facility en_facility = {0, };
2229 en_facility.result = SIM_INCORRECT_PASSWORD;
2230 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2231 en_facility.retry_count = attempts_left;
2232 tcore_user_request_send_response(ur, _find_resp_command(ur),
2233 sizeof(struct tresp_sim_enable_facility), &en_facility);
2238 dbg("not handled sec op[%d]", sp->current_sec_op);
2243 tcore_at_tok_free(tokens);
2249 static gboolean _get_sim_type(CoreObject *o)
2251 TcoreHal *hal = NULL;
2252 TcoreATRequest *req = NULL;
2253 TcorePending *pending = NULL;
2254 UserRequest *ur = NULL;
2255 char *cmd_str = NULL;
2259 hal = tcore_object_get_hal(o);
2260 pending = tcore_pending_new(o, 0);
2262 err("Pending is NULL");
2265 cmd_str = g_strdup_printf("AT+XUICC?");
2266 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2268 tcore_pending_free(pending);
2274 dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2275 req->cmd, req->prefix, strlen(req->cmd));
2277 tcore_pending_set_request_data(pending, 0, req);
2278 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2279 tcore_pending_link_user_request(pending, ur);
2280 tcore_hal_send_request(hal, pending);
2286 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2288 TcoreHal *hal = NULL;
2289 TcorePending *pending = NULL;
2290 struct imc_sim_property meta_info = {0, };
2291 char *cmd_str = NULL;
2292 TReturn ret = TCORE_RETURN_FAILURE;
2297 meta_info.file_id = ef;
2298 dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2299 hal = tcore_object_get_hal(o);
2300 dbg("hal: %x", hal);
2302 trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2303 dbg("trt[%d]", trt);
2304 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
2305 dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2307 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2308 tcore_pending_link_user_request(pending, ur);
2309 ret = tcore_hal_send_request(hal, pending);
2310 if (TCORE_RETURN_SUCCESS != ret)
2311 tcore_user_request_free(ur);
2315 return TCORE_RETURN_SUCCESS;
2318 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2320 TcoreHal *hal = NULL;
2321 TcoreATRequest *req = NULL;
2322 TcorePending *pending = NULL;
2323 char *cmd_str = NULL;
2329 hal = tcore_object_get_hal(o);
2330 pending = tcore_pending_new(o, 0);
2332 err("Pending is NULL");
2336 dbg("file_id: %x", ef);
2338 p1 = (unsigned char) (offset & 0xFF00) >> 8;
2339 p2 = (unsigned char) offset & 0x00FF; /* offset low */
2340 p3 = (unsigned char) length;
2342 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
2344 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2346 tcore_pending_free(pending);
2352 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2353 req->cmd, req->prefix, strlen(req->cmd));
2355 tcore_pending_set_request_data(pending, 0, req);
2356 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2357 tcore_pending_link_user_request(pending, ur);
2358 tcore_hal_send_request(hal, pending);
2364 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2366 TcoreHal *hal = NULL;
2367 TcoreATRequest *req = NULL;
2368 TcorePending *pending = NULL;
2369 char *cmd_str = NULL;
2376 hal = tcore_object_get_hal(o);
2377 pending = tcore_pending_new(o, 0);
2379 err("Pending is NULL");
2383 p1 = (unsigned char) index;
2384 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
2385 p3 = (unsigned char) length;
2387 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
2389 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2391 tcore_pending_free(pending);
2397 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2398 req->cmd, req->prefix, strlen(req->cmd));
2400 tcore_pending_set_request_data(pending, 0, req);
2401 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2402 tcore_pending_link_user_request(pending, ur);
2403 tcore_hal_send_request(hal, pending);
2409 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2411 TcoreHal *hal = NULL;
2412 TcoreATRequest *req = NULL;
2413 TcorePending *pending = NULL;
2414 char *cmd_str = NULL;
2416 struct imc_sim_property *sp = NULL;
2420 hal = tcore_object_get_hal(o);
2421 pending = tcore_pending_new(o, 0);
2423 err("Pending is NULL");
2424 return TCORE_RETURN_FAILURE;
2426 sp = tcore_sim_ref_userdata(o);
2428 err("user data is null");
2429 tcore_pending_free(pending);
2430 return TCORE_RETURN_FAILURE;
2433 switch (sp->current_sec_op) {
2434 case SEC_PIN1_VERIFY:
2435 case SEC_PIN1_CHANGE:
2436 case SEC_PIN1_ENABLE:
2437 case SEC_PIN1_DISABLE:
2441 case SEC_PIN2_VERIFY:
2442 case SEC_PIN2_CHANGE:
2443 case SEC_PIN2_ENABLE:
2444 case SEC_PIN2_DISABLE:
2445 case SEC_FDN_ENABLE:
2446 case SEC_FDN_DISABLE:
2450 case SEC_PUK1_VERIFY:
2454 case SEC_PUK2_VERIFY:
2458 case SEC_NET_ENABLE:
2459 case SEC_NET_DISABLE:
2464 case SEC_NS_DISABLE:
2469 case SEC_SP_DISABLE:
2474 case SEC_CP_DISABLE:
2478 case SEC_ADM_VERIFY:
2486 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2487 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2489 tcore_pending_free(pending);
2491 return TCORE_RETURN_FAILURE;
2495 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2496 req->cmd, req->prefix, strlen(req->cmd));
2498 tcore_pending_set_request_data(pending, 0, req);
2499 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2500 tcore_pending_link_user_request(pending, ur);
2501 tcore_hal_send_request(hal, pending);
2504 return TCORE_RETURN_SUCCESS;
2507 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2510 GSList *tokens = NULL;
2511 GSList *lines = NULL;
2513 dbg("Function entry");
2515 lines = (GSList *)event_info;
2516 if (1 != g_slist_length(lines)) {
2517 dbg("unsolicited msg but multiple line");
2520 line = (char *)(lines->data);
2521 tokens = tcore_at_tok_new(line);
2522 if (g_slist_length(tokens) != 1) {
2523 msg("Invalid message");
2524 tcore_at_tok_free(tokens);
2531 tcore_at_tok_free(tokens);
2535 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2536 unsigned int sms_ready)
2538 Server *server = tcore_plugin_ref_server(plugin);
2539 struct tnoti_sms_ready_status sms_ready_noti;
2544 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2545 if (co_sms == NULL) {
2546 err("Can't find SMS core object");
2550 if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2553 tcore_sms_set_ready_status(co_sms, sms_ready);
2555 if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2556 sms_ready_noti.status = sms_ready;
2557 tcore_server_send_notification(server, co_sms,
2558 TNOTI_SMS_DEVICE_READY,
2559 sizeof(sms_ready_noti),
2566 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2568 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2569 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2570 GSList *tokens = NULL;
2574 enum telephony_sms_ready_status sms_state = 0;
2578 lines = (GSList *)event_info;
2579 if (g_slist_length(lines) != 1) {
2580 err("Unsolicited message BUT multiple lines");
2586 /* Create 'tokens' */
2587 tokens = tcore_at_tok_new(line);
2590 if (g_slist_length(tokens) == 4) {
2591 sim_state = atoi(g_slist_nth_data(tokens, 1));
2592 sms_state = atoi(g_slist_nth_data(tokens, 3));
2594 notify_sms_state(plugin, o, sms_state);
2595 } else if (g_slist_length(tokens) == 1) {
2596 sim_state = atoi(g_slist_nth_data(tokens, 0));
2598 err("Invalid message");
2602 switch (sim_state) {
2604 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2609 sim_status = SIM_STATUS_PIN_REQUIRED;
2610 dbg("PIN REQUIRED");
2614 sim_status = SIM_STATUS_INITIALIZING;
2615 dbg("PIN DISABLED AT BOOT UP");
2619 sim_status = SIM_STATUS_INITIALIZING;
2620 dbg("PIN VERIFIED");
2624 sim_status = SIM_STATUS_PUK_REQUIRED;
2625 dbg("PUK REQUIRED");
2629 sim_status = SIM_STATUS_CARD_BLOCKED;
2630 dbg("CARD PERMANENTLY BLOCKED");
2634 sim_status = SIM_STATUS_CARD_ERROR;
2635 dbg("SIM CARD ERROR");
2639 sim_status = SIM_STATUS_INIT_COMPLETED;
2640 dbg("SIM INIT COMPLETED");
2644 sim_status = SIM_STATUS_CARD_ERROR;
2645 dbg("SIM CARD ERROR");
2649 sim_status = SIM_STATUS_CARD_REMOVED;
2654 dbg("SIM SMS Ready");
2655 notify_sms_state(plugin, o, SMS_STATE_READY);
2659 sim_status = SIM_STATUS_UNKNOWN;
2660 dbg("SIM STATE UNKNOWN");
2664 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2668 switch (sim_status) {
2669 case SIM_STATUS_INIT_COMPLETED:
2670 dbg("[SIM] SIM INIT COMPLETED");
2671 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2678 case SIM_STATUS_CARD_REMOVED:
2679 dbg("[SIM] SIM CARD REMOVED");
2680 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2683 case SIM_STATUS_CARD_NOT_PRESENT:
2684 dbg("[SIM] SIM CARD NOT PRESENT");
2685 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2688 case SIM_STATUS_CARD_ERROR:
2689 dbg("[SIM] SIM CARD ERROR");
2690 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2694 dbg("SIM Status: [0x%02x]", sim_status);
2698 _sim_status_update(o, sim_status);
2701 tcore_at_tok_free(tokens);
2707 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2709 const TcoreATResponse *resp = data;
2710 CoreObject *o = NULL;
2714 o = tcore_pending_ref_core_object(p);
2716 if (resp->success > 0) {
2719 on_event_pin_status(o, resp->lines, NULL);
2721 dbg("RESPONSE NOK");
2727 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2728 unsigned int data_len, void *data, void *user_data)
2730 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2731 CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2734 return TCORE_HOOK_RETURN_CONTINUE;
2736 dbg("Get SIM status");
2738 sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2740 return TCORE_HOOK_RETURN_CONTINUE;
2743 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2745 const TcoreATResponse *resp = data;
2746 UserRequest *ur = NULL;
2747 CoreObject *co_sim = NULL;
2748 struct imc_sim_property *sp = NULL;
2749 GSList *tokens = NULL;
2750 struct tresp_sim_verify_pins res;
2756 co_sim = tcore_pending_ref_core_object(p);
2757 sp = tcore_sim_ref_userdata(co_sim);
2759 err("user data is null");
2763 ur = tcore_pending_ref_user_request(p);
2765 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2767 if (resp->success > 0) {
2769 res.result = SIM_PIN_OPERATION_SUCCESS;
2771 /* Get PIN facility */
2772 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2773 if ((res.pin_type == SIM_PTYPE_PIN1)
2774 || (res.pin_type == SIM_PTYPE_SIM)) {
2775 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2776 /* Update SIM Status */
2777 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2782 tcore_user_request_send_response(ur, _find_resp_command(ur),
2783 sizeof(struct tresp_sim_verify_pins), &res);
2785 dbg("RESPONSE NOK");
2786 line = (const char *)resp->final_response;
2787 tokens = tcore_at_tok_new(line);
2788 if (g_slist_length(tokens) < 1) {
2789 dbg("Unkown Error OR String corrupted");
2790 res.result = TCORE_RETURN_3GPP_ERROR;
2793 tcore_user_request_send_response(ur, _find_resp_command(ur),
2794 sizeof(struct tresp_sim_verify_pins), &res);
2796 err = atoi(g_slist_nth_data(tokens, 0));
2797 dbg("Error: [%d]", err);
2799 ur = tcore_user_request_ref(ur);
2801 /* Get retry count */
2802 _get_retry_count(co_sim, ur);
2806 tcore_at_tok_free(tokens);
2812 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2814 const TcoreATResponse *resp = data;
2815 UserRequest *ur = NULL;
2816 CoreObject *co_sim = NULL;
2817 struct imc_sim_property *sp = NULL;
2818 GSList *tokens = NULL;
2819 struct tresp_sim_verify_puks res;
2825 co_sim = tcore_pending_ref_core_object(p);
2826 sp = tcore_sim_ref_userdata(co_sim);
2828 err("user data is null");
2832 ur = tcore_pending_ref_user_request(p);
2834 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2836 if (resp->success > 0) {
2838 res.result = SIM_PIN_OPERATION_SUCCESS;
2839 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2842 tcore_user_request_send_response(ur, _find_resp_command(ur),
2843 sizeof(struct tresp_sim_verify_pins), &res);
2845 dbg("RESPONSE NOK");
2846 line = (const char *)resp->final_response;
2847 tokens = tcore_at_tok_new(line);
2849 if (g_slist_length(tokens) < 1) {
2850 dbg("Unkown Error OR String corrupted");
2851 res.result = TCORE_RETURN_3GPP_ERROR;
2854 tcore_user_request_send_response(ur, _find_resp_command(ur),
2855 sizeof(struct tresp_sim_verify_pins), &res);
2857 err = atoi(g_slist_nth_data(tokens, 0));
2858 dbg("Error: [%d]", err);
2859 ur = tcore_user_request_ref(ur);
2860 _get_retry_count(co_sim, ur);
2862 tcore_at_tok_free(tokens);
2867 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2869 const TcoreATResponse *resp = data;
2870 UserRequest *ur = NULL;
2871 CoreObject *co_sim = NULL;
2872 struct imc_sim_property *sp = NULL;
2873 GSList *tokens = NULL;
2874 struct tresp_sim_change_pins res;
2880 co_sim = tcore_pending_ref_core_object(p);
2881 sp = tcore_sim_ref_userdata(co_sim);
2883 err("user data is null");
2887 ur = tcore_pending_ref_user_request(p);
2889 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2891 if (resp->success > 0) {
2893 res.result = SIM_PIN_OPERATION_SUCCESS;
2894 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2897 tcore_user_request_send_response(ur, _find_resp_command(ur),
2898 sizeof(struct tresp_sim_change_pins), &res);
2900 dbg("RESPONSE NOK");
2901 line = (const char *)resp->final_response;
2902 tokens = tcore_at_tok_new(line);
2904 if (g_slist_length(tokens) < 1) {
2905 dbg("Unkown Error OR String corrupted");
2906 res.result = TCORE_RETURN_3GPP_ERROR;
2909 tcore_user_request_send_response(ur, _find_resp_command(ur),
2910 sizeof(struct tresp_sim_change_pins), &res);
2912 err = atoi(g_slist_nth_data(tokens, 0));
2913 dbg("Error: [%d]", err);
2914 ur = tcore_user_request_ref(ur);
2915 _get_retry_count(co_sim, ur);
2919 tcore_at_tok_free(tokens);
2924 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2926 const TcoreATResponse *resp = data;
2927 UserRequest *ur = NULL;
2928 GSList *tokens = NULL;
2929 struct tresp_sim_get_facility_status *res = user_data;
2934 ur = tcore_pending_ref_user_request(p);
2936 res->result = SIM_PIN_OPERATION_SUCCESS;
2938 if (resp->success > 0) {
2941 line = (const char *)resp->lines->data;
2942 tokens = tcore_at_tok_new(line);
2943 if (g_slist_length(tokens) != 1) {
2944 msg("Invalid message");
2945 tcore_at_tok_free(tokens);
2949 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2951 dbg("RESPONSE NOK");
2952 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2957 tcore_user_request_send_response(ur, _find_resp_command(ur),
2958 sizeof(struct tresp_sim_get_facility_status), res);
2960 tcore_at_tok_free(tokens);
2965 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2967 const TcoreATResponse *resp = data;
2968 UserRequest *ur = NULL;
2969 CoreObject *co_sim = NULL;
2970 struct imc_sim_property *sp = NULL;
2971 GSList *tokens = NULL;
2972 struct tresp_sim_enable_facility res;
2977 co_sim = tcore_pending_ref_core_object(p);
2978 sp = tcore_sim_ref_userdata(co_sim);
2980 err("user data is null");
2984 ur = tcore_pending_ref_user_request(p);
2986 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2988 res.result = SIM_CARD_ERROR;
2989 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2991 if (resp->success > 0) {
2994 line = (const char *)resp->lines->data;
2995 tokens = tcore_at_tok_new(line);
2996 if (g_slist_length(tokens) != 1) {
2997 msg("Invalid message");
3000 tcore_user_request_send_response(ur, _find_resp_command(ur),
3001 sizeof(struct tresp_sim_enable_facility), &res);
3002 tcore_at_tok_free(tokens);
3007 res.result = SIM_PIN_OPERATION_SUCCESS;
3011 tcore_user_request_send_response(ur, _find_resp_command(ur),
3012 sizeof(struct tresp_sim_enable_facility), &res);
3016 tcore_at_tok_free(tokens);
3018 dbg("RESPONSE NOK");
3019 ur = tcore_user_request_ref(ur);
3020 _get_retry_count(co_sim, ur);
3025 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
3027 const TcoreATResponse *resp = data;
3028 UserRequest *ur = NULL;
3029 CoreObject *co_sim = NULL;
3030 struct imc_sim_property *sp = NULL;
3031 GSList *tokens = NULL;
3032 struct tresp_sim_disable_facility res;
3037 co_sim = tcore_pending_ref_core_object(p);
3038 sp = tcore_sim_ref_userdata(co_sim);
3040 err("user data is null");
3044 ur = tcore_pending_ref_user_request(p);
3046 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
3048 res.result = SIM_CARD_ERROR;
3049 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3051 if (resp->success > 0) {
3054 line = (const char *)resp->lines->data;
3055 tokens = tcore_at_tok_new(line);
3056 if (g_slist_length(tokens) != 1) {
3057 msg("Invalid message");
3060 tcore_user_request_send_response(ur, _find_resp_command(ur),
3061 sizeof(struct tresp_sim_disable_facility), &res);
3062 tcore_at_tok_free(tokens);
3067 res.result = SIM_PIN_OPERATION_SUCCESS;
3070 tcore_user_request_send_response(ur, _find_resp_command(ur),
3071 sizeof(struct tresp_sim_disable_facility), &res);
3074 tcore_at_tok_free(tokens);
3076 dbg("RESPONSE NOK");
3077 ur = tcore_user_request_ref(ur);
3078 _get_retry_count(co_sim, ur);
3083 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
3085 const TcoreATResponse *response = (TcoreATResponse *)data;
3086 UserRequest *ur = NULL;
3087 GSList *tokens = NULL;
3088 struct treq_sim_get_lock_info *req_data = NULL;
3089 struct tresp_sim_get_lock_info resp;
3091 int pin1_attempts_left = 0;
3092 int puk1_attempts_left = 0;
3093 int pin2_attempts_left = 0;
3094 int puk2_attempts_left = 0;
3095 int length_tokens = 0;
3099 memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3101 ur = tcore_pending_ref_user_request(p);
3103 if (!ur || !response) {
3104 err("NULL data : ur[%p], response[%p]", ur, response);
3105 resp.result = SIM_CARD_ERROR;
3106 tcore_user_request_send_response(ur, _find_resp_command(ur),
3107 sizeof(struct tresp_sim_get_lock_info), &resp);
3111 req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3113 resp.result = SIM_PIN_OPERATION_SUCCESS;
3114 resp.type = req_data->type;
3116 if (response->success > 0) {
3118 if (response->lines) {
3119 line = (const char *)response->lines->data;
3120 tokens = tcore_at_tok_new(line);
3121 length_tokens = g_slist_length(tokens);
3122 dbg("No of Tokens [%d]", length_tokens);
3123 switch (length_tokens) {
3125 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3127 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3129 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3131 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3135 err("Invalid response");
3136 tcore_at_tok_free(tokens);
3137 resp.result = SIM_CARD_ERROR;
3138 tcore_user_request_send_response(ur, _find_resp_command(ur),
3139 sizeof(struct tresp_sim_get_lock_info), &resp);
3144 dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3145 pin1_attempts_left, puk1_attempts_left);
3146 dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3147 pin2_attempts_left, puk2_attempts_left);
3149 resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3151 switch (resp.type) {
3152 case SIM_FACILITY_SC:
3153 resp.retry_count = pin1_attempts_left;
3154 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3155 resp.lock_status = SIM_LOCK_STATUS_PIN;
3156 } else if (pin1_attempts_left == 0) {
3157 if (puk1_attempts_left) {
3158 resp.lock_status = SIM_LOCK_STATUS_PUK;
3159 resp.retry_count = puk1_attempts_left;
3161 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3166 case SIM_FACILITY_FD:
3167 resp.retry_count = pin2_attempts_left;
3168 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3169 resp.lock_status = SIM_LOCK_STATUS_PIN2;
3170 } else if (pin2_attempts_left == 0) {
3171 if (puk2_attempts_left) {
3172 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3173 resp.retry_count = puk2_attempts_left;
3175 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3181 err("Unhandled facility type : [%d]", resp.type);
3184 dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3185 tcore_at_tok_free(tokens);
3188 err("RESPONSE NOK");
3189 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3193 tcore_user_request_send_response(ur, _find_resp_command(ur),
3194 sizeof(struct tresp_sim_get_lock_info), &resp);
3197 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
3199 UserRequest *ur = NULL;
3200 GSList *tokens = NULL;
3201 const char *line = NULL;
3202 const TcoreATResponse *response = (TcoreATResponse *)data;
3203 CoreObject *co_sim = NULL;
3204 struct imc_sim_property *meta_info = NULL;
3205 struct tresp_sim_set_data resp;
3208 gboolean cphs_sim = FALSE;
3209 enum tcore_request_command command;
3212 memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3214 ur = tcore_pending_ref_user_request(p);
3215 command = tcore_user_request_get_command(ur);
3216 co_sim = tcore_pending_ref_core_object(p);
3217 cphs_sim = tcore_sim_get_cphs_status(co_sim);
3218 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3220 if (!ur || !co_sim || !meta_info || !response) {
3221 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3222 resp.result = SIM_CARD_ERROR;
3225 if (response->success > 0) {
3227 if (response->lines) {
3228 line = (const char *)response->lines->data;
3229 tokens = tcore_at_tok_new(line);
3230 if (g_slist_length(tokens) < 2) {
3231 err("Invalid response");
3232 resp.result = SIM_CARD_ERROR;
3234 sw1 = atoi(g_slist_nth_data(tokens, 0));
3235 sw2 = atoi(g_slist_nth_data(tokens, 1));
3237 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
3238 resp.result = SIM_ACCESS_SUCCESS;
3240 resp.result = _decode_status_word(sw1, sw2);
3242 tcore_at_tok_free(tokens);
3245 err("RESPONSE NOK");
3246 resp.result = SIM_ACCESS_FAILED;
3250 if (cphs_sim == FALSE) {
3252 case TREQ_SIM_SET_MAILBOX:
3253 if (meta_info->file_id == SIM_EF_USIM_MBI) {
3254 if (resp.result == SIM_ACCESS_SUCCESS) {
3255 ur = tcore_user_request_ref(ur);
3256 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3258 dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3259 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3260 ur = tcore_user_request_ref(ur);
3261 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3271 case TREQ_SIM_SET_MAILBOX:
3272 if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3273 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3278 case TREQ_SIM_SET_CALLFORWARDING:
3279 if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3280 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3285 case TREQ_SIM_SET_MESSAGEWAITING:
3286 if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3287 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3299 tcore_user_request_send_response(ur, _find_resp_command(ur),
3300 sizeof(struct tresp_sim_set_data), &resp);
3303 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3305 const TcoreATResponse *resp = data;
3306 UserRequest *ur = NULL;
3307 struct tresp_sim_transmit_apdu res;
3312 ur = tcore_pending_ref_user_request(p);
3314 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3315 res.result = SIM_ACCESS_FAILED;
3317 if (resp->success > 0) {
3320 GSList *tokens = NULL;
3322 char *decoded_data = NULL;
3323 line = (const char *)resp->lines->data;
3324 tokens = tcore_at_tok_new(line);
3325 if (g_slist_length(tokens) != 2) {
3326 msg("Invalid message");
3327 tcore_at_tok_free(tokens);
3328 res.result = SIM_CARD_ERROR;
3332 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3334 decoded_data = util_hexStringToBytes(tmp);
3336 res.apdu_resp_length = strlen(tmp) / 2;
3337 res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3338 if (res.apdu_resp == NULL) {
3339 err("Memory allocation failed!!");
3340 tcore_at_tok_free(tokens);
3342 g_free(decoded_data);
3345 memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3347 g_free(decoded_data);
3348 res.result = SIM_ACCESS_SUCCESS;
3349 tcore_at_tok_free(tokens);
3351 err("util_hexStringToBytes Failed!!");
3357 dbg("RESPONSE NOK");
3363 tcore_user_request_send_response(ur, _find_resp_command(ur),
3364 sizeof(struct tresp_sim_transmit_apdu), &res);
3369 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3371 const TcoreATResponse *resp = data;
3372 UserRequest *ur = NULL;
3373 GSList *tokens = NULL;
3374 struct tresp_sim_get_atr res;
3379 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3380 ur = tcore_pending_ref_user_request(p);
3382 res.result = SIM_ACCESS_FAILED;
3383 if (resp->success > 0) {
3387 char *decoded_data = NULL;
3388 line = (const char *)resp->lines->data;
3389 tokens = tcore_at_tok_new(line);
3390 if (g_slist_length(tokens) < 1) {
3391 msg("Invalid message");
3395 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3397 decoded_data = util_hexStringToBytes(tmp);
3398 if (!decoded_data) {
3399 err("util_hexStringToBytes Failed!!");
3403 res.atr_length = strlen(tmp) / 2;
3404 memcpy((char *)res.atr, decoded_data, res.atr_length);
3406 g_free(decoded_data);
3407 res.result = SIM_ACCESS_SUCCESS;
3411 dbg("RESPONSE NOK");
3417 tcore_user_request_send_response(ur, _find_resp_command(ur),
3418 sizeof(struct tresp_sim_get_atr), &res);
3420 tcore_at_tok_free(tokens);
3424 static void on_response_req_authentication(TcorePending *p, int data_len,
3425 const void *data, void *user_data)
3427 const TcoreATResponse *at_resp = data;
3428 GSList *tokens = NULL;
3429 struct tresp_sim_req_authentication resp_auth;
3430 const struct treq_sim_req_authentication *req_data;
3431 UserRequest *ur = tcore_pending_ref_user_request(p);
3435 memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3437 if (at_resp == NULL) {
3438 err("at_resp is NULL");
3439 resp_auth.result = SIM_ACCESS_FAILED;
3440 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3444 req_data = tcore_user_request_ref_data(ur, NULL);
3445 if (req_data == NULL) {
3446 err("req_data is NULL");
3447 resp_auth.result = SIM_ACCESS_FAILED;
3448 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3451 resp_auth.auth_type = req_data->auth_type;
3453 if (at_resp->success == TRUE) {
3458 if (at_resp->lines != NULL) {
3459 line = at_resp->lines->data;
3460 dbg("Received data: [%s]", line);
3462 err("at_resp->lines is NULL");
3463 resp_auth.result = SIM_ACCESS_FAILED;
3464 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3468 tokens = tcore_at_tok_new(line);
3469 if (tokens == NULL) {
3470 err("tokens is NULL");
3471 resp_auth.result = SIM_ACCESS_FAILED;
3472 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3476 status = atoi(g_slist_nth_data(tokens, 0));
3479 dbg("Authentications successful");
3480 resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3483 err("Synchronize fail");
3484 resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3488 resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3491 err("Does not support security context");
3492 resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3495 err("Other failure");
3496 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3500 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3502 char *convert_kc, *convert_sres;
3504 kc = g_slist_nth_data(tokens, 1);
3506 kc = tcore_at_tok_extract(kc);
3507 dbg("Kc: [%s]", kc);
3508 convert_kc = util_hexStringToBytes(kc);
3509 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3510 resp_auth.authentication_key_length = strlen(convert_kc);
3511 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3514 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3520 sres = g_slist_nth_data(tokens, 2);
3522 sres = tcore_at_tok_extract(sres);
3523 dbg("SRES: [%s]", sres);
3524 convert_sres = util_hexStringToBytes(sres);
3525 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3526 resp_auth.resp_length = strlen(convert_sres);
3527 memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3529 err("Invalid SRES");
3530 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3533 g_free(convert_sres);
3535 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3536 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3540 err("RESPONSE NOK");
3541 resp_auth.result = SIM_ACCESS_FAILED;
3542 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3546 tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3547 sizeof(struct tresp_sim_req_authentication), &resp_auth);
3549 tcore_at_tok_free(tokens);
3552 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3554 TcoreHal *hal = NULL;
3555 TcoreATRequest *req = NULL;
3556 TcorePending *pending = NULL;
3557 char *cmd_str = NULL;
3558 const struct treq_sim_verify_pins *req_data = NULL;
3559 struct imc_sim_property *sp = NULL;
3560 TReturn ret = TCORE_RETURN_FAILURE;
3564 if ((o == NULL) || (ur == NULL))
3565 return TCORE_RETURN_EINVAL;
3567 hal = tcore_object_get_hal(o);
3568 if (FALSE == tcore_hal_get_power_state(hal)) {
3569 err("CP NOT READY");
3570 return TCORE_RETURN_ENOSYS;
3573 sp = tcore_sim_ref_userdata(o);
3575 err("user data is null");
3576 return TCORE_RETURN_FAILURE;
3579 pending = tcore_pending_new(o, 0);
3581 err("Pending is NULL");
3582 return TCORE_RETURN_FAILURE;
3585 req_data = tcore_user_request_ref_data(ur, NULL);
3587 if (req_data->pin_type == SIM_PTYPE_PIN1) {
3588 sp->current_sec_op = SEC_PIN1_VERIFY;
3589 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3590 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3591 sp->current_sec_op = SEC_PIN2_VERIFY;
3592 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3593 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3594 sp->current_sec_op = SEC_SIM_VERIFY;
3595 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3596 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3597 sp->current_sec_op = SEC_ADM_VERIFY;
3598 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3600 tcore_pending_free(pending);
3601 return TCORE_RETURN_EINVAL;
3604 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3606 tcore_pending_free(pending);
3608 return TCORE_RETURN_FAILURE;
3612 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3613 req->cmd, req->prefix, strlen(req->cmd));
3615 tcore_pending_set_request_data(pending, 0, req);
3616 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3617 tcore_pending_link_user_request(pending, ur);
3618 ret = tcore_hal_send_request(hal, pending);
3624 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3626 TcoreHal *hal = NULL;
3627 TcoreATRequest *req = NULL;
3628 TcorePending *pending = NULL;
3629 char *cmd_str = NULL;
3630 const struct treq_sim_verify_puks *req_data;
3631 struct imc_sim_property *sp = NULL;
3632 TReturn ret = TCORE_RETURN_FAILURE;
3636 if ((o == NULL) || (ur == NULL))
3637 return TCORE_RETURN_EINVAL;
3639 hal = tcore_object_get_hal(o);
3640 if (FALSE == tcore_hal_get_power_state(hal)) {
3641 err("CP NOT READY");
3642 return TCORE_RETURN_ENOSYS;
3645 sp = tcore_sim_ref_userdata(o);
3647 err("user data is null");
3648 return TCORE_RETURN_FAILURE;
3651 pending = tcore_pending_new(o, 0);
3653 err("Pending is NULL");
3654 return TCORE_RETURN_FAILURE;
3657 req_data = tcore_user_request_ref_data(ur, NULL);
3659 if (req_data->puk_type == SIM_PTYPE_PUK1) {
3660 sp->current_sec_op = SEC_PUK1_VERIFY;
3661 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3662 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3663 sp->current_sec_op = SEC_PUK2_VERIFY;
3664 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3666 tcore_pending_free(pending);
3667 return TCORE_RETURN_EINVAL;
3670 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3672 tcore_pending_free(pending);
3674 return TCORE_RETURN_FAILURE;
3678 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3679 req->cmd, req->prefix, strlen(req->cmd));
3681 tcore_pending_set_request_data(pending, 0, req);
3682 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3683 tcore_pending_link_user_request(pending, ur);
3684 ret = tcore_hal_send_request(hal, pending);
3690 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3692 TcoreHal *hal = NULL;
3693 TcoreATRequest *req = NULL;
3694 TcorePending *pending = NULL;
3695 char *cmd_str = NULL;
3696 const struct treq_sim_change_pins *req_data;
3697 struct imc_sim_property *sp = NULL;
3700 TReturn ret = TCORE_RETURN_FAILURE;
3704 if ((o == NULL) || (ur == NULL))
3705 return TCORE_RETURN_EINVAL;
3707 hal = tcore_object_get_hal(o);
3708 if (FALSE == tcore_hal_get_power_state(hal)) {
3709 err("CP NOT READY");
3710 return TCORE_RETURN_ENOSYS;
3713 sp = tcore_sim_ref_userdata(o);
3715 err("user data is null");
3716 return TCORE_RETURN_FAILURE;
3719 pending = tcore_pending_new(o, 0);
3721 err("Pending is NULL");
3722 return TCORE_RETURN_FAILURE;
3725 req_data = tcore_user_request_ref_data(ur, NULL);
3727 if (req_data->type == SIM_PTYPE_PIN1) {
3728 sp->current_sec_op = SEC_PIN1_CHANGE;
3729 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3730 } else if (req_data->type == SIM_PTYPE_PIN2) {
3731 sp->current_sec_op = SEC_PIN2_CHANGE;
3732 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3734 tcore_pending_free(pending);
3735 return TCORE_RETURN_EINVAL;
3737 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3739 tcore_pending_free(pending);
3741 return TCORE_RETURN_FAILURE;
3745 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3746 req->cmd, req->prefix, strlen(req->cmd));
3748 tcore_pending_set_request_data(pending, 0, req);
3749 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3750 tcore_pending_link_user_request(pending, ur);
3751 ret = tcore_hal_send_request(hal, pending);
3757 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3759 TcoreHal *hal = NULL;
3760 TcoreATRequest *req = NULL;
3761 TcorePending *pending = NULL;
3762 char *cmd_str = NULL;
3763 const struct treq_sim_get_facility_status *req_data;
3764 struct tresp_sim_get_facility_status *res;
3766 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
3767 TReturn ret = TCORE_RETURN_FAILURE;
3771 if ((o == NULL) || (ur == NULL))
3772 return TCORE_RETURN_EINVAL;
3774 hal = tcore_object_get_hal(o);
3775 if (FALSE == tcore_hal_get_power_state(hal)) {
3776 err("CP NOT READY");
3777 return TCORE_RETURN_ENOSYS;
3780 pending = tcore_pending_new(o, 0);
3782 err("Pending is NULL");
3783 return TCORE_RETURN_FAILURE;
3786 req_data = tcore_user_request_ref_data(ur, NULL);
3788 res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3790 tcore_pending_free(pending);
3791 return TCORE_RETURN_ENOMEM;
3794 res->type = req_data->type;
3796 if (req_data->type == SIM_FACILITY_PS)
3797 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3798 else if (req_data->type == SIM_FACILITY_SC)
3799 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3800 else if (req_data->type == SIM_FACILITY_FD)
3801 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3802 else if (req_data->type == SIM_FACILITY_PN)
3803 fac = "PN"; /*Network Personalization*/
3804 else if (req_data->type == SIM_FACILITY_PU)
3805 fac = "PU"; /*network sUbset Personalization*/
3806 else if (req_data->type == SIM_FACILITY_PP)
3807 fac = "PP"; /*service Provider Personalization*/
3808 else if (req_data->type == SIM_FACILITY_PC)
3809 fac = "PC"; /*Corporate Personalization*/
3811 return TCORE_RETURN_EINVAL;
3813 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3814 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3816 tcore_pending_free(pending);
3818 return TCORE_RETURN_FAILURE;
3822 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3823 req->cmd, req->prefix, strlen(req->cmd));
3825 tcore_pending_set_request_data(pending, 0, req);
3826 tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3827 tcore_pending_link_user_request(pending, ur);
3828 ret = tcore_hal_send_request(hal, pending);
3834 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3836 TcoreHal *hal = NULL;
3837 TcoreATRequest *req = NULL;
3838 TcorePending *pending = NULL;
3839 char *cmd_str = NULL;
3840 const struct treq_sim_enable_facility *req_data;
3841 struct imc_sim_property *sp = NULL;
3843 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
3844 TReturn ret = TCORE_RETURN_FAILURE;
3848 if ((o == NULL) || (ur == NULL))
3849 return TCORE_RETURN_EINVAL;
3851 hal = tcore_object_get_hal(o);
3852 if (FALSE == tcore_hal_get_power_state(hal)) {
3853 err("CP NOT READY");
3854 return TCORE_RETURN_ENOSYS;
3857 sp = tcore_sim_ref_userdata(o);
3859 err("user data is null");
3860 return TCORE_RETURN_FAILURE;
3863 pending = tcore_pending_new(o, 0);
3865 err("Pending is NULL");
3866 return TCORE_RETURN_FAILURE;
3869 req_data = tcore_user_request_ref_data(ur, NULL);
3871 if (req_data->type == SIM_FACILITY_PS) {
3872 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3873 sp->current_sec_op = SEC_SIM_ENABLE;
3874 } else if (req_data->type == SIM_FACILITY_SC) {
3875 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3876 sp->current_sec_op = SEC_PIN1_ENABLE;
3877 } else if (req_data->type == SIM_FACILITY_FD) {
3878 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3879 sp->current_sec_op = SEC_FDN_ENABLE;
3880 } else if (req_data->type == SIM_FACILITY_PN) {
3881 fac = "PN"; /*Network Personalization*/
3882 sp->current_sec_op = SEC_NET_ENABLE;
3883 } else if (req_data->type == SIM_FACILITY_PU) {
3884 fac = "PU"; /*network sUbset Personalization*/
3885 sp->current_sec_op = SEC_NS_ENABLE;
3886 } else if (req_data->type == SIM_FACILITY_PP) {
3887 fac = "PP"; /*service Provider Personalization*/
3888 sp->current_sec_op = SEC_SP_ENABLE;
3889 } else if (req_data->type == SIM_FACILITY_PC) {
3890 fac = "PC"; /*Corporate Personalization*/
3891 sp->current_sec_op = SEC_CP_ENABLE;
3893 return TCORE_RETURN_EINVAL;
3895 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3896 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3898 tcore_pending_free(pending);
3900 return TCORE_RETURN_FAILURE;
3904 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3905 req->cmd, req->prefix, strlen(req->cmd));
3907 tcore_pending_set_request_data(pending, 0, req);
3908 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3909 tcore_pending_link_user_request(pending, ur);
3910 ret = tcore_hal_send_request(hal, pending);
3916 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3919 TcoreATRequest *req;
3920 TcorePending *pending = NULL;
3921 char *cmd_str = NULL;
3922 const struct treq_sim_enable_facility *req_data;
3923 struct imc_sim_property *sp = NULL;
3925 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
3926 TReturn ret = TCORE_RETURN_FAILURE;
3930 if ((o == NULL) || (ur == NULL))
3931 return TCORE_RETURN_EINVAL;
3933 hal = tcore_object_get_hal(o);
3934 if (FALSE == tcore_hal_get_power_state(hal)) {
3935 err("CP NOT READY");
3936 return TCORE_RETURN_ENOSYS;
3939 sp = tcore_sim_ref_userdata(o);
3941 err("user data is null");
3942 return TCORE_RETURN_FAILURE;
3945 pending = tcore_pending_new(o, 0);
3947 err("Pending is NULL");
3948 return TCORE_RETURN_FAILURE;
3951 req_data = tcore_user_request_ref_data(ur, NULL);
3953 if (req_data->type == SIM_FACILITY_PS) {
3954 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3955 sp->current_sec_op = SEC_SIM_DISABLE;
3956 } else if (req_data->type == SIM_FACILITY_SC) {
3957 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3958 sp->current_sec_op = SEC_PIN1_DISABLE;
3959 } else if (req_data->type == SIM_FACILITY_FD) {
3960 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3961 sp->current_sec_op = SEC_FDN_DISABLE;
3962 } else if (req_data->type == SIM_FACILITY_PN) {
3963 fac = "PN"; /*Network Personalization*/
3964 sp->current_sec_op = SEC_NET_DISABLE;
3965 } else if (req_data->type == SIM_FACILITY_PU) {
3966 fac = "PU"; /*network sUbset Personalization*/
3967 sp->current_sec_op = SEC_NS_DISABLE;
3968 } else if (req_data->type == SIM_FACILITY_PP) {
3969 fac = "PP"; /*service Provider Personalization*/
3970 sp->current_sec_op = SEC_SP_DISABLE;
3971 } else if (req_data->type == SIM_FACILITY_PC) {
3972 fac = "PC"; /*Corporate Personalization*/
3973 sp->current_sec_op = SEC_CP_DISABLE;
3975 return TCORE_RETURN_EINVAL;
3977 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3978 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3980 tcore_pending_free(pending);
3982 return TCORE_RETURN_FAILURE;
3986 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3987 req->cmd, req->prefix, strlen(req->cmd));
3989 tcore_pending_set_request_data(pending, 0, req);
3990 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
3991 tcore_pending_link_user_request(pending, ur);
3992 ret = tcore_hal_send_request(hal, pending);
3998 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
4000 TcoreHal *hal = NULL;
4001 TcoreATRequest *req = NULL;
4002 TcorePending *pending = NULL;
4006 hal = tcore_object_get_hal(o);
4007 pending = tcore_pending_new(o, 0);
4009 err("Pending is NULL");
4010 return TCORE_RETURN_FAILURE;
4013 if ((o == NULL) || (ur == NULL)) {
4014 tcore_pending_free(pending);
4015 return TCORE_RETURN_EINVAL;
4017 req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
4020 tcore_pending_free(pending);
4021 return TCORE_RETURN_FAILURE;
4024 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4025 req->cmd, req->prefix, strlen(req->cmd));
4027 tcore_pending_set_request_data(pending, 0, req);
4028 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
4029 tcore_pending_link_user_request(pending, ur);
4030 tcore_hal_send_request(hal, pending);
4033 return TCORE_RETURN_SUCCESS;
4036 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
4038 TReturn api_ret = TCORE_RETURN_SUCCESS;
4039 enum tcore_request_command command;
4043 if ((o == NULL) || (ur == NULL))
4044 return TCORE_RETURN_EINVAL;
4046 command = tcore_user_request_get_command(ur);
4047 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
4048 err("CP NOT READY");
4049 return TCORE_RETURN_ENOSYS;
4053 case TREQ_SIM_GET_ECC:
4054 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
4057 case TREQ_SIM_GET_LANGUAGE:
4058 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
4059 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
4060 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
4061 api_ret = _get_file_info(o, ur, SIM_EF_LP);
4063 api_ret = TCORE_RETURN_ENOSYS;
4066 case TREQ_SIM_GET_ICCID:
4067 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
4070 case TREQ_SIM_GET_MAILBOX:
4071 if (tcore_sim_get_cphs_status(o))
4072 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4074 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
4077 case TREQ_SIM_GET_CALLFORWARDING:
4078 if (tcore_sim_get_cphs_status(o))
4079 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4081 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
4084 case TREQ_SIM_GET_MESSAGEWAITING:
4085 if (tcore_sim_get_cphs_status(o))
4086 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4088 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
4091 case TREQ_SIM_GET_CPHS_INFO:
4092 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
4095 case TREQ_SIM_GET_MSISDN:
4096 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
4099 case TREQ_SIM_GET_SPN:
4100 dbg("enter case SPN");
4101 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
4104 case TREQ_SIM_GET_SPDI:
4105 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
4108 case TREQ_SIM_GET_OPL:
4109 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
4112 case TREQ_SIM_GET_PNN:
4113 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
4116 case TREQ_SIM_GET_CPHS_NETNAME:
4117 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
4120 case TREQ_SIM_GET_OPLMNWACT:
4121 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
4124 case TREQ_SIM_GET_SERVICE_TABLE:
4125 api_ret = _get_file_info(o, ur, SIM_EF_SST);
4129 dbg("error - not handled read treq command[%d]", command);
4130 api_ret = TCORE_RETURN_EINVAL;
4138 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
4140 TReturn ret_code = TCORE_RETURN_SUCCESS;
4141 enum tcore_request_command command;
4142 enum tel_sim_file_id ef = SIM_EF_INVALID;
4143 struct imc_sim_property meta_info = {0, };
4144 enum tel_sim_type sim_type;
4145 gboolean cphs_sim = FALSE;
4148 command = tcore_user_request_get_command(ur);
4149 cphs_sim = tcore_sim_get_cphs_status(co_sim);
4150 sim_type = tcore_sim_get_type(co_sim);
4152 if ((co_sim == NULL) || (ur == NULL))
4153 return TCORE_RETURN_EINVAL;
4156 case TREQ_SIM_SET_LANGUAGE:
4157 if (sim_type == SIM_TYPE_GSM)
4158 ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
4159 else if (sim_type == SIM_TYPE_USIM)
4160 ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
4162 ret_code = TCORE_RETURN_ENOSYS;
4165 case TREQ_SIM_SET_MAILBOX:
4167 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4171 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])) {
4172 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4173 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4175 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
4176 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4180 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4184 case TREQ_SIM_SET_CALLFORWARDING:
4186 const struct treq_sim_set_callforwarding *cf = NULL;
4187 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
4191 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4194 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])) {
4195 if (cf->b_cphs == FALSE)
4196 ef = SIM_EF_USIM_CFIS;
4198 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4200 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4201 ret_code = _get_file_info(co_sim, ur, ef);
4203 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4204 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4208 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4211 ret_code = TCORE_RETURN_EINVAL;
4216 case TREQ_SIM_SET_MESSAGEWAITING:
4218 const struct treq_sim_set_messagewaiting *mw = NULL;
4219 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4222 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4225 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])) {
4226 if (mw->b_cphs == FALSE)
4227 ef = SIM_EF_USIM_MWIS;
4229 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4231 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4232 ret_code = _get_file_info(co_sim, ur, ef);
4234 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4235 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4239 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4242 ret_code = TCORE_RETURN_EINVAL;
4248 err("Unhandled UPDATE command[%d]", command);
4249 return TCORE_RETURN_EINVAL;
4255 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4257 const struct treq_sim_transmit_apdu *req_data;
4258 TcoreHal *hal = NULL;
4259 char *cmd_str = NULL;
4262 TReturn ret = TCORE_RETURN_FAILURE;
4266 if ((o == NULL) || (ur == NULL))
4267 return TCORE_RETURN_EINVAL;
4269 hal = tcore_object_get_hal(o);
4270 if (FALSE == tcore_hal_get_power_state(hal)) {
4271 err("CP NOT READY");
4272 return TCORE_RETURN_ENOSYS;
4275 req_data = tcore_user_request_ref_data(ur, NULL);
4277 apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4279 err("Memory allocation failed!!");
4280 return TCORE_RETURN_ENOMEM;
4282 result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4283 dbg("result %d", result);
4285 cmd_str = g_strdup_printf("AT+CSIM=%d, \"%s\"", (unsigned int)strlen(apdu), apdu);
4287 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4288 TCORE_AT_SINGLELINE, ur,
4289 on_response_transmit_apdu, hal,
4290 NULL, NULL, 0, NULL, NULL);
4298 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4300 TcoreHal *hal = NULL;
4304 if ((o == NULL) || (ur == NULL)) {
4305 err("Invalid parameters");
4306 return TCORE_RETURN_EINVAL;
4309 hal = tcore_object_get_hal(o);
4310 if (FALSE == tcore_hal_get_power_state(hal)) {
4311 err("CP NOT READY");
4312 return TCORE_RETURN_ENOSYS;
4315 return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4316 TCORE_AT_SINGLELINE, ur,
4317 on_response_get_atr, hal,
4318 NULL, NULL, 0, NULL, NULL);
4321 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4323 const struct treq_sim_req_authentication *req_data;
4324 char *cmd_str = NULL;
4325 enum tel_sim_type sim_type;
4328 TReturn ret = TCORE_RETURN_FAILURE;
4329 char *convert_rand = NULL;
4330 char *convert_autn = NULL;
4334 req_data = tcore_user_request_ref_data(ur, NULL);
4335 if (req_data == NULL) {
4336 err("req_data is NULL");
4340 convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
4341 dbg("Convert RAND hex to string: [%s]", convert_rand);
4343 sim_type = tcore_sim_get_type(co);
4350 err("Not supported");
4351 ret = TCORE_RETURN_ENOSYS;
4355 switch (req_data->auth_type) {
4356 case SIM_AUTH_TYPE_GSM:
4358 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\"", session_id,
4359 context_type, convert_rand);
4361 case SIM_AUTH_TYPE_3G:
4363 convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
4364 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4366 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\", \"%s\"",
4367 session_id, context_type,
4368 convert_rand, convert_autn);
4371 err("Not supported");
4372 ret = TCORE_RETURN_ENOSYS;
4376 ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4377 TCORE_AT_SINGLELINE, ur,
4378 on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4382 g_free(convert_rand);
4383 g_free(convert_autn);
4388 /* SIM Operations */
4389 static struct tcore_sim_operations sim_ops = {
4390 .verify_pins = imc_verify_pins,
4391 .verify_puks = imc_verify_puks,
4392 .change_pins = imc_change_pins,
4393 .get_facility_status = imc_get_facility_status,
4394 .enable_facility = imc_enable_facility,
4395 .disable_facility = imc_disable_facility,
4396 .get_lock_info = imc_get_lock_info,
4397 .read_file = imc_read_file,
4398 .update_file = imc_update_file,
4399 .transmit_apdu = imc_transmit_apdu,
4400 .get_atr = imc_get_atr,
4401 .req_authentication = imc_req_authentication,
4402 .set_powerstate = NULL,
4405 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4407 struct imc_sim_property *meta_info;
4411 /* Set operations */
4412 tcore_sim_set_ops(co_sim, &sim_ops, TCORE_OPS_TYPE_CP);
4414 meta_info = g_try_new0(struct imc_sim_property, 1);
4415 if (meta_info == NULL)
4418 tcore_sim_link_userdata(co_sim, meta_info);
4420 tcore_object_add_callback(co_sim, "+XLOCK:",
4421 on_event_facility_lock_status, NULL);
4422 tcore_object_add_callback(co_sim, "+XSIM:",
4423 on_event_pin_status, NULL);
4425 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4426 TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4433 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4435 struct imc_sim_property *meta_info;
4437 meta_info = tcore_sim_ref_userdata(co_sim);