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_KEY "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 char *_add_shared_owner_prefix(const char *name)
453 size_t alias_len = strlen(name) + strlen(ckmc_label_shared_owner) + strlen(ckmc_label_name_separator);
454 char *ckm_alias = (char *)malloc(alias_len + 1);
456 err("Failed to allocate memory");
459 memset(ckm_alias, 0, alias_len);
460 strncat(ckm_alias, ckmc_label_shared_owner, strlen(ckmc_label_shared_owner));
461 strncat(ckm_alias, ckmc_label_name_separator, strlen(ckmc_label_name_separator));
462 strncat(ckm_alias, name, strlen(name));
467 static gboolean _sim_check_identity(CoreObject *co_sim, struct tel_sim_imsi *imsi)
469 gboolean is_changed = TRUE;
470 char new_imsi[16 + 1]; /* IMSI is 15 digit, but for distingushing between plmn and msin, define as 16 bytes. */
471 char *imsi_buf = NULL;
476 ckmc_raw_buffer_s *ckmc_buffer;
485 alias = _add_shared_owner_prefix(SIM_STORE_KEY);
487 err("Failed to allocate alias name.");
491 memset(new_imsi, 0x5F, 16);
492 memcpy(new_imsi, imsi->plmn, strlen(imsi->plmn));
493 memcpy(&new_imsi[6], imsi->msin, strlen(imsi->msin));
494 new_imsi[6 + strlen(imsi->msin)] = '\0';
496 ret_val = ckmc_get_data(alias, passwd, &ckmc_buffer);
497 imsi_buf = (char*)ckmc_buffer->data;
498 if (ret_val == CKMC_ERROR_NONE && imsi_buf != NULL) {
499 if (strncmp(imsi_buf, new_imsi, 16) == 0)
501 ckmc_buffer_free(ckmc_buffer);
505 ckmc_policy_s policy;
506 ckmc_raw_buffer_s store_buffer;
508 policy.password = passwd;
509 policy.extractable = true;
510 store_buffer.data = (unsigned char*)new_imsi;
511 store_buffer.size = strlen(new_imsi) + 1;
515 ret_val = ckmc_save_data(alias, store_buffer, policy);
516 if (ret_val != CKMC_ERROR_NONE)
517 err("ckmc_save_data failed. ret_val=[%d]", ret_val);
520 /* Update sim identification */
521 tcore_sim_set_identification(co_sim, is_changed);
529 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
530 char *encoded_data, unsigned int encoded_len, int rec_index)
532 TcoreHal *hal = NULL;
533 TcoreATRequest *req = NULL;
534 TcorePending *pending = NULL;
535 char *cmd_str = NULL;
536 struct imc_sim_property *meta_info = NULL;
544 hal = tcore_object_get_hal(o);
545 pending = tcore_pending_new(o, 0);
547 err("Pending is NULL");
548 return TCORE_RETURN_FAILURE;
550 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
552 meta_info->file_id = ef;
553 dbg("File ID: [0x%x]", meta_info->file_id);
556 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
559 case SIM_EF_CPHS_VOICE_MSG_WAITING:
566 case SIM_EF_USIM_CFIS:
567 case SIM_EF_USIM_MWIS:
568 case SIM_EF_CPHS_MAILBOX_NUMBERS:
570 case SIM_EF_USIM_MBI:
578 err("Unhandled File ID[0x%04x]", ef);
579 tcore_pending_free(pending);
580 return TCORE_RETURN_EINVAL;
583 cmd_str = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d, \"%s\"", cmd, ef, p1, p2, p3, encoded_data);
585 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
587 tcore_pending_free(pending);
589 return TCORE_RETURN_FAILURE;
593 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
594 req->cmd, req->prefix, strlen(req->cmd));
596 tcore_pending_set_request_data(pending, 0, req);
597 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
598 tcore_pending_link_user_request(pending, ur);
599 tcore_hal_send_request(hal, pending);
606 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
608 struct imc_sim_property *meta_info = NULL;
609 TReturn ret_code = TCORE_RETURN_FAILURE;
611 enum tcore_request_command command;
613 char *encoded_data = NULL;
619 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
620 return TCORE_RETURN_EINVAL;
622 command = tcore_user_request_get_command(ur);
623 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
626 case TREQ_SIM_SET_LANGUAGE: {
627 const struct treq_sim_set_language *lang = NULL;
628 struct tel_sim_language language = {0, };
630 lang = tcore_user_request_ref_data(ur, NULL);
631 language.language_count = 1;
632 language.language[0] = lang->language;
633 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP) {
634 dbg("Encoding EF-LP, language[%d]", lang->language);
635 tmp = tcore_sim_encode_lp(&encoded_len, &language);
637 dbg("Encoding EF-ELP, language[%d]", lang->language);
638 tmp = tcore_sim_encode_li(&encoded_len, &language);
643 case TREQ_SIM_SET_CALLFORWARDING: {
644 const struct treq_sim_set_callforwarding *cf = NULL;
646 cf = tcore_user_request_ref_data(ur, NULL);
647 if (ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
649 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cf->cphs_cf, meta_info->data_size);
651 /* Convert 3GPP data to CPHS data */
652 struct tel_sim_cphs_cf cphs_cf;
654 dbg("Convert 3GPP data to CPHS data");
655 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
656 if (cf->cf.cfu_status & 0x01)
657 cphs_cf.b_line1 = TRUE;
659 if (cf->cf.cfu_status & 0x02)
660 cphs_cf.b_fax = TRUE;
662 if (cf->cf.cfu_status & 0x04)
663 cphs_cf.b_data = TRUE;
665 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf *)&cphs_cf, meta_info->data_size);
669 encoded_len = strlen(tmp);
671 err("NULL Encoding Data[%p].. No Updating EF", tmp);
674 } else if (ef == SIM_EF_USIM_CFIS) {
675 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis *)&cf->cf);
676 rec_index = cf->cf.rec_index;
678 err("Invalid File ID[0x%04x]", ef);
684 case TREQ_SIM_SET_MESSAGEWAITING: {
685 const struct treq_sim_set_messagewaiting *mw = NULL;
687 mw = tcore_user_request_ref_data(ur, NULL);
688 if (ef == SIM_EF_CPHS_VOICE_MSG_WAITING) {
690 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&mw->cphs_mw, meta_info->data_size);
692 /* Convert 3GPP data to CPHS data */
693 struct tel_sim_cphs_mw cphs_mw;
695 dbg("Convert 3GPP data to CPHS data");
696 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
698 if (mw->mw.indicator_status & 0x01)
699 cphs_mw.b_voice1 = TRUE;
701 if (mw->mw.indicator_status & 0x02)
702 cphs_mw.b_fax = TRUE;
704 if (mw->mw.indicator_status & 0x04)
705 cphs_mw.b_data = TRUE;
707 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw *)&cphs_mw, meta_info->data_size);
709 } else if (ef == SIM_EF_USIM_MWIS) {
710 tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw *)&mw->mw, meta_info->rec_length);
711 rec_index = mw->mw.rec_index;
713 encoded_len = meta_info->rec_length;
715 err("Invalid File ID[0x%04x]", ef);
721 case TREQ_SIM_SET_MAILBOX: {
722 const struct treq_sim_set_mailbox *mb = NULL;
724 mb = tcore_user_request_ref_data(ur, NULL);
725 if (ef == SIM_EF_USIM_MBI) {
726 gboolean mbi_changed = FALSE;
727 struct tel_sim_mbi mbi;
730 meta_info->current_index++;
731 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
733 switch (mb->mb_info.mb_type) {
734 case SIM_MAILBOX_VOICE:
735 if (mbi.voice_index != mb->mb_info.rec_index) {
737 mbi.voice_index = mb->mb_info.rec_index;
741 case SIM_MAILBOX_FAX:
742 if (mbi.fax_index != mb->mb_info.rec_index) {
744 mbi.fax_index = mb->mb_info.rec_index;
748 case SIM_MAILBOX_EMAIL:
749 if (mbi.email_index != mb->mb_info.rec_index) {
751 mbi.email_index = mb->mb_info.rec_index;
755 case SIM_MAILBOX_OTHER:
756 if (mbi.other_index != mb->mb_info.rec_index) {
758 mbi.other_index = mb->mb_info.rec_index;
762 case SIM_MAILBOX_VIDEO:
763 if (mbi.video_index != mb->mb_info.rec_index) {
765 mbi.video_index = mb->mb_info.rec_index;
769 case SIM_MAILBOX_DATA:
774 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
775 mbi_changed, meta_info->mbi_list.profile_count,
776 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
777 } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
779 if (mbi_changed == TRUE) {
780 rec_index = meta_info->current_index;
781 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
783 encoded_len = meta_info->rec_length;
785 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
786 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
787 rec_index = mb->mb_info.rec_index;
789 encoded_len = meta_info->rec_length;
790 } else if (ef == SIM_EF_MBDN) {
791 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number *)&mb->mb_info.number_info);
792 rec_index = mb->mb_info.rec_index;
794 encoded_len = meta_info->rec_length;
796 err("Invalid File ID[0x%04x]", ef);
803 err("Unhandled update REQUEST command[%d]", command);
804 ret_code = TCORE_RETURN_EINVAL;
809 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
810 if (encoded_data == NULL) {
811 err("Memory allocation failed!!");
816 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
817 util_byte_to_hex(tmp, encoded_data, encoded_len);
820 err("Failed to Encode data");
824 dbg("Encoded Data length =[%d]", encoded_len);
825 tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
828 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
831 case SIM_EF_CPHS_VOICE_MSG_WAITING:
832 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
835 case SIM_EF_USIM_CFIS:
836 case SIM_EF_USIM_MWIS:
837 case SIM_EF_CPHS_MAILBOX_NUMBERS:
839 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
842 case SIM_EF_USIM_MBI:
844 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
846 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
850 err("Unhandled File ID[0x%04x]", ef);
851 ret_code = TCORE_RETURN_EINVAL;
864 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
866 struct tresp_sim_read resp = {0, };
867 struct imc_sim_property *meta_info = NULL;
868 enum tcore_request_command command = TREQ_UNKNOWN;
869 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
871 dbg("EF[0x%x] access Result[%d]", ef, rt);
874 memset(&resp.data, 0x00, sizeof(resp.data));
875 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
876 command = tcore_user_request_get_command(ur);
877 sim_type = tcore_sim_get_type(o);
879 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
880 && (rt != SIM_ACCESS_SUCCESS)) {
881 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
887 if (rt == SIM_ACCESS_SUCCESS) {
888 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
889 if (command == TREQ_SIM_SET_LANGUAGE)
890 __set_file_data(o, ur, ef);
892 _get_file_data(o, ur, ef, 0, meta_info->data_size);
894 if (sim_type == SIM_TYPE_GSM) {
895 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
896 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
897 _get_file_info(o, ur, SIM_EF_LP);
898 } else if (sim_type == SIM_TYPE_USIM) {
900 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05), EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
901 /* EFELPand EFLI not present at this point. */
902 /* po->language.lang_cnt = 0;*/
903 tcore_user_request_send_response(ur, _find_resp_command(ur),
904 sizeof(struct tresp_sim_read), &resp);
910 case SIM_EF_LP: /* same with SIM_EF_USIM_LI */
911 if (rt == SIM_ACCESS_SUCCESS) {
912 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
913 if (command == TREQ_SIM_SET_LANGUAGE)
914 __set_file_data(o, ur, ef);
916 _get_file_data(o, ur, ef, 0, meta_info->data_size);
918 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
920 if (sim_type == SIM_TYPE_GSM) {
921 tcore_user_request_send_response(ur, _find_resp_command(ur),
922 sizeof(struct tresp_sim_read), &resp);
925 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
926 else if (sim_type == SIM_TYPE_USIM) {
927 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
928 _get_file_info(o, ur, SIM_EF_ELP);
934 if (rt == SIM_ACCESS_SUCCESS) {
935 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
936 if (command == TREQ_SIM_SET_LANGUAGE)
937 __set_file_data(o, ur, ef);
939 _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
941 /* EFELIand EFPL not present, so set language count as zero and select ECC */
942 dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
943 tcore_user_request_send_response(ur, _find_resp_command(ur),
944 sizeof(struct tresp_sim_read), &resp);
950 if (sim_type == SIM_TYPE_GSM) {
951 _get_file_data(o, ur, ef, 0, meta_info->data_size);
952 } else if (sim_type == SIM_TYPE_USIM) {
953 if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX)
954 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
956 meta_info->current_index++;
957 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
966 case SIM_EF_CPHS_VOICE_MSG_WAITING:
967 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
968 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
969 case SIM_EF_CPHS_DYNAMICFLAGS:
970 case SIM_EF_CPHS_DYNAMIC2FLAG:
971 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
972 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
973 case SIM_EF_OPLMN_ACT:
974 _get_file_data(o, ur, ef, 0, meta_info->data_size);
977 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
978 if (command == TREQ_SIM_SET_CALLFORWARDING)
979 __set_file_data(o, ur, ef);
981 _get_file_data(o, ur, ef, 0, meta_info->data_size);
984 case SIM_EF_CPHS_CPHS_INFO:
985 if (rt == SIM_ACCESS_SUCCESS) {
986 tcore_sim_set_cphs_status(o, TRUE);
987 if (!tcore_user_request_ref_communicator(ur)) {
988 dbg("internal CPHS INFO request before sim status update");
989 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
991 dbg("external CPHS INFO request");
992 _get_file_data(o, ur, ef, 0, meta_info->data_size);
995 tcore_sim_set_cphs_status(o, FALSE);
996 if (!tcore_user_request_ref_communicator(ur)) {
997 dbg("internal CPHS INFO request before sim status update");
998 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
1000 dbg("external CPHS INFO request");
1001 tcore_user_request_send_response(ur, _find_resp_command(ur),
1002 sizeof(struct tresp_sim_read), &resp);
1007 case SIM_EF_USIM_CFIS:
1008 if (command == TREQ_SIM_SET_CALLFORWARDING) {
1009 __set_file_data(o, ur, ef);
1011 if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX)
1012 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
1014 meta_info->current_index++;
1015 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1019 case SIM_EF_USIM_MWIS:
1020 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
1021 __set_file_data(o, ur, ef);
1023 meta_info->current_index++;
1024 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1028 case SIM_EF_USIM_MBI:
1029 if (command == TREQ_SIM_SET_MAILBOX) {
1030 __set_file_data(o, ur, ef);
1032 meta_info->current_index++;
1033 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1039 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1041 meta_info->current_index++;
1042 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1046 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1047 if (command == TREQ_SIM_SET_MAILBOX) {
1048 /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1049 if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1050 err("Cyclic File ID. No update & return error.");
1051 meta_info->files.result = SIM_ACCESS_FAILED;
1052 tcore_user_request_send_response(ur, _find_resp_command(ur),
1053 sizeof(struct tresp_sim_read), &meta_info->files);
1056 __set_file_data(o, ur, ef);
1060 meta_info->mb_count = 0;
1061 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1062 if (meta_info->current_index == 0) {
1063 err("Invalid MBDN index");
1064 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1065 tcore_user_request_send_response(ur, _find_resp_command(ur),
1066 sizeof(struct tresp_sim_read), &meta_info->files);
1068 ur = tcore_user_request_ref(ur);
1069 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1071 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1076 dbg("error - File id for get file info [0x%x]", ef);
1081 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1083 struct imc_sim_property *meta_info = NULL;
1087 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1088 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1089 switch (meta_info->file_id) {
1091 case SIM_EF_USIM_PL:
1093 case SIM_EF_USIM_LI:
1094 if (decode_ret == TRUE) {
1096 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1097 /* po->language_file = SIM_EF_LP;*/
1098 else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL)
1099 /* po->language_file = SIM_EF_ELP;*/
1101 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1104 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1105 - EFELP is not available;
1106 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1107 - the ME does not support any of the languages in EFELP.
1110 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1111 - if the EFLI has the value 'FFFF' in its highest priority position
1112 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1114 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1115 if (meta_info->file_id == SIM_EF_LP)
1116 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1118 _get_file_info(o, ur, SIM_EF_LP);
1119 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1120 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI)
1121 _get_file_info(o, ur, SIM_EF_ELP);
1123 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1129 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1130 if (meta_info->current_index == meta_info->rec_count) {
1131 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1133 meta_info->current_index++;
1134 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1136 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1137 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1139 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1144 ur = tcore_user_request_new(NULL, NULL); /* this is for using ur metainfo set/ref functionality. */
1145 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1149 if (meta_info->current_index == meta_info->rec_count) {
1150 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1152 meta_info->current_index++;
1153 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1158 if (meta_info->current_index == meta_info->rec_count) {
1159 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1161 meta_info->current_index++;
1162 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1167 if (meta_info->current_index == meta_info->rec_count) {
1168 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1170 meta_info->current_index++;
1171 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1175 case SIM_EF_USIM_MBI:
1176 if (meta_info->current_index == meta_info->rec_count) {
1177 _get_file_info(0, ur, SIM_EF_MBDN);
1179 meta_info->current_index++;
1180 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1185 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1186 if (meta_info->mb_count == meta_info->mb_data.count) {
1187 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1188 tcore_user_request_send_response(ur, _find_resp_command(ur),
1189 sizeof(struct tresp_sim_read), &meta_info->files);
1191 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1192 if (meta_info->current_index == 0) {
1193 err("Invalid MBDN index");
1194 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1195 tcore_user_request_send_response(ur, _find_resp_command(ur),
1196 sizeof(struct tresp_sim_read), &meta_info->files);
1198 ur = tcore_user_request_ref(ur);
1199 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1204 case SIM_EF_USIM_CFIS:
1205 case SIM_EF_USIM_MWIS:
1206 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1207 if (meta_info->current_index == meta_info->rec_count) {
1208 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1210 meta_info->current_index++;
1211 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1215 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1216 meta_info->files.result = rt;
1217 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1220 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1221 if (rt == SIM_ACCESS_SUCCESS)
1222 meta_info->files.result = SIM_ACCESS_SUCCESS;
1224 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1231 case SIM_EF_OPLMN_ACT:
1232 case SIM_EF_CPHS_CPHS_INFO:
1233 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1234 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1235 case SIM_EF_CPHS_DYNAMICFLAGS:
1236 case SIM_EF_CPHS_DYNAMIC2FLAG:
1237 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1238 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1239 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1243 dbg("File id not handled [0x%x]", meta_info->file_id);
1248 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1250 struct tnoti_sim_status noti_data = {0, };
1252 if (sim_status != tcore_sim_get_status(o)) {
1253 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1254 tcore_sim_get_status(o), sim_status);
1256 /* Update SIM Status */
1257 tcore_sim_set_status(o, sim_status);
1258 noti_data.sim_status = sim_status;
1260 /* Send notification */
1261 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1262 o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
1266 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1268 const TcoreATResponse *resp = data;
1269 UserRequest *ur = NULL;
1270 CoreObject *o = NULL;
1271 GSList *tokens = NULL;
1272 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1278 o = tcore_pending_ref_core_object(p);
1279 ur = tcore_pending_ref_user_request(p);
1281 if (resp->success > 0) {
1284 line = (const char *)resp->lines->data;
1285 tokens = tcore_at_tok_new(line);
1286 if (g_slist_length(tokens) != 1) {
1287 msg("Invalid message");
1288 tcore_at_tok_free(tokens);
1292 state = atoi(g_slist_nth_data(tokens, 0));
1293 dbg("SIM Type is %d", state);
1296 sim_type = SIM_TYPE_GSM;
1297 tcore_sim_set_app_list(o, SIM_APP_TYPE_SIM);
1298 } else if (state == 1) {
1299 sim_type = SIM_TYPE_USIM;
1300 tcore_sim_set_app_list(o, SIM_APP_TYPE_USIM);
1302 sim_type = SIM_TYPE_UNKNOWN;
1305 dbg("RESPONSE NOK");
1306 sim_type = SIM_TYPE_UNKNOWN;
1309 tcore_sim_set_type(o, sim_type);
1311 if (sim_type != SIM_TYPE_UNKNOWN) {
1312 /* set user request for using ur metainfo set/ref functionality */
1313 ur = tcore_user_request_new(NULL, NULL);
1314 _get_file_info(o, ur, SIM_EF_IMSI);
1317 tcore_at_tok_free(tokens);
1321 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1323 const TcoreATResponse *resp = data;
1324 UserRequest *ur = NULL;
1325 CoreObject *o = NULL;
1326 struct imc_sim_property *meta_info = NULL;
1327 GSList *tokens = NULL;
1328 enum tel_sim_access_result rt;
1329 const char *line = NULL;
1335 o = tcore_pending_ref_core_object(p);
1336 ur = tcore_pending_ref_user_request(p);
1337 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1339 if (resp->success > 0) {
1342 line = (const char *)resp->lines->data;
1343 tokens = tcore_at_tok_new(line);
1344 if (g_slist_length(tokens) < 2) {
1345 err("Invalid message");
1346 tcore_at_tok_free(tokens);
1350 sw1 = atoi(g_slist_nth_data(tokens, 0));
1351 sw2 = atoi(g_slist_nth_data(tokens, 1));
1353 /*1. SIM access success case*/
1354 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1355 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1356 unsigned short record_len = 0;
1357 char num_of_records = 0;
1358 unsigned char file_id_len = 0;
1359 unsigned short file_id = 0;
1360 unsigned short file_size = 0;
1361 unsigned short file_type = 0;
1362 unsigned short arr_file_id = 0;
1364 /* handling only last 3 bits */
1365 unsigned char file_type_tag = 0x07;
1366 unsigned char *ptr_data;
1370 char *recordData = NULL;
1371 hexData = g_slist_nth_data(tokens, 2);
1372 dbg("hexData: %s", hexData);
1373 dbg("hexData: %s", hexData + 1);
1375 tmp = tcore_at_tok_extract(hexData);
1376 recordData = util_hexStringToBytes(tmp);
1378 err("util_hexStringToBytes Failed!!");
1379 tcore_at_tok_free(tokens);
1382 tcore_util_hex_dump(" ", strlen(hexData) / 2, recordData);
1385 ptr_data = (unsigned char *)recordData;
1386 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1388 ETSI TS 102 221 v7.9.0
1390 '62' FCP template tag
1391 - Response for an EF
1392 '82' M File Descriptor
1393 '83' M File Identifier
1394 'A5' O Proprietary information
1395 '8A' M Life Cycle Status Integer
1396 '8B', '8C' or 'AB' C1 Security attributes
1398 '81' O Total file size
1399 '88' O Short File Identifier (SFI)
1402 /* rsim.res_len has complete data length received */
1404 /* FCP template tag - File Control Parameters tag*/
1405 if (*ptr_data == 0x62) {
1406 /* parse complete FCP tag*/
1407 /* increment to next byte */
1409 tag_len = *ptr_data++;
1410 dbg("tag_len: %02x", tag_len);
1411 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1412 if (*ptr_data == 0x82) {
1413 /* increment to next byte */
1417 /* unsigned char file_desc_len = *ptr_data++;*/
1418 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1419 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1420 /* consider only last 3 bits*/
1421 dbg("file_type_tag: %02x", file_type_tag);
1422 file_type_tag = file_type_tag & (*ptr_data);
1423 dbg("file_type_tag: %02x", file_type_tag);
1425 switch (file_type_tag) {
1426 /* increment to next byte */
1428 dbg("Getting FileType: [Transparent file type]");
1429 file_type = SIM_FTYPE_TRANSPARENT;
1431 /* increment to next byte */
1433 /* increment to next byte */
1438 dbg("Getting FileType: [Linear fixed file type]");
1439 /* increment to next byte */
1441 /* data coding byte - value 21 */
1444 memcpy(&record_len, ptr_data, 2);
1446 SWAPBYTES16(record_len);
1447 ptr_data = ptr_data + 2;
1448 num_of_records = *ptr_data++;
1449 /* Data lossy conversation from enum (int) to unsigned char */
1450 file_type = SIM_FTYPE_LINEAR_FIXED;
1454 dbg("Cyclic fixed file type");
1455 /* increment to next byte */
1457 /* data coding byte - value 21 */
1460 memcpy(&record_len, ptr_data, 2);
1462 SWAPBYTES16(record_len);
1463 ptr_data = ptr_data + 2;
1464 num_of_records = *ptr_data++;
1465 file_type = SIM_FTYPE_CYCLIC;
1469 dbg("not handled file type [0x%x]", *ptr_data);
1473 dbg("INVALID FCP received - DEbug!");
1474 tcore_at_tok_free(tokens);
1480 * File identifier - file id??
1482 * 0x84, 0x85, 0x86 etc are currently ignored and not handled
1484 if (*ptr_data == 0x83) {
1485 /* increment to next byte */
1487 file_id_len = *ptr_data++;
1488 dbg("file_id_len: %02x", file_id_len);
1490 memcpy(&file_id, ptr_data, file_id_len);
1491 dbg("file_id: %x", file_id);
1494 SWAPBYTES16(file_id);
1495 dbg("file_id: %x", file_id);
1497 ptr_data = ptr_data + 2;
1498 dbg("Getting FileID=[0x%x]", file_id);
1500 dbg("INVALID FCP received - DEbug!");
1501 tcore_at_tok_free(tokens);
1506 /* proprietary information */
1507 if (*ptr_data == 0xA5) {
1508 unsigned short prop_len;
1509 /* increment to next byte */
1513 prop_len = *ptr_data;
1514 dbg("prop_len: %02x", prop_len);
1517 ptr_data = ptr_data + prop_len + 1;
1519 dbg("INVALID FCP received - DEbug!");
1522 /* life cycle status integer [8A][length:0x01][status]*/
1525 00000000 : No information given
1526 00000001 : creation state
1527 00000011 : initialization state
1528 000001-1 : operation state -activated
1529 000001-0 : operation state -deactivated
1530 000011-- : Termination state
1531 b8~b5 !=0, b4~b1=X : Proprietary
1532 Any other value : RFU
1534 if (*ptr_data == 0x8A) {
1535 /* increment to next byte */
1537 /* length - value 1 */
1540 switch (*ptr_data) {
1543 dbg("<RX> operation state -deactivated");
1549 dbg("<RX> operation state -activated");
1554 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1560 /* related to security attributes : currently not handled*/
1561 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1562 /* increment to next byte */
1564 /* if tag length is 3 */
1565 if (*ptr_data == 0x03) {
1566 /* increment to next byte */
1569 memcpy(&arr_file_id, ptr_data, 2);
1571 SWAPBYTES16(arr_file_id);
1572 ptr_data = ptr_data + 2;
1573 ptr_data++; /*arr_file_id_rec_num = *ptr_data++; */
1575 /* if tag length is not 3 */
1576 /* ignoring bytes */
1577 dbg("Useless security attributes, so jump to next tag");
1578 ptr_data = ptr_data + (*ptr_data + 1);
1581 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1582 tcore_at_tok_free(tokens);
1587 dbg("Current ptr_data value is [%x]", *ptr_data);
1589 /* file size excluding structural info*/
1590 if (*ptr_data == 0x80) {
1591 /* for EF file size is body of file and for Linear or cyclic it is
1592 * number of recXsizeof(one record)
1594 /* increment to next byte */
1596 /* length is 1 byte - value is 2 bytes or more */
1598 memcpy(&file_size, ptr_data, 2);
1600 SWAPBYTES16(file_size);
1601 ptr_data = ptr_data + 2;
1603 dbg("INVALID FCP received - DEbug!");
1604 tcore_at_tok_free(tokens);
1609 /* total file size including structural info*/
1610 if (*ptr_data == 0x81) {
1612 /* increment to next byte */
1615 /* len = *ptr_data; */
1617 ptr_data = ptr_data + 3;
1619 dbg("INVALID FCP received - DEbug!");
1620 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1623 /*short file identifier ignored*/
1624 if (*ptr_data == 0x88) {
1625 dbg("0x88: Do Nothing");
1629 dbg("INVALID FCP received - DEbug!");
1630 tcore_at_tok_free(tokens);
1634 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1635 unsigned char gsm_specific_file_data_len = 0;
1636 /* ignore RFU byte1 and byte2 */
1640 memcpy(&file_size, ptr_data, 2);
1642 SWAPBYTES16(file_size);
1643 /* parsed file size */
1644 ptr_data = ptr_data + 2;
1646 memcpy(&file_id, ptr_data, 2);
1647 SWAPBYTES16(file_id);
1648 dbg("FILE id --> [%x]", file_id);
1649 ptr_data = ptr_data + 2;
1650 /* save file type - transparent, linear fixed or cyclic */
1651 file_type_tag = (*(ptr_data + 7));
1653 switch (*ptr_data) {
1656 dbg("RFU file type- not handled - Debug!");
1661 dbg("MF file type - not handled - Debug!");
1666 dbg("DF file type - not handled - Debug!");
1671 dbg("EF file type [%d] ", file_type_tag);
1672 /* increment to next byte */
1675 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1676 /* increament to next byte as this byte is RFU */
1679 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1681 /* increment to next byte */
1683 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1684 /* the INCREASE command is allowed on the selected cyclic file. */
1685 file_type = SIM_FTYPE_CYCLIC;
1687 /* bytes 9 to 11 give SIM file access conditions */
1689 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1691 /* byte 11 is invalidate and rehabilate nibbles */
1693 /* byte 12 - file status */
1695 /* byte 13 - GSM specific data */
1696 gsm_specific_file_data_len = *ptr_data;
1697 dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1699 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1701 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1702 record_len = *ptr_data;
1703 dbg("record length[%d], file size[%d]", record_len, file_size);
1705 if (record_len != 0)
1706 num_of_records = (file_size / record_len);
1708 dbg("Number of records [%d]", num_of_records);
1712 dbg("not handled file type");
1716 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1719 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1720 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1722 meta_info->file_type = file_type;
1723 meta_info->data_size = file_size;
1724 meta_info->rec_length = record_len;
1725 meta_info->rec_count = num_of_records;
1726 meta_info->current_index = 0; /* reset for new record type EF */
1727 rt = SIM_ACCESS_SUCCESS;
1730 /*2. SIM access fail case*/
1731 dbg("error to get ef[0x%x]", meta_info->file_id);
1732 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1733 rt = _decode_status_word(sw1, sw2);
1735 ur = tcore_user_request_ref(ur);
1737 dbg("Calling _next_from_get_file_info");
1738 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1739 tcore_at_tok_free(tokens);
1741 dbg("RESPONSE NOK");
1742 dbg("error to get ef[0x%x]", meta_info->file_id);
1743 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1744 rt = SIM_ACCESS_FAILED;
1746 ur = tcore_user_request_ref(ur);
1747 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1752 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1754 const TcoreATResponse *resp = data;
1755 UserRequest *ur = NULL;
1756 CoreObject *o = NULL;
1757 struct imc_sim_property *meta_info = NULL;
1758 GSList *tokens = NULL;
1759 enum tel_sim_access_result rt;
1760 gboolean dr = FALSE;
1761 const char *line = NULL;
1770 o = tcore_pending_ref_core_object(p);
1771 ur = tcore_pending_ref_user_request(p);
1772 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1774 if (resp->success > 0) {
1777 line = (const char *)resp->lines->data;
1778 tokens = tcore_at_tok_new(line);
1779 if (g_slist_length(tokens) != 3) {
1780 msg("Invalid message");
1781 tcore_at_tok_free(tokens);
1785 sw1 = atoi(g_slist_nth_data(tokens, 0));
1786 sw2 = atoi(g_slist_nth_data(tokens, 1));
1787 res = g_slist_nth_data(tokens, 2);
1789 tmp = tcore_at_tok_extract(res);
1792 res = util_hexStringToBytes(tmp);
1793 res_len = strlen(tmp) / 2;
1794 dbg("Response: [%s] Response length: [%d]", res, res_len);
1796 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1797 rt = SIM_ACCESS_SUCCESS;
1798 meta_info->files.result = rt;
1800 dbg("File ID: [0x%x]", meta_info->file_id);
1801 switch (meta_info->file_id) {
1804 struct tel_sim_imsi *imsi = NULL;
1806 dbg("Data: [%s]", res);
1807 imsi = g_try_new0(struct tel_sim_imsi, 1);
1808 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1810 err("IMSI decoding failed");
1812 _sim_check_identity(o, imsi);
1813 tcore_sim_set_imsi(o, imsi);
1822 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1825 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1826 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1827 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1828 case SIM_EF_LP: /* 1 byte encoding */
1829 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1830 && (meta_info->file_id == SIM_EF_LP)) {
1832 * 2G LP(0x6F05) has 1 byte for each language
1834 dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1835 (unsigned char *)res, res_len);
1838 * 3G LI(0x6F05)/PL(0x2F05),
1839 * 2G ELP(0x2F05) has 2 bytes for each language
1841 dr = tcore_sim_decode_li(meta_info->file_id,
1842 &meta_info->files.data.language,
1843 (unsigned char *)res, res_len);
1848 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1849 (unsigned char *)res, res_len);
1853 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1854 (unsigned char *)res, res_len);
1857 case SIM_EF_SST: /* EF UST has same address */
1859 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1860 dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1862 dbg("SST decoding failed");
1863 tcore_sim_set_service_table(o, NULL);
1865 int i = 0, size = sizeof(struct tel_sim_sst);
1867 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1868 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1869 memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1870 for (i = 0; i < size; i++) {
1876 dbg("svct.table.sst=[%s]", temp);
1879 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1881 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1882 dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1884 dbg("SST decoding failed");
1885 tcore_sim_set_service_table(o, NULL);
1887 int i = 0, size = sizeof(struct tel_sim_ust);
1889 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1890 if ((temp = g_try_malloc0(size + 1)) != NULL) {
1891 memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1892 for (i = 0; i < size; i++) {
1898 dbg("svct.table.ust=[%s]", temp);
1901 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1904 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(o));
1911 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1912 dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1913 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1914 struct tel_sim_ecc *ecc = NULL;
1916 ecc = g_try_new0(struct tel_sim_ecc, 1);
1917 dbg("Index [%d]", meta_info->current_index);
1919 dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1921 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1922 meta_info->files.data.ecc.ecc_count++;
1928 dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1935 struct tel_sim_msisdn *msisdn = NULL;
1937 dbg("Index [%d]", meta_info->current_index);
1938 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1939 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1941 memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1942 msisdn, sizeof(struct tel_sim_msisdn));
1944 meta_info->files.data.msisdn_list.count++;
1954 struct tel_sim_opl *opl = NULL;
1956 dbg("decode w/ index [%d]", meta_info->current_index);
1958 opl = g_try_new0(struct tel_sim_opl, 1);
1959 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1961 memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1962 opl, sizeof(struct tel_sim_opl));
1963 meta_info->files.data.opl.opl_count++;
1973 struct tel_sim_pnn *pnn = NULL;
1975 dbg("decode w/ index [%d]", meta_info->current_index);
1977 pnn = g_try_new0(struct tel_sim_pnn, 1);
1978 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1980 memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1981 pnn, sizeof(struct tel_sim_pnn));
1983 meta_info->files.data.pnn.pnn_count++;
1991 case SIM_EF_OPLMN_ACT:
1992 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1993 (unsigned char *)res, res_len);
1996 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1997 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
2000 case SIM_EF_USIM_MBI: /* linear type */
2002 struct tel_sim_mbi *mbi = NULL;
2004 mbi = g_try_new0(struct tel_sim_mbi, 1);
2005 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
2007 memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
2008 mbi, sizeof(struct tel_sim_mbi));
2009 meta_info->mbi_list.profile_count++;
2011 dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
2012 dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].voice_index);
2013 dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].fax_index);
2014 dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].email_index);
2015 dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].other_index);
2016 dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count - 1].video_index);
2024 case SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
2025 case SIM_EF_MBDN: /* linear type */
2026 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
2027 (unsigned char *)res, res_len);
2028 meta_info->mb_count++;
2031 case SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
2032 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
2033 (unsigned char *)res, res_len);
2036 case SIM_EF_USIM_MWIS: /* linear type */
2038 struct tel_sim_mw *mw = NULL;
2040 mw = g_try_new0(struct tel_sim_mw, 1);
2042 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
2044 memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
2045 meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
2046 meta_info->files.data.mw.mw_list.profile_count++;
2054 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
2055 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2056 (unsigned char *)res, res_len);
2059 case SIM_EF_USIM_CFIS: /* linear type */
2061 struct tel_sim_cfis *cf = NULL;
2063 cf = g_try_new0(struct tel_sim_cfis, 1);
2064 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2066 memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2067 cf, sizeof(struct tel_sim_cfis));
2069 meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2070 meta_info->files.data.cf.cf_list.profile_count++;
2078 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2079 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2082 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2083 dr = tcore_sim_decode_ons((unsigned char *)&meta_info->files.data.cphs_net.full_name,
2084 (unsigned char *)res, res_len);
2085 dbg("meta_info->files.result[%d], meta_info->files.data.cphs_net.full_name[%s]",
2086 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2089 case SIM_EF_CPHS_DYNAMICFLAGS:
2090 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2091 p_data->response, p_data->response_len);*/
2094 case SIM_EF_CPHS_DYNAMIC2FLAG:
2095 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2096 p_data->response_len);*/
2099 case SIM_EF_CPHS_CPHS_INFO:
2100 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2101 (unsigned char *)res, res_len);
2104 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2105 dr = tcore_sim_decode_short_ons((unsigned char *)&meta_info->files.data.cphs_net.short_name,
2106 (unsigned char *)res, res_len);
2109 case SIM_EF_CPHS_INFORMATION_NUMBERS:
2110 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2114 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2119 rt = _decode_status_word(sw1, sw2);
2120 meta_info->files.result = rt;
2128 tcore_at_tok_free(tokens);
2130 dbg("RESPONSE NOK");
2131 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2132 rt = SIM_ACCESS_FAILED;
2135 /* Reference User Request */
2136 ur = tcore_user_request_ref(ur);
2139 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2144 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2146 const TcoreATResponse *resp = data;
2147 UserRequest *ur = NULL;
2148 CoreObject *o = NULL;
2149 struct imc_sim_property *sp = NULL;
2150 GSList *tokens = NULL;
2151 const char *line = NULL;
2153 int attempts_left = 0;
2154 int time_penalty = 0;
2158 o = tcore_pending_ref_core_object(p);
2159 sp = tcore_sim_ref_userdata(o);
2161 err("user data is null");
2164 ur = tcore_pending_ref_user_request(p);
2166 if (resp->success > 0) {
2169 line = (const char *)resp->lines->data;
2170 tokens = tcore_at_tok_new(line);
2171 if (g_slist_length(tokens) < 3) {
2172 msg("Invalid message");
2173 tcore_at_tok_free(tokens);
2177 lock_type = atoi(g_slist_nth_data(tokens, 0));
2178 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2179 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2181 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2182 lock_type, attempts_left, time_penalty);
2184 switch (sp->current_sec_op) {
2185 case SEC_PIN1_VERIFY:
2186 case SEC_PIN2_VERIFY:
2187 case SEC_SIM_VERIFY:
2188 case SEC_ADM_VERIFY:
2190 struct tresp_sim_verify_pins v_pin = {0, };
2192 v_pin.result = SIM_INCORRECT_PASSWORD;
2193 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2194 v_pin.retry_count = attempts_left;
2195 tcore_user_request_send_response(ur, _find_resp_command(ur),
2196 sizeof(struct tresp_sim_verify_pins), &v_pin);
2200 case SEC_PUK1_VERIFY:
2201 case SEC_PUK2_VERIFY:
2203 struct tresp_sim_verify_puks v_puk = {0, };
2205 v_puk.result = SIM_INCORRECT_PASSWORD;
2206 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2207 v_puk.retry_count = attempts_left;
2208 tcore_user_request_send_response(ur, _find_resp_command(ur),
2209 sizeof(struct tresp_sim_verify_puks), &v_puk);
2213 case SEC_PIN1_CHANGE:
2214 case SEC_PIN2_CHANGE:
2216 struct tresp_sim_change_pins change_pin = {0, };
2218 change_pin.result = SIM_INCORRECT_PASSWORD;
2219 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2220 change_pin.retry_count = attempts_left;
2221 tcore_user_request_send_response(ur, _find_resp_command(ur),
2222 sizeof(struct tresp_sim_change_pins), &change_pin);
2226 case SEC_PIN1_DISABLE:
2227 case SEC_PIN2_DISABLE:
2228 case SEC_FDN_DISABLE:
2229 case SEC_SIM_DISABLE:
2230 case SEC_NET_DISABLE:
2231 case SEC_NS_DISABLE:
2232 case SEC_SP_DISABLE:
2233 case SEC_CP_DISABLE:
2235 struct tresp_sim_disable_facility dis_facility = {0, };
2237 dis_facility.result = SIM_INCORRECT_PASSWORD;
2238 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2239 dis_facility.retry_count = attempts_left;
2240 tcore_user_request_send_response(ur, _find_resp_command(ur),
2241 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2245 case SEC_PIN1_ENABLE:
2246 case SEC_PIN2_ENABLE:
2247 case SEC_FDN_ENABLE:
2248 case SEC_SIM_ENABLE:
2249 case SEC_NET_ENABLE:
2254 struct tresp_sim_enable_facility en_facility = {0, };
2256 en_facility.result = SIM_INCORRECT_PASSWORD;
2257 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2258 en_facility.retry_count = attempts_left;
2259 tcore_user_request_send_response(ur, _find_resp_command(ur),
2260 sizeof(struct tresp_sim_enable_facility), &en_facility);
2265 dbg("not handled sec op[%d]", sp->current_sec_op);
2270 tcore_at_tok_free(tokens);
2276 static gboolean _get_sim_type(CoreObject *o)
2278 TcoreHal *hal = NULL;
2279 TcoreATRequest *req = NULL;
2280 TcorePending *pending = NULL;
2281 UserRequest *ur = NULL;
2282 char *cmd_str = NULL;
2286 hal = tcore_object_get_hal(o);
2287 pending = tcore_pending_new(o, 0);
2289 err("Pending is NULL");
2292 cmd_str = g_strdup_printf("AT+XUICC?");
2293 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2295 tcore_pending_free(pending);
2301 dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2302 req->cmd, req->prefix, strlen(req->cmd));
2304 tcore_pending_set_request_data(pending, 0, req);
2305 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2306 tcore_pending_link_user_request(pending, ur);
2307 tcore_hal_send_request(hal, pending);
2313 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2315 TcoreHal *hal = NULL;
2316 TcorePending *pending = NULL;
2317 struct imc_sim_property meta_info = {0, };
2318 char *cmd_str = NULL;
2319 TReturn ret = TCORE_RETURN_FAILURE;
2324 meta_info.file_id = ef;
2325 dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2326 hal = tcore_object_get_hal(o);
2327 dbg("hal: %x", hal);
2329 trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2330 dbg("trt[%d]", trt);
2331 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
2332 dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2334 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2335 tcore_pending_link_user_request(pending, ur);
2336 ret = tcore_hal_send_request(hal, pending);
2337 if (TCORE_RETURN_SUCCESS != ret)
2338 tcore_user_request_free(ur);
2342 return TCORE_RETURN_SUCCESS;
2345 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2347 TcoreHal *hal = NULL;
2348 TcoreATRequest *req = NULL;
2349 TcorePending *pending = NULL;
2350 char *cmd_str = NULL;
2356 hal = tcore_object_get_hal(o);
2357 pending = tcore_pending_new(o, 0);
2359 err("Pending is NULL");
2363 dbg("file_id: %x", ef);
2365 p1 = (unsigned char) (offset & 0xFF00) >> 8;
2366 p2 = (unsigned char) offset & 0x00FF; /* offset low */
2367 p3 = (unsigned char) length;
2369 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
2371 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2373 tcore_pending_free(pending);
2379 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2380 req->cmd, req->prefix, strlen(req->cmd));
2382 tcore_pending_set_request_data(pending, 0, req);
2383 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2384 tcore_pending_link_user_request(pending, ur);
2385 tcore_hal_send_request(hal, pending);
2391 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2393 TcoreHal *hal = NULL;
2394 TcoreATRequest *req = NULL;
2395 TcorePending *pending = NULL;
2396 char *cmd_str = NULL;
2403 hal = tcore_object_get_hal(o);
2404 pending = tcore_pending_new(o, 0);
2406 err("Pending is NULL");
2410 p1 = (unsigned char) index;
2411 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
2412 p3 = (unsigned char) length;
2414 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
2416 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2418 tcore_pending_free(pending);
2424 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2425 req->cmd, req->prefix, strlen(req->cmd));
2427 tcore_pending_set_request_data(pending, 0, req);
2428 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2429 tcore_pending_link_user_request(pending, ur);
2430 tcore_hal_send_request(hal, pending);
2436 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2438 TcoreHal *hal = NULL;
2439 TcoreATRequest *req = NULL;
2440 TcorePending *pending = NULL;
2441 char *cmd_str = NULL;
2443 struct imc_sim_property *sp = NULL;
2447 hal = tcore_object_get_hal(o);
2448 pending = tcore_pending_new(o, 0);
2450 err("Pending is NULL");
2451 return TCORE_RETURN_FAILURE;
2453 sp = tcore_sim_ref_userdata(o);
2455 err("user data is null");
2456 tcore_pending_free(pending);
2457 return TCORE_RETURN_FAILURE;
2460 switch (sp->current_sec_op) {
2461 case SEC_PIN1_VERIFY:
2462 case SEC_PIN1_CHANGE:
2463 case SEC_PIN1_ENABLE:
2464 case SEC_PIN1_DISABLE:
2468 case SEC_PIN2_VERIFY:
2469 case SEC_PIN2_CHANGE:
2470 case SEC_PIN2_ENABLE:
2471 case SEC_PIN2_DISABLE:
2472 case SEC_FDN_ENABLE:
2473 case SEC_FDN_DISABLE:
2477 case SEC_PUK1_VERIFY:
2481 case SEC_PUK2_VERIFY:
2485 case SEC_NET_ENABLE:
2486 case SEC_NET_DISABLE:
2491 case SEC_NS_DISABLE:
2496 case SEC_SP_DISABLE:
2501 case SEC_CP_DISABLE:
2505 case SEC_ADM_VERIFY:
2513 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2514 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2516 tcore_pending_free(pending);
2518 return TCORE_RETURN_FAILURE;
2522 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2523 req->cmd, req->prefix, strlen(req->cmd));
2525 tcore_pending_set_request_data(pending, 0, req);
2526 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2527 tcore_pending_link_user_request(pending, ur);
2528 tcore_hal_send_request(hal, pending);
2531 return TCORE_RETURN_SUCCESS;
2534 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2537 GSList *tokens = NULL;
2538 GSList *lines = NULL;
2540 dbg("Function entry");
2542 lines = (GSList *)event_info;
2543 if (1 != g_slist_length(lines)) {
2544 dbg("unsolicited msg but multiple line");
2547 line = (char *)(lines->data);
2548 tokens = tcore_at_tok_new(line);
2549 if (g_slist_length(tokens) != 1) {
2550 msg("Invalid message");
2551 tcore_at_tok_free(tokens);
2558 tcore_at_tok_free(tokens);
2562 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2563 unsigned int sms_ready)
2565 Server *server = tcore_plugin_ref_server(plugin);
2566 struct tnoti_sms_ready_status sms_ready_noti;
2571 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2572 if (co_sms == NULL) {
2573 err("Can't find SMS core object");
2577 if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2580 tcore_sms_set_ready_status(co_sms, sms_ready);
2582 if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2583 sms_ready_noti.status = sms_ready;
2584 tcore_server_send_notification(server, co_sms,
2585 TNOTI_SMS_DEVICE_READY,
2586 sizeof(sms_ready_noti),
2593 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2595 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2596 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2597 GSList *tokens = NULL;
2601 enum telephony_sms_ready_status sms_state = 0;
2605 lines = (GSList *)event_info;
2606 if (g_slist_length(lines) != 1) {
2607 err("Unsolicited message BUT multiple lines");
2613 /* Create 'tokens' */
2614 tokens = tcore_at_tok_new(line);
2617 if (g_slist_length(tokens) == 4) {
2618 sim_state = atoi(g_slist_nth_data(tokens, 1));
2619 sms_state = atoi(g_slist_nth_data(tokens, 3));
2621 notify_sms_state(plugin, o, sms_state);
2622 } else if (g_slist_length(tokens) == 1) {
2623 sim_state = atoi(g_slist_nth_data(tokens, 0));
2625 err("Invalid message");
2629 switch (sim_state) {
2631 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2636 sim_status = SIM_STATUS_PIN_REQUIRED;
2637 dbg("PIN REQUIRED");
2641 sim_status = SIM_STATUS_INITIALIZING;
2642 dbg("PIN DISABLED AT BOOT UP");
2646 sim_status = SIM_STATUS_INITIALIZING;
2647 dbg("PIN VERIFIED");
2651 sim_status = SIM_STATUS_PUK_REQUIRED;
2652 dbg("PUK REQUIRED");
2656 sim_status = SIM_STATUS_CARD_BLOCKED;
2657 dbg("CARD PERMANENTLY BLOCKED");
2661 sim_status = SIM_STATUS_CARD_ERROR;
2662 dbg("SIM CARD ERROR");
2666 sim_status = SIM_STATUS_INIT_COMPLETED;
2667 dbg("SIM INIT COMPLETED");
2671 sim_status = SIM_STATUS_CARD_ERROR;
2672 dbg("SIM CARD ERROR");
2676 sim_status = SIM_STATUS_CARD_REMOVED;
2681 dbg("SIM SMS Ready");
2682 notify_sms_state(plugin, o, SMS_STATE_READY);
2686 sim_status = SIM_STATUS_UNKNOWN;
2687 dbg("SIM STATE UNKNOWN");
2691 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2695 switch (sim_status) {
2696 case SIM_STATUS_INIT_COMPLETED:
2697 dbg("[SIM] SIM INIT COMPLETED");
2698 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2705 case SIM_STATUS_CARD_REMOVED:
2706 dbg("[SIM] SIM CARD REMOVED");
2707 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2710 case SIM_STATUS_CARD_NOT_PRESENT:
2711 dbg("[SIM] SIM CARD NOT PRESENT");
2712 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2715 case SIM_STATUS_CARD_ERROR:
2716 dbg("[SIM] SIM CARD ERROR");
2717 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2721 dbg("SIM Status: [0x%02x]", sim_status);
2725 _sim_status_update(o, sim_status);
2728 tcore_at_tok_free(tokens);
2734 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2736 const TcoreATResponse *resp = data;
2737 CoreObject *o = NULL;
2741 o = tcore_pending_ref_core_object(p);
2743 if (resp->success > 0) {
2746 on_event_pin_status(o, resp->lines, NULL);
2748 dbg("RESPONSE NOK");
2754 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2755 unsigned int data_len, void *data, void *user_data)
2757 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2758 CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2761 return TCORE_HOOK_RETURN_CONTINUE;
2763 dbg("Get SIM status");
2765 sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2767 return TCORE_HOOK_RETURN_CONTINUE;
2770 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2772 const TcoreATResponse *resp = data;
2773 UserRequest *ur = NULL;
2774 CoreObject *co_sim = NULL;
2775 struct imc_sim_property *sp = NULL;
2776 GSList *tokens = NULL;
2777 struct tresp_sim_verify_pins res;
2783 co_sim = tcore_pending_ref_core_object(p);
2784 sp = tcore_sim_ref_userdata(co_sim);
2786 err("user data is null");
2790 ur = tcore_pending_ref_user_request(p);
2792 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2794 if (resp->success > 0) {
2796 res.result = SIM_PIN_OPERATION_SUCCESS;
2798 /* Get PIN facility */
2799 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2800 if ((res.pin_type == SIM_PTYPE_PIN1)
2801 || (res.pin_type == SIM_PTYPE_SIM)) {
2802 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2803 /* Update SIM Status */
2804 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2809 tcore_user_request_send_response(ur, _find_resp_command(ur),
2810 sizeof(struct tresp_sim_verify_pins), &res);
2812 dbg("RESPONSE NOK");
2813 line = (const char *)resp->final_response;
2814 tokens = tcore_at_tok_new(line);
2815 if (g_slist_length(tokens) < 1) {
2816 dbg("Unkown Error OR String corrupted");
2817 res.result = TCORE_RETURN_3GPP_ERROR;
2820 tcore_user_request_send_response(ur, _find_resp_command(ur),
2821 sizeof(struct tresp_sim_verify_pins), &res);
2823 err = atoi(g_slist_nth_data(tokens, 0));
2824 dbg("Error: [%d]", err);
2826 ur = tcore_user_request_ref(ur);
2828 /* Get retry count */
2829 _get_retry_count(co_sim, ur);
2833 tcore_at_tok_free(tokens);
2839 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2841 const TcoreATResponse *resp = data;
2842 UserRequest *ur = NULL;
2843 CoreObject *co_sim = NULL;
2844 struct imc_sim_property *sp = NULL;
2845 GSList *tokens = NULL;
2846 struct tresp_sim_verify_puks res;
2852 co_sim = tcore_pending_ref_core_object(p);
2853 sp = tcore_sim_ref_userdata(co_sim);
2855 err("user data is null");
2859 ur = tcore_pending_ref_user_request(p);
2861 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2863 if (resp->success > 0) {
2865 res.result = SIM_PIN_OPERATION_SUCCESS;
2866 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2869 tcore_user_request_send_response(ur, _find_resp_command(ur),
2870 sizeof(struct tresp_sim_verify_pins), &res);
2872 dbg("RESPONSE NOK");
2873 line = (const char *)resp->final_response;
2874 tokens = tcore_at_tok_new(line);
2876 if (g_slist_length(tokens) < 1) {
2877 dbg("Unkown Error OR String corrupted");
2878 res.result = TCORE_RETURN_3GPP_ERROR;
2881 tcore_user_request_send_response(ur, _find_resp_command(ur),
2882 sizeof(struct tresp_sim_verify_pins), &res);
2884 err = atoi(g_slist_nth_data(tokens, 0));
2885 dbg("Error: [%d]", err);
2886 ur = tcore_user_request_ref(ur);
2887 _get_retry_count(co_sim, ur);
2889 tcore_at_tok_free(tokens);
2894 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2896 const TcoreATResponse *resp = data;
2897 UserRequest *ur = NULL;
2898 CoreObject *co_sim = NULL;
2899 struct imc_sim_property *sp = NULL;
2900 GSList *tokens = NULL;
2901 struct tresp_sim_change_pins res;
2907 co_sim = tcore_pending_ref_core_object(p);
2908 sp = tcore_sim_ref_userdata(co_sim);
2910 err("user data is null");
2914 ur = tcore_pending_ref_user_request(p);
2916 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2918 if (resp->success > 0) {
2920 res.result = SIM_PIN_OPERATION_SUCCESS;
2921 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2924 tcore_user_request_send_response(ur, _find_resp_command(ur),
2925 sizeof(struct tresp_sim_change_pins), &res);
2927 dbg("RESPONSE NOK");
2928 line = (const char *)resp->final_response;
2929 tokens = tcore_at_tok_new(line);
2931 if (g_slist_length(tokens) < 1) {
2932 dbg("Unkown Error OR String corrupted");
2933 res.result = TCORE_RETURN_3GPP_ERROR;
2936 tcore_user_request_send_response(ur, _find_resp_command(ur),
2937 sizeof(struct tresp_sim_change_pins), &res);
2939 err = atoi(g_slist_nth_data(tokens, 0));
2940 dbg("Error: [%d]", err);
2941 ur = tcore_user_request_ref(ur);
2942 _get_retry_count(co_sim, ur);
2946 tcore_at_tok_free(tokens);
2951 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2953 const TcoreATResponse *resp = data;
2954 UserRequest *ur = NULL;
2955 GSList *tokens = NULL;
2956 struct tresp_sim_get_facility_status *res = user_data;
2961 ur = tcore_pending_ref_user_request(p);
2963 res->result = SIM_PIN_OPERATION_SUCCESS;
2965 if (resp->success > 0) {
2968 line = (const char *)resp->lines->data;
2969 tokens = tcore_at_tok_new(line);
2970 if (g_slist_length(tokens) != 1) {
2971 msg("Invalid message");
2972 tcore_at_tok_free(tokens);
2976 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2978 dbg("RESPONSE NOK");
2979 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2984 tcore_user_request_send_response(ur, _find_resp_command(ur),
2985 sizeof(struct tresp_sim_get_facility_status), res);
2987 tcore_at_tok_free(tokens);
2992 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2994 const TcoreATResponse *resp = data;
2995 UserRequest *ur = NULL;
2996 CoreObject *co_sim = NULL;
2997 struct imc_sim_property *sp = NULL;
2998 GSList *tokens = NULL;
2999 struct tresp_sim_enable_facility res;
3004 co_sim = tcore_pending_ref_core_object(p);
3005 sp = tcore_sim_ref_userdata(co_sim);
3007 err("user data is null");
3011 ur = tcore_pending_ref_user_request(p);
3013 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
3015 res.result = SIM_CARD_ERROR;
3016 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3018 if (resp->success > 0) {
3021 line = (const char *)resp->lines->data;
3022 tokens = tcore_at_tok_new(line);
3023 if (g_slist_length(tokens) != 1) {
3024 msg("Invalid message");
3027 tcore_user_request_send_response(ur, _find_resp_command(ur),
3028 sizeof(struct tresp_sim_enable_facility), &res);
3029 tcore_at_tok_free(tokens);
3034 res.result = SIM_PIN_OPERATION_SUCCESS;
3038 tcore_user_request_send_response(ur, _find_resp_command(ur),
3039 sizeof(struct tresp_sim_enable_facility), &res);
3043 tcore_at_tok_free(tokens);
3045 dbg("RESPONSE NOK");
3046 ur = tcore_user_request_ref(ur);
3047 _get_retry_count(co_sim, ur);
3052 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
3054 const TcoreATResponse *resp = data;
3055 UserRequest *ur = NULL;
3056 CoreObject *co_sim = NULL;
3057 struct imc_sim_property *sp = NULL;
3058 GSList *tokens = NULL;
3059 struct tresp_sim_disable_facility res;
3064 co_sim = tcore_pending_ref_core_object(p);
3065 sp = tcore_sim_ref_userdata(co_sim);
3067 err("user data is null");
3071 ur = tcore_pending_ref_user_request(p);
3073 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
3075 res.result = SIM_CARD_ERROR;
3076 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
3078 if (resp->success > 0) {
3081 line = (const char *)resp->lines->data;
3082 tokens = tcore_at_tok_new(line);
3083 if (g_slist_length(tokens) != 1) {
3084 msg("Invalid message");
3087 tcore_user_request_send_response(ur, _find_resp_command(ur),
3088 sizeof(struct tresp_sim_disable_facility), &res);
3089 tcore_at_tok_free(tokens);
3094 res.result = SIM_PIN_OPERATION_SUCCESS;
3097 tcore_user_request_send_response(ur, _find_resp_command(ur),
3098 sizeof(struct tresp_sim_disable_facility), &res);
3101 tcore_at_tok_free(tokens);
3103 dbg("RESPONSE NOK");
3104 ur = tcore_user_request_ref(ur);
3105 _get_retry_count(co_sim, ur);
3110 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
3112 const TcoreATResponse *response = (TcoreATResponse *)data;
3113 UserRequest *ur = NULL;
3114 GSList *tokens = NULL;
3115 struct treq_sim_get_lock_info *req_data = NULL;
3116 struct tresp_sim_get_lock_info resp;
3118 int pin1_attempts_left = 0;
3119 int puk1_attempts_left = 0;
3120 int pin2_attempts_left = 0;
3121 int puk2_attempts_left = 0;
3122 int length_tokens = 0;
3126 memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3128 ur = tcore_pending_ref_user_request(p);
3130 if (!ur || !response) {
3131 err("NULL data : ur[%p], response[%p]", ur, response);
3132 resp.result = SIM_CARD_ERROR;
3133 tcore_user_request_send_response(ur, _find_resp_command(ur),
3134 sizeof(struct tresp_sim_get_lock_info), &resp);
3138 req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3140 resp.result = SIM_PIN_OPERATION_SUCCESS;
3141 resp.type = req_data->type;
3143 if (response->success > 0) {
3145 if (response->lines) {
3146 line = (const char *)response->lines->data;
3147 tokens = tcore_at_tok_new(line);
3148 length_tokens = g_slist_length(tokens);
3149 dbg("No of Tokens [%d]", length_tokens);
3150 switch (length_tokens) {
3152 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3154 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3156 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3158 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3162 err("Invalid response");
3163 tcore_at_tok_free(tokens);
3164 resp.result = SIM_CARD_ERROR;
3165 tcore_user_request_send_response(ur, _find_resp_command(ur),
3166 sizeof(struct tresp_sim_get_lock_info), &resp);
3171 dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3172 pin1_attempts_left, puk1_attempts_left);
3173 dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3174 pin2_attempts_left, puk2_attempts_left);
3176 resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3178 switch (resp.type) {
3179 case SIM_FACILITY_SC:
3180 resp.retry_count = pin1_attempts_left;
3181 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3182 resp.lock_status = SIM_LOCK_STATUS_PIN;
3183 } else if (pin1_attempts_left == 0) {
3184 if (puk1_attempts_left) {
3185 resp.lock_status = SIM_LOCK_STATUS_PUK;
3186 resp.retry_count = puk1_attempts_left;
3188 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3193 case SIM_FACILITY_FD:
3194 resp.retry_count = pin2_attempts_left;
3195 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3196 resp.lock_status = SIM_LOCK_STATUS_PIN2;
3197 } else if (pin2_attempts_left == 0) {
3198 if (puk2_attempts_left) {
3199 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3200 resp.retry_count = puk2_attempts_left;
3202 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3208 err("Unhandled facility type : [%d]", resp.type);
3211 dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3212 tcore_at_tok_free(tokens);
3215 err("RESPONSE NOK");
3216 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3220 tcore_user_request_send_response(ur, _find_resp_command(ur),
3221 sizeof(struct tresp_sim_get_lock_info), &resp);
3224 void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
3226 UserRequest *ur = NULL;
3227 GSList *tokens = NULL;
3228 const char *line = NULL;
3229 const TcoreATResponse *response = (TcoreATResponse *)data;
3230 CoreObject *co_sim = NULL;
3231 struct imc_sim_property *meta_info = NULL;
3232 struct tresp_sim_set_data resp;
3235 gboolean cphs_sim = FALSE;
3236 enum tcore_request_command command;
3239 memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3241 ur = tcore_pending_ref_user_request(p);
3242 command = tcore_user_request_get_command(ur);
3243 co_sim = tcore_pending_ref_core_object(p);
3244 cphs_sim = tcore_sim_get_cphs_status(co_sim);
3245 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3247 if (!ur || !co_sim || !meta_info || !response) {
3248 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3249 resp.result = SIM_CARD_ERROR;
3252 if (response->success > 0) {
3254 if (response->lines) {
3255 line = (const char *)response->lines->data;
3256 tokens = tcore_at_tok_new(line);
3257 if (g_slist_length(tokens) < 2) {
3258 err("Invalid response");
3259 resp.result = SIM_CARD_ERROR;
3261 sw1 = atoi(g_slist_nth_data(tokens, 0));
3262 sw2 = atoi(g_slist_nth_data(tokens, 1));
3264 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91)
3265 resp.result = SIM_ACCESS_SUCCESS;
3267 resp.result = _decode_status_word(sw1, sw2);
3269 tcore_at_tok_free(tokens);
3272 err("RESPONSE NOK");
3273 resp.result = SIM_ACCESS_FAILED;
3277 if (cphs_sim == FALSE) {
3279 case TREQ_SIM_SET_MAILBOX:
3280 if (meta_info->file_id == SIM_EF_USIM_MBI) {
3281 if (resp.result == SIM_ACCESS_SUCCESS) {
3282 ur = tcore_user_request_ref(ur);
3283 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3285 dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3286 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3287 ur = tcore_user_request_ref(ur);
3288 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3298 case TREQ_SIM_SET_MAILBOX:
3299 if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3300 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3305 case TREQ_SIM_SET_CALLFORWARDING:
3306 if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3307 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3312 case TREQ_SIM_SET_MESSAGEWAITING:
3313 if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3314 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3326 tcore_user_request_send_response(ur, _find_resp_command(ur),
3327 sizeof(struct tresp_sim_set_data), &resp);
3330 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3332 const TcoreATResponse *resp = data;
3333 UserRequest *ur = NULL;
3334 struct tresp_sim_transmit_apdu res;
3339 ur = tcore_pending_ref_user_request(p);
3341 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3342 res.result = SIM_ACCESS_FAILED;
3344 if (resp->success > 0) {
3347 GSList *tokens = NULL;
3349 char *decoded_data = NULL;
3350 line = (const char *)resp->lines->data;
3351 tokens = tcore_at_tok_new(line);
3352 if (g_slist_length(tokens) != 2) {
3353 msg("Invalid message");
3354 tcore_at_tok_free(tokens);
3355 res.result = SIM_CARD_ERROR;
3359 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3361 decoded_data = util_hexStringToBytes(tmp);
3363 res.apdu_resp_length = strlen(tmp) / 2;
3364 res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3365 if (res.apdu_resp == NULL) {
3366 err("Memory allocation failed!!");
3367 tcore_at_tok_free(tokens);
3369 g_free(decoded_data);
3372 memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3374 g_free(decoded_data);
3375 res.result = SIM_ACCESS_SUCCESS;
3376 tcore_at_tok_free(tokens);
3378 err("util_hexStringToBytes Failed!!");
3384 dbg("RESPONSE NOK");
3390 tcore_user_request_send_response(ur, _find_resp_command(ur),
3391 sizeof(struct tresp_sim_transmit_apdu), &res);
3396 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3398 const TcoreATResponse *resp = data;
3399 UserRequest *ur = NULL;
3400 GSList *tokens = NULL;
3401 struct tresp_sim_get_atr res;
3406 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3407 ur = tcore_pending_ref_user_request(p);
3409 res.result = SIM_ACCESS_FAILED;
3410 if (resp->success > 0) {
3414 char *decoded_data = NULL;
3415 line = (const char *)resp->lines->data;
3416 tokens = tcore_at_tok_new(line);
3417 if (g_slist_length(tokens) < 1) {
3418 msg("Invalid message");
3422 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3424 decoded_data = util_hexStringToBytes(tmp);
3425 if (!decoded_data) {
3426 err("util_hexStringToBytes Failed!!");
3430 res.atr_length = strlen(tmp) / 2;
3431 memcpy((char *)res.atr, decoded_data, res.atr_length);
3433 g_free(decoded_data);
3434 res.result = SIM_ACCESS_SUCCESS;
3438 dbg("RESPONSE NOK");
3444 tcore_user_request_send_response(ur, _find_resp_command(ur),
3445 sizeof(struct tresp_sim_get_atr), &res);
3447 tcore_at_tok_free(tokens);
3451 static void on_response_req_authentication(TcorePending *p, int data_len,
3452 const void *data, void *user_data)
3454 const TcoreATResponse *at_resp = data;
3455 GSList *tokens = NULL;
3456 struct tresp_sim_req_authentication resp_auth;
3457 const struct treq_sim_req_authentication *req_data;
3458 UserRequest *ur = tcore_pending_ref_user_request(p);
3462 memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3464 if (at_resp == NULL) {
3465 err("at_resp is NULL");
3466 resp_auth.result = SIM_ACCESS_FAILED;
3467 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3471 req_data = tcore_user_request_ref_data(ur, NULL);
3472 if (req_data == NULL) {
3473 err("req_data is NULL");
3474 resp_auth.result = SIM_ACCESS_FAILED;
3475 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3478 resp_auth.auth_type = req_data->auth_type;
3480 if (at_resp->success == TRUE) {
3485 if (at_resp->lines != NULL) {
3486 line = at_resp->lines->data;
3487 dbg("Received data: [%s]", line);
3489 err("at_resp->lines is NULL");
3490 resp_auth.result = SIM_ACCESS_FAILED;
3491 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3495 tokens = tcore_at_tok_new(line);
3496 if (tokens == NULL) {
3497 err("tokens is NULL");
3498 resp_auth.result = SIM_ACCESS_FAILED;
3499 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3503 status = atoi(g_slist_nth_data(tokens, 0));
3506 dbg("Authentications successful");
3507 resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3510 err("Synchronize fail");
3511 resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3515 resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3518 err("Does not support security context");
3519 resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3522 err("Other failure");
3523 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3527 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3529 char *convert_kc, *convert_sres;
3531 kc = g_slist_nth_data(tokens, 1);
3533 kc = tcore_at_tok_extract(kc);
3534 dbg("Kc: [%s]", kc);
3535 convert_kc = util_hexStringToBytes(kc);
3536 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3537 resp_auth.authentication_key_length = strlen(convert_kc);
3538 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3541 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3547 sres = g_slist_nth_data(tokens, 2);
3549 sres = tcore_at_tok_extract(sres);
3550 dbg("SRES: [%s]", sres);
3551 convert_sres = util_hexStringToBytes(sres);
3552 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3553 resp_auth.resp_length = strlen(convert_sres);
3554 memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3556 err("Invalid SRES");
3557 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3560 g_free(convert_sres);
3562 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3563 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3567 err("RESPONSE NOK");
3568 resp_auth.result = SIM_ACCESS_FAILED;
3569 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3573 tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3574 sizeof(struct tresp_sim_req_authentication), &resp_auth);
3576 tcore_at_tok_free(tokens);
3579 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3581 TcoreHal *hal = NULL;
3582 TcoreATRequest *req = NULL;
3583 TcorePending *pending = NULL;
3584 char *cmd_str = NULL;
3585 const struct treq_sim_verify_pins *req_data = NULL;
3586 struct imc_sim_property *sp = NULL;
3587 TReturn ret = TCORE_RETURN_FAILURE;
3591 if ((o == NULL) || (ur == NULL))
3592 return TCORE_RETURN_EINVAL;
3594 hal = tcore_object_get_hal(o);
3595 if (FALSE == tcore_hal_get_power_state(hal)) {
3596 err("CP NOT READY");
3597 return TCORE_RETURN_ENOSYS;
3600 sp = tcore_sim_ref_userdata(o);
3602 err("user data is null");
3603 return TCORE_RETURN_FAILURE;
3606 pending = tcore_pending_new(o, 0);
3608 err("Pending is NULL");
3609 return TCORE_RETURN_FAILURE;
3612 req_data = tcore_user_request_ref_data(ur, NULL);
3614 if (req_data->pin_type == SIM_PTYPE_PIN1) {
3615 sp->current_sec_op = SEC_PIN1_VERIFY;
3616 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3617 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3618 sp->current_sec_op = SEC_PIN2_VERIFY;
3619 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3620 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3621 sp->current_sec_op = SEC_SIM_VERIFY;
3622 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3623 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3624 sp->current_sec_op = SEC_ADM_VERIFY;
3625 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3627 tcore_pending_free(pending);
3628 return TCORE_RETURN_EINVAL;
3631 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3633 tcore_pending_free(pending);
3635 return TCORE_RETURN_FAILURE;
3639 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3640 req->cmd, req->prefix, strlen(req->cmd));
3642 tcore_pending_set_request_data(pending, 0, req);
3643 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3644 tcore_pending_link_user_request(pending, ur);
3645 ret = tcore_hal_send_request(hal, pending);
3651 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3653 TcoreHal *hal = NULL;
3654 TcoreATRequest *req = NULL;
3655 TcorePending *pending = NULL;
3656 char *cmd_str = NULL;
3657 const struct treq_sim_verify_puks *req_data;
3658 struct imc_sim_property *sp = NULL;
3659 TReturn ret = TCORE_RETURN_FAILURE;
3663 if ((o == NULL) || (ur == NULL))
3664 return TCORE_RETURN_EINVAL;
3666 hal = tcore_object_get_hal(o);
3667 if (FALSE == tcore_hal_get_power_state(hal)) {
3668 err("CP NOT READY");
3669 return TCORE_RETURN_ENOSYS;
3672 sp = tcore_sim_ref_userdata(o);
3674 err("user data is null");
3675 return TCORE_RETURN_FAILURE;
3678 pending = tcore_pending_new(o, 0);
3680 err("Pending is NULL");
3681 return TCORE_RETURN_FAILURE;
3684 req_data = tcore_user_request_ref_data(ur, NULL);
3686 if (req_data->puk_type == SIM_PTYPE_PUK1) {
3687 sp->current_sec_op = SEC_PUK1_VERIFY;
3688 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3689 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3690 sp->current_sec_op = SEC_PUK2_VERIFY;
3691 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3693 tcore_pending_free(pending);
3694 return TCORE_RETURN_EINVAL;
3697 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3699 tcore_pending_free(pending);
3701 return TCORE_RETURN_FAILURE;
3705 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3706 req->cmd, req->prefix, strlen(req->cmd));
3708 tcore_pending_set_request_data(pending, 0, req);
3709 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3710 tcore_pending_link_user_request(pending, ur);
3711 ret = tcore_hal_send_request(hal, pending);
3717 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3719 TcoreHal *hal = NULL;
3720 TcoreATRequest *req = NULL;
3721 TcorePending *pending = NULL;
3722 char *cmd_str = NULL;
3723 const struct treq_sim_change_pins *req_data;
3724 struct imc_sim_property *sp = NULL;
3727 TReturn ret = TCORE_RETURN_FAILURE;
3731 if ((o == NULL) || (ur == NULL))
3732 return TCORE_RETURN_EINVAL;
3734 hal = tcore_object_get_hal(o);
3735 if (FALSE == tcore_hal_get_power_state(hal)) {
3736 err("CP NOT READY");
3737 return TCORE_RETURN_ENOSYS;
3740 sp = tcore_sim_ref_userdata(o);
3742 err("user data is null");
3743 return TCORE_RETURN_FAILURE;
3746 pending = tcore_pending_new(o, 0);
3748 err("Pending is NULL");
3749 return TCORE_RETURN_FAILURE;
3752 req_data = tcore_user_request_ref_data(ur, NULL);
3754 if (req_data->type == SIM_PTYPE_PIN1) {
3755 sp->current_sec_op = SEC_PIN1_CHANGE;
3756 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3757 } else if (req_data->type == SIM_PTYPE_PIN2) {
3758 sp->current_sec_op = SEC_PIN2_CHANGE;
3759 cmd_str = g_strdup_printf("AT+CPWD=\"%s\", \"%s\", \"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3761 tcore_pending_free(pending);
3762 return TCORE_RETURN_EINVAL;
3764 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3766 tcore_pending_free(pending);
3768 return TCORE_RETURN_FAILURE;
3772 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3773 req->cmd, req->prefix, strlen(req->cmd));
3775 tcore_pending_set_request_data(pending, 0, req);
3776 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3777 tcore_pending_link_user_request(pending, ur);
3778 ret = tcore_hal_send_request(hal, pending);
3784 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3786 TcoreHal *hal = NULL;
3787 TcoreATRequest *req = NULL;
3788 TcorePending *pending = NULL;
3789 char *cmd_str = NULL;
3790 const struct treq_sim_get_facility_status *req_data;
3791 struct tresp_sim_get_facility_status *res;
3793 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
3794 TReturn ret = TCORE_RETURN_FAILURE;
3798 if ((o == NULL) || (ur == NULL))
3799 return TCORE_RETURN_EINVAL;
3801 hal = tcore_object_get_hal(o);
3802 if (FALSE == tcore_hal_get_power_state(hal)) {
3803 err("CP NOT READY");
3804 return TCORE_RETURN_ENOSYS;
3807 pending = tcore_pending_new(o, 0);
3809 err("Pending is NULL");
3810 return TCORE_RETURN_FAILURE;
3813 req_data = tcore_user_request_ref_data(ur, NULL);
3815 res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3817 tcore_pending_free(pending);
3818 return TCORE_RETURN_ENOMEM;
3821 res->type = req_data->type;
3823 if (req_data->type == SIM_FACILITY_PS)
3824 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3825 else if (req_data->type == SIM_FACILITY_SC)
3826 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3827 else if (req_data->type == SIM_FACILITY_FD)
3828 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3829 else if (req_data->type == SIM_FACILITY_PN)
3830 fac = "PN"; /*Network Personalization*/
3831 else if (req_data->type == SIM_FACILITY_PU)
3832 fac = "PU"; /*network sUbset Personalization*/
3833 else if (req_data->type == SIM_FACILITY_PP)
3834 fac = "PP"; /*service Provider Personalization*/
3835 else if (req_data->type == SIM_FACILITY_PC)
3836 fac = "PC"; /*Corporate Personalization*/
3838 return TCORE_RETURN_EINVAL;
3840 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3841 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3843 tcore_pending_free(pending);
3845 return TCORE_RETURN_FAILURE;
3849 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3850 req->cmd, req->prefix, strlen(req->cmd));
3852 tcore_pending_set_request_data(pending, 0, req);
3853 tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3854 tcore_pending_link_user_request(pending, ur);
3855 ret = tcore_hal_send_request(hal, pending);
3861 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3863 TcoreHal *hal = NULL;
3864 TcoreATRequest *req = NULL;
3865 TcorePending *pending = NULL;
3866 char *cmd_str = NULL;
3867 const struct treq_sim_enable_facility *req_data;
3868 struct imc_sim_property *sp = NULL;
3870 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
3871 TReturn ret = TCORE_RETURN_FAILURE;
3875 if ((o == NULL) || (ur == NULL))
3876 return TCORE_RETURN_EINVAL;
3878 hal = tcore_object_get_hal(o);
3879 if (FALSE == tcore_hal_get_power_state(hal)) {
3880 err("CP NOT READY");
3881 return TCORE_RETURN_ENOSYS;
3884 sp = tcore_sim_ref_userdata(o);
3886 err("user data is null");
3887 return TCORE_RETURN_FAILURE;
3890 pending = tcore_pending_new(o, 0);
3892 err("Pending is NULL");
3893 return TCORE_RETURN_FAILURE;
3896 req_data = tcore_user_request_ref_data(ur, NULL);
3898 if (req_data->type == SIM_FACILITY_PS) {
3899 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3900 sp->current_sec_op = SEC_SIM_ENABLE;
3901 } else if (req_data->type == SIM_FACILITY_SC) {
3902 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3903 sp->current_sec_op = SEC_PIN1_ENABLE;
3904 } else if (req_data->type == SIM_FACILITY_FD) {
3905 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3906 sp->current_sec_op = SEC_FDN_ENABLE;
3907 } else if (req_data->type == SIM_FACILITY_PN) {
3908 fac = "PN"; /*Network Personalization*/
3909 sp->current_sec_op = SEC_NET_ENABLE;
3910 } else if (req_data->type == SIM_FACILITY_PU) {
3911 fac = "PU"; /*network sUbset Personalization*/
3912 sp->current_sec_op = SEC_NS_ENABLE;
3913 } else if (req_data->type == SIM_FACILITY_PP) {
3914 fac = "PP"; /*service Provider Personalization*/
3915 sp->current_sec_op = SEC_SP_ENABLE;
3916 } else if (req_data->type == SIM_FACILITY_PC) {
3917 fac = "PC"; /*Corporate Personalization*/
3918 sp->current_sec_op = SEC_CP_ENABLE;
3920 return TCORE_RETURN_EINVAL;
3922 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3923 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3925 tcore_pending_free(pending);
3927 return TCORE_RETURN_FAILURE;
3931 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3932 req->cmd, req->prefix, strlen(req->cmd));
3934 tcore_pending_set_request_data(pending, 0, req);
3935 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3936 tcore_pending_link_user_request(pending, ur);
3937 ret = tcore_hal_send_request(hal, pending);
3943 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3946 TcoreATRequest *req;
3947 TcorePending *pending = NULL;
3948 char *cmd_str = NULL;
3949 const struct treq_sim_enable_facility *req_data;
3950 struct imc_sim_property *sp = NULL;
3952 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
3953 TReturn ret = TCORE_RETURN_FAILURE;
3957 if ((o == NULL) || (ur == NULL))
3958 return TCORE_RETURN_EINVAL;
3960 hal = tcore_object_get_hal(o);
3961 if (FALSE == tcore_hal_get_power_state(hal)) {
3962 err("CP NOT READY");
3963 return TCORE_RETURN_ENOSYS;
3966 sp = tcore_sim_ref_userdata(o);
3968 err("user data is null");
3969 return TCORE_RETURN_FAILURE;
3972 pending = tcore_pending_new(o, 0);
3974 err("Pending is NULL");
3975 return TCORE_RETURN_FAILURE;
3978 req_data = tcore_user_request_ref_data(ur, NULL);
3980 if (req_data->type == SIM_FACILITY_PS) {
3981 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3982 sp->current_sec_op = SEC_SIM_DISABLE;
3983 } else if (req_data->type == SIM_FACILITY_SC) {
3984 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3985 sp->current_sec_op = SEC_PIN1_DISABLE;
3986 } else if (req_data->type == SIM_FACILITY_FD) {
3987 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3988 sp->current_sec_op = SEC_FDN_DISABLE;
3989 } else if (req_data->type == SIM_FACILITY_PN) {
3990 fac = "PN"; /*Network Personalization*/
3991 sp->current_sec_op = SEC_NET_DISABLE;
3992 } else if (req_data->type == SIM_FACILITY_PU) {
3993 fac = "PU"; /*network sUbset Personalization*/
3994 sp->current_sec_op = SEC_NS_DISABLE;
3995 } else if (req_data->type == SIM_FACILITY_PP) {
3996 fac = "PP"; /*service Provider Personalization*/
3997 sp->current_sec_op = SEC_SP_DISABLE;
3998 } else if (req_data->type == SIM_FACILITY_PC) {
3999 fac = "PC"; /*Corporate Personalization*/
4000 sp->current_sec_op = SEC_CP_DISABLE;
4002 return TCORE_RETURN_EINVAL;
4004 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
4005 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
4007 tcore_pending_free(pending);
4009 return TCORE_RETURN_FAILURE;
4013 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4014 req->cmd, req->prefix, strlen(req->cmd));
4016 tcore_pending_set_request_data(pending, 0, req);
4017 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
4018 tcore_pending_link_user_request(pending, ur);
4019 ret = tcore_hal_send_request(hal, pending);
4025 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
4027 TcoreHal *hal = NULL;
4028 TcoreATRequest *req = NULL;
4029 TcorePending *pending = NULL;
4033 hal = tcore_object_get_hal(o);
4034 pending = tcore_pending_new(o, 0);
4036 err("Pending is NULL");
4037 return TCORE_RETURN_FAILURE;
4040 if ((o == NULL) || (ur == NULL)) {
4041 tcore_pending_free(pending);
4042 return TCORE_RETURN_EINVAL;
4044 req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
4047 tcore_pending_free(pending);
4048 return TCORE_RETURN_FAILURE;
4051 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
4052 req->cmd, req->prefix, strlen(req->cmd));
4054 tcore_pending_set_request_data(pending, 0, req);
4055 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
4056 tcore_pending_link_user_request(pending, ur);
4057 tcore_hal_send_request(hal, pending);
4060 return TCORE_RETURN_SUCCESS;
4063 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
4065 TReturn api_ret = TCORE_RETURN_SUCCESS;
4066 enum tcore_request_command command;
4070 if ((o == NULL) || (ur == NULL))
4071 return TCORE_RETURN_EINVAL;
4073 command = tcore_user_request_get_command(ur);
4074 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
4075 err("CP NOT READY");
4076 return TCORE_RETURN_ENOSYS;
4080 case TREQ_SIM_GET_ECC:
4081 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
4084 case TREQ_SIM_GET_LANGUAGE:
4085 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
4086 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
4087 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
4088 api_ret = _get_file_info(o, ur, SIM_EF_LP);
4090 api_ret = TCORE_RETURN_ENOSYS;
4093 case TREQ_SIM_GET_ICCID:
4094 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
4097 case TREQ_SIM_GET_MAILBOX:
4098 if (tcore_sim_get_cphs_status(o))
4099 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4101 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
4104 case TREQ_SIM_GET_CALLFORWARDING:
4105 if (tcore_sim_get_cphs_status(o))
4106 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4108 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
4111 case TREQ_SIM_GET_MESSAGEWAITING:
4112 if (tcore_sim_get_cphs_status(o))
4113 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4115 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
4118 case TREQ_SIM_GET_CPHS_INFO:
4119 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
4122 case TREQ_SIM_GET_MSISDN:
4123 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
4126 case TREQ_SIM_GET_SPN:
4127 dbg("enter case SPN");
4128 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
4131 case TREQ_SIM_GET_SPDI:
4132 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
4135 case TREQ_SIM_GET_OPL:
4136 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
4139 case TREQ_SIM_GET_PNN:
4140 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
4143 case TREQ_SIM_GET_CPHS_NETNAME:
4144 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
4147 case TREQ_SIM_GET_OPLMNWACT:
4148 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
4151 case TREQ_SIM_GET_SERVICE_TABLE:
4152 api_ret = _get_file_info(o, ur, SIM_EF_SST);
4156 dbg("error - not handled read treq command[%d]", command);
4157 api_ret = TCORE_RETURN_EINVAL;
4165 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
4167 TReturn ret_code = TCORE_RETURN_SUCCESS;
4168 enum tcore_request_command command;
4169 enum tel_sim_file_id ef = SIM_EF_INVALID;
4170 struct imc_sim_property meta_info = {0, };
4171 enum tel_sim_type sim_type;
4172 gboolean cphs_sim = FALSE;
4175 command = tcore_user_request_get_command(ur);
4176 cphs_sim = tcore_sim_get_cphs_status(co_sim);
4177 sim_type = tcore_sim_get_type(co_sim);
4179 if ((co_sim == NULL) || (ur == NULL))
4180 return TCORE_RETURN_EINVAL;
4183 case TREQ_SIM_SET_LANGUAGE:
4184 if (sim_type == SIM_TYPE_GSM)
4185 ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
4186 else if (sim_type == SIM_TYPE_USIM)
4187 ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
4189 ret_code = TCORE_RETURN_ENOSYS;
4192 case TREQ_SIM_SET_MAILBOX:
4194 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4198 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])) {
4199 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4200 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4202 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
4203 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
4207 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
4211 case TREQ_SIM_SET_CALLFORWARDING:
4213 const struct treq_sim_set_callforwarding *cf = NULL;
4214 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
4218 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4221 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])) {
4222 if (cf->b_cphs == FALSE)
4223 ef = SIM_EF_USIM_CFIS;
4225 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4227 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4228 ret_code = _get_file_info(co_sim, ur, ef);
4230 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4231 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4235 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4238 ret_code = TCORE_RETURN_EINVAL;
4243 case TREQ_SIM_SET_MESSAGEWAITING:
4245 const struct treq_sim_set_messagewaiting *mw = NULL;
4246 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4249 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4252 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])) {
4253 if (mw->b_cphs == FALSE)
4254 ef = SIM_EF_USIM_MWIS;
4256 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4258 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4259 ret_code = _get_file_info(co_sim, ur, ef);
4261 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4262 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4266 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4269 ret_code = TCORE_RETURN_EINVAL;
4275 err("Unhandled UPDATE command[%d]", command);
4276 return TCORE_RETURN_EINVAL;
4282 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4284 const struct treq_sim_transmit_apdu *req_data;
4285 TcoreHal *hal = NULL;
4286 char *cmd_str = NULL;
4289 TReturn ret = TCORE_RETURN_FAILURE;
4293 if ((o == NULL) || (ur == NULL))
4294 return TCORE_RETURN_EINVAL;
4296 hal = tcore_object_get_hal(o);
4297 if (FALSE == tcore_hal_get_power_state(hal)) {
4298 err("CP NOT READY");
4299 return TCORE_RETURN_ENOSYS;
4302 req_data = tcore_user_request_ref_data(ur, NULL);
4304 apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4306 err("Memory allocation failed!!");
4307 return TCORE_RETURN_ENOMEM;
4309 result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4310 dbg("result %d", result);
4312 cmd_str = g_strdup_printf("AT+CSIM=%d, \"%s\"", (unsigned int)strlen(apdu), apdu);
4314 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4315 TCORE_AT_SINGLELINE, ur,
4316 on_response_transmit_apdu, hal,
4317 NULL, NULL, 0, NULL, NULL);
4325 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4327 TcoreHal *hal = NULL;
4331 if ((o == NULL) || (ur == NULL)) {
4332 err("Invalid parameters");
4333 return TCORE_RETURN_EINVAL;
4336 hal = tcore_object_get_hal(o);
4337 if (FALSE == tcore_hal_get_power_state(hal)) {
4338 err("CP NOT READY");
4339 return TCORE_RETURN_ENOSYS;
4342 return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4343 TCORE_AT_SINGLELINE, ur,
4344 on_response_get_atr, hal,
4345 NULL, NULL, 0, NULL, NULL);
4348 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4350 const struct treq_sim_req_authentication *req_data;
4351 char *cmd_str = NULL;
4352 enum tel_sim_type sim_type;
4355 TReturn ret = TCORE_RETURN_FAILURE;
4356 char *convert_rand = NULL;
4357 char *convert_autn = NULL;
4361 req_data = tcore_user_request_ref_data(ur, NULL);
4362 if (req_data == NULL) {
4363 err("req_data is NULL");
4367 convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
4368 dbg("Convert RAND hex to string: [%s]", convert_rand);
4370 sim_type = tcore_sim_get_type(co);
4377 err("Not supported");
4378 ret = TCORE_RETURN_ENOSYS;
4382 switch (req_data->auth_type) {
4383 case SIM_AUTH_TYPE_GSM:
4385 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\"", session_id,
4386 context_type, convert_rand);
4388 case SIM_AUTH_TYPE_3G:
4390 convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
4391 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4393 cmd_str = g_strdup_printf("AT+XAUTH=%d, %d, \"%s\", \"%s\"",
4394 session_id, context_type,
4395 convert_rand, convert_autn);
4398 err("Not supported");
4399 ret = TCORE_RETURN_ENOSYS;
4403 ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4404 TCORE_AT_SINGLELINE, ur,
4405 on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4409 g_free(convert_rand);
4410 g_free(convert_autn);
4415 /* SIM Operations */
4416 static struct tcore_sim_operations sim_ops = {
4417 .verify_pins = imc_verify_pins,
4418 .verify_puks = imc_verify_puks,
4419 .change_pins = imc_change_pins,
4420 .get_facility_status = imc_get_facility_status,
4421 .enable_facility = imc_enable_facility,
4422 .disable_facility = imc_disable_facility,
4423 .get_lock_info = imc_get_lock_info,
4424 .read_file = imc_read_file,
4425 .update_file = imc_update_file,
4426 .transmit_apdu = imc_transmit_apdu,
4427 .get_atr = imc_get_atr,
4428 .req_authentication = imc_req_authentication,
4429 .set_powerstate = NULL,
4432 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4434 struct imc_sim_property *meta_info;
4438 /* Set operations */
4439 tcore_sim_set_ops(co_sim, &sim_ops, TCORE_OPS_TYPE_CP);
4441 meta_info = g_try_new0(struct imc_sim_property, 1);
4442 if (meta_info == NULL)
4445 tcore_sim_link_userdata(co_sim, meta_info);
4447 tcore_object_add_callback(co_sim, "+XLOCK:",
4448 on_event_facility_lock_status, NULL);
4449 tcore_object_add_callback(co_sim, "+XSIM:",
4450 on_event_pin_status, NULL);
4452 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4453 TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4460 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4462 struct imc_sim_property *meta_info;
4464 meta_info = tcore_sim_ref_userdata(co_sim);