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>
37 #include "imc_common.h"
41 #define ID_RESERVED_AT 0x0229
42 #define SIM_PIN_MAX_RETRY_COUNT 3
43 #define SMS_STATE_READY 1
45 #define SWAPBYTES16(x) \
47 unsigned short int data = *(unsigned short int *)&(x); \
48 data = ((data & 0xff00) >> 8) | \
49 ((data & 0x00ff) << 8); \
50 *(unsigned short int *)&(x) = data; \
53 enum imc_sim_file_type_e {
54 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
55 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
56 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
57 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
58 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
61 enum imc_sim_sec_op_e {
73 SEC_PIN2_DISABLE, // 10
94 SEC_SIM_UNKNOWN = 0xff
97 struct imc_sim_property {
98 gboolean b_valid; /**< Valid or not */
99 enum tel_sim_file_id file_id; /**< File identifier */
100 enum imc_sim_file_type_e file_type; /**< File type and structure */
101 int rec_length; /**< Length of one record in file */
102 int rec_count; /**< Number of records in file */
103 int data_size; /**< File size */
104 int current_index; /**< current index to read */
105 enum imc_sim_sec_op_e current_sec_op; /**< current index to read */
106 int mb_count; /**< Number of MB records in file */
107 struct tel_sim_mbi_list mbi_list;
108 // struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
109 struct tel_sim_mailbox mb_data;
110 struct tresp_sim_read files;
113 void on_response_update_file (TcorePending *p, int data_len, const void *data, void *user_data);
114 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
115 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
116 static gboolean _get_sim_type(CoreObject *o);
117 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
118 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
119 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
120 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
121 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
123 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)
125 TcoreATRequest *req = NULL;
126 TcoreHal *hal = NULL;
127 TcorePending *pending = NULL;
131 hal = tcore_object_get_hal(co);
134 pending = tcore_pending_new(co, 0);
136 dbg("Pending is NULL");
137 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
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);
452 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
455 Storage *strg = NULL;
456 char *old_imsi = NULL;
457 char new_imsi[15 + 1] = {0, };
459 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
461 dbg("there is no valid server at this point");
464 strg = (Storage *)tcore_server_find_storage(s, "vconf");
466 dbg("there is no valid storage plugin");
469 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
470 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
471 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
473 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
474 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
476 if (old_imsi != NULL) {
477 if (strncmp(old_imsi, new_imsi, 15) != 0) {
479 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
480 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
482 tcore_sim_set_identification(o, TRUE);
485 tcore_sim_set_identification(o, FALSE);
488 dbg("OLD SIM VALUE IS NULL. NEW SIM");
489 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
490 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
492 tcore_sim_set_identification(o, TRUE);
498 static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
499 char *encoded_data, unsigned int encoded_len, int rec_index)
501 TcoreHal *hal = NULL;
502 TcoreATRequest *req = NULL;
503 TcorePending *pending = NULL;
504 char *cmd_str = NULL;
505 struct imc_sim_property *meta_info = NULL;
513 hal = tcore_object_get_hal(o);
514 pending = tcore_pending_new(o, 0);
516 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
518 meta_info->file_id = ef;
519 dbg("File ID: [0x%x]", meta_info->file_id);
523 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
526 case SIM_EF_CPHS_VOICE_MSG_WAITING:
533 case SIM_EF_USIM_CFIS:
534 case SIM_EF_USIM_MWIS:
535 case SIM_EF_CPHS_MAILBOX_NUMBERS:
537 case SIM_EF_USIM_MBI:
544 err("Unhandled File ID[0x%04x]", ef);
545 return TCORE_RETURN_EINVAL;
548 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
550 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
553 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
554 req->cmd, req->prefix, strlen(req->cmd));
556 tcore_pending_set_request_data(pending, 0, req);
557 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
558 tcore_pending_link_user_request(pending, ur);
559 tcore_hal_send_request(hal, pending);
566 static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
568 struct imc_sim_property *meta_info = NULL;
569 TReturn ret_code = TCORE_RETURN_FAILURE;
571 enum tcore_request_command command;
573 char *encoded_data = NULL;
579 err("NULL data : CoreObject[%p] UR[%p]", o, ur);
580 return TCORE_RETURN_EINVAL;
582 command = tcore_user_request_get_command(ur);
583 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
587 case TREQ_SIM_SET_LANGUAGE:
589 const struct treq_sim_set_language *lang = NULL;
590 struct tel_sim_language language = {0,};
592 lang = tcore_user_request_ref_data(ur, NULL);
593 language.language_count = 1;
594 language.language[0] = lang->language;
595 if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP){
596 dbg("Encoding EF-LP, language[%d]", lang->language);
597 tmp = tcore_sim_encode_lp(&encoded_len, &language);
599 dbg("Encoding EF-ELP, language[%d]", lang->language);
600 tmp = tcore_sim_encode_li(&encoded_len, &language);
605 case TREQ_SIM_SET_CALLFORWARDING:
607 const struct treq_sim_set_callforwarding *cf = NULL;
609 cf = tcore_user_request_ref_data(ur, NULL);
610 if(ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS ) {
612 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf, meta_info->data_size);
614 /* Convert 3GPP data to CPHS data */
615 struct tel_sim_cphs_cf cphs_cf;
617 dbg("Convert 3GPP data to CPHS data");
618 memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
619 if (cf->cf.cfu_status & 0x01) {
620 cphs_cf.b_line1 = TRUE;
622 if (cf->cf.cfu_status & 0x02) {
623 cphs_cf.b_fax = TRUE;
625 if (cf->cf.cfu_status & 0x04) {
626 cphs_cf.b_data = TRUE;
628 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cphs_cf, meta_info->data_size);
631 encoded_len = strlen(tmp);
633 err("NULL Encoding Data[%p].. No Updating EF", tmp);
636 } else if (ef == SIM_EF_USIM_CFIS){
637 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
638 rec_index = cf->cf.rec_index;
640 err("Invalid File ID[0x%04x]", ef);
646 case TREQ_SIM_SET_MESSAGEWAITING:
648 const struct treq_sim_set_messagewaiting *mw = NULL;
650 mw = tcore_user_request_ref_data(ur, NULL);
651 if(ef == SIM_EF_CPHS_VOICE_MSG_WAITING ) {
653 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw*)&mw->cphs_mw, meta_info->data_size);
655 /* Convert 3GPP data to CPHS data */
656 struct tel_sim_cphs_mw cphs_mw;
658 dbg("Convert 3GPP data to CPHS data");
659 memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
661 if (mw->mw.indicator_status & 0x01) {
662 cphs_mw.b_voice1 = TRUE;
664 if (mw->mw.indicator_status & 0x02) {
665 cphs_mw.b_fax = TRUE;
667 if (mw->mw.indicator_status & 0x04) {
668 cphs_mw.b_data = TRUE;
670 tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw*)&cphs_mw, meta_info->data_size);
672 } else if (ef == SIM_EF_USIM_MWIS){
673 tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw*)&mw->mw, meta_info->rec_length);
674 rec_index = mw->mw.rec_index;
676 encoded_len = meta_info->rec_length;
678 err("Invalid File ID[0x%04x]", ef);
684 case TREQ_SIM_SET_MAILBOX:
686 const struct treq_sim_set_mailbox *mb = NULL;
688 mb = tcore_user_request_ref_data(ur, NULL);
689 if (ef == SIM_EF_USIM_MBI){
690 gboolean mbi_changed = FALSE;
691 struct tel_sim_mbi mbi;
694 meta_info->current_index++;
695 memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
697 switch(mb->mb_info.mb_type) {
698 case SIM_MAILBOX_VOICE:
699 if (mbi.voice_index != mb->mb_info.rec_index) {
701 mbi.voice_index = mb->mb_info.rec_index;
704 case SIM_MAILBOX_FAX:
705 if (mbi.fax_index != mb->mb_info.rec_index) {
707 mbi.fax_index = mb->mb_info.rec_index;
710 case SIM_MAILBOX_EMAIL:
711 if (mbi.email_index != mb->mb_info.rec_index) {
713 mbi.email_index = mb->mb_info.rec_index;
716 case SIM_MAILBOX_OTHER:
717 if (mbi.other_index != mb->mb_info.rec_index) {
719 mbi.other_index = mb->mb_info.rec_index;
722 case SIM_MAILBOX_VIDEO:
723 if (mbi.video_index != mb->mb_info.rec_index) {
725 mbi.video_index = mb->mb_info.rec_index;
728 case SIM_MAILBOX_DATA:
733 dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
734 mbi_changed, meta_info->mbi_list.profile_count,
735 mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
736 } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
738 if (mbi_changed == TRUE) {
739 rec_index = meta_info->current_index;
740 tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
742 encoded_len = meta_info->rec_length;
744 } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
745 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number*)&mb->mb_info.number_info);
746 rec_index = mb->mb_info.rec_index;
748 encoded_len = meta_info->rec_length;
749 } else if (ef == SIM_EF_MBDN){
750 tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number*)&mb->mb_info.number_info);
751 rec_index = mb->mb_info.rec_index;
753 encoded_len = meta_info->rec_length;
755 err("Invalid File ID[0x%04x]", ef);
762 err("Unhandled update REQUEST command[%d]", command);
763 ret_code = TCORE_RETURN_EINVAL;
768 encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
769 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
770 util_byte_to_hex(tmp, encoded_data, encoded_len);
773 err("Failed to Encode data");
777 dbg("Encoded Data length =[%d]", encoded_len);
778 tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
782 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
785 case SIM_EF_CPHS_VOICE_MSG_WAITING:
786 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
789 case SIM_EF_USIM_CFIS:
790 case SIM_EF_USIM_MWIS:
791 case SIM_EF_CPHS_MAILBOX_NUMBERS:
793 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
795 case SIM_EF_USIM_MBI:
797 ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
799 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
803 err("Unhandled File ID[0x%04x]", ef);
804 ret_code = TCORE_RETURN_EINVAL;
815 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
817 struct tresp_sim_read resp = {0, };
818 struct imc_sim_property *meta_info = NULL;
819 enum tcore_request_command command = TREQ_UNKNOWN;
820 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
822 dbg("EF[0x%x] access Result[%d]", ef, rt);
825 memset(&resp.data, 0x00, sizeof(resp.data));
826 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
827 command = tcore_user_request_get_command(ur);
828 sim_type = tcore_sim_get_type(o);
830 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
831 && (rt != SIM_ACCESS_SUCCESS)) {
832 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
838 if (rt == SIM_ACCESS_SUCCESS) {
839 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
840 if (command == TREQ_SIM_SET_LANGUAGE) {
841 __set_file_data(o, ur, ef);
843 _get_file_data(o, ur, ef, 0, meta_info->data_size);
846 if (sim_type == SIM_TYPE_GSM) {
847 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
848 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
849 _get_file_info(o, ur, SIM_EF_LP);
850 } else if (sim_type == SIM_TYPE_USIM) {
852 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
853 /* EFELPand EFLI not present at this point. */
854 /* po->language.lang_cnt = 0;*/
855 tcore_user_request_send_response(ur, _find_resp_command(ur),
856 sizeof(struct tresp_sim_read), &resp);
862 case SIM_EF_LP: // same with SIM_EF_USIM_LI
863 if (rt == SIM_ACCESS_SUCCESS) {
864 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
865 if (command == TREQ_SIM_SET_LANGUAGE) {
866 __set_file_data(o, ur, ef);
868 _get_file_data(o, ur, ef, 0, meta_info->data_size);
871 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
873 if (sim_type == SIM_TYPE_GSM) {
874 tcore_user_request_send_response(ur, _find_resp_command(ur),
875 sizeof(struct tresp_sim_read), &resp);
878 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
879 else if (sim_type == SIM_TYPE_USIM) {
880 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
881 _get_file_info(o, ur, SIM_EF_ELP);
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, SIM_EF_ELP, 0, meta_info->data_size);
895 /* EFELIand EFPL not present, so set language count as zero and select ECC */
896 dbg(" [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
897 tcore_user_request_send_response(ur, _find_resp_command(ur),
898 sizeof(struct tresp_sim_read), &resp);
904 if (sim_type == SIM_TYPE_GSM) {
905 _get_file_data(o, ur, ef, 0, meta_info->data_size);
906 } else if (sim_type == SIM_TYPE_USIM) {
907 if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX) {
908 meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
911 meta_info->current_index++;
912 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
921 case SIM_EF_CPHS_VOICE_MSG_WAITING:
922 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
923 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
924 case SIM_EF_CPHS_DYNAMICFLAGS:
925 case SIM_EF_CPHS_DYNAMIC2FLAG:
926 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
927 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
928 case SIM_EF_OPLMN_ACT:
929 _get_file_data(o, ur, ef, 0, meta_info->data_size);
932 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
933 if (command == TREQ_SIM_SET_CALLFORWARDING) {
934 __set_file_data(o, ur, ef);
936 _get_file_data(o, ur, ef, 0, meta_info->data_size);
939 case SIM_EF_CPHS_CPHS_INFO:
940 if (rt == SIM_ACCESS_SUCCESS) {
941 tcore_sim_set_cphs_status(o, TRUE);
942 if (!tcore_user_request_ref_communicator(ur)) {
943 dbg("internal CPHS INFO request before sim status update");
944 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
946 dbg("external CPHS INFO request");
947 _get_file_data(o, ur, ef, 0, meta_info->data_size);
950 tcore_sim_set_cphs_status(o, FALSE);
951 if (!tcore_user_request_ref_communicator(ur)) {
952 dbg("internal CPHS INFO request before sim status update");
953 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
955 dbg("external CPHS INFO request");
956 tcore_user_request_send_response(ur, _find_resp_command(ur),
957 sizeof(struct tresp_sim_read), &resp);
962 case SIM_EF_USIM_CFIS:
963 if (command == TREQ_SIM_SET_CALLFORWARDING) {
964 __set_file_data(o, ur, ef);
966 if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX) {
967 meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
969 meta_info->current_index++;
970 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
974 case SIM_EF_USIM_MWIS:
975 if (command == TREQ_SIM_SET_MESSAGEWAITING) {
976 __set_file_data(o, ur, ef);
978 meta_info->current_index++;
979 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
983 case SIM_EF_USIM_MBI:
984 if (command == TREQ_SIM_SET_MAILBOX) {
985 __set_file_data(o, ur, ef);
987 meta_info->current_index++;
988 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
994 case SIM_EF_CPHS_INFORMATION_NUMBERS:
996 meta_info->current_index++;
997 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1001 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1002 if (command == TREQ_SIM_SET_MAILBOX) {
1003 /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
1004 if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
1005 err("Cyclic File ID. No update & return error.");
1006 meta_info->files.result = SIM_ACCESS_FAILED;
1007 tcore_user_request_send_response(ur, _find_resp_command(ur),
1008 sizeof(struct tresp_sim_read), &meta_info->files);
1011 __set_file_data(o, ur, ef);
1015 meta_info->mb_count = 0;
1016 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1017 if (meta_info->current_index == 0) {
1018 err("Invalid MBDN index");
1019 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1020 tcore_user_request_send_response(ur, _find_resp_command(ur),
1021 sizeof(struct tresp_sim_read), &meta_info->files);
1023 ur = tcore_user_request_ref(ur);
1024 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1026 _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
1031 dbg("error - File id for get file info [0x%x]", ef);
1037 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
1039 struct imc_sim_property *meta_info = NULL;
1043 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1044 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
1045 switch (meta_info->file_id) {
1047 case SIM_EF_USIM_PL:
1049 case SIM_EF_USIM_LI:
1050 if (decode_ret == TRUE) {
1051 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI) {
1052 /* po->language_file = SIM_EF_LP;*/
1053 } else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL) {
1054 /* po->language_file = SIM_EF_ELP;*/
1056 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1059 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
1060 - EFELP is not available;
1061 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
1062 - the ME does not support any of the languages in EFELP.
1065 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
1066 - if the EFLI has the value 'FFFF' in its highest priority position
1067 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
1069 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1070 if (meta_info->file_id == SIM_EF_LP) {
1071 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1073 _get_file_info(o, ur, SIM_EF_LP);
1075 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1076 if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI) {
1077 _get_file_info(o, ur, SIM_EF_ELP);
1079 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1086 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1087 if (meta_info->current_index == meta_info->rec_count) {
1088 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1090 meta_info->current_index++;
1091 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1093 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1094 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1096 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
1101 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
1102 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
1106 if (meta_info->current_index == meta_info->rec_count) {
1107 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1109 meta_info->current_index++;
1110 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1115 if (meta_info->current_index == meta_info->rec_count) {
1116 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1118 meta_info->current_index++;
1119 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1124 if (meta_info->current_index == meta_info->rec_count) {
1125 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1127 meta_info->current_index++;
1128 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1132 case SIM_EF_USIM_MBI:
1133 if (meta_info->current_index == meta_info->rec_count) {
1134 _get_file_info(0, ur, SIM_EF_MBDN);
1136 meta_info->current_index++;
1137 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1142 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1143 if (meta_info->mb_count == meta_info->mb_data.count) {
1144 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1145 tcore_user_request_send_response(ur, _find_resp_command(ur),
1146 sizeof(struct tresp_sim_read), &meta_info->files);
1148 meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
1149 if (meta_info->current_index == 0) {
1150 err("Invalid MBDN index");
1151 memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
1152 tcore_user_request_send_response(ur, _find_resp_command(ur),
1153 sizeof(struct tresp_sim_read), &meta_info->files);
1155 ur = tcore_user_request_ref(ur);
1156 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1161 case SIM_EF_USIM_CFIS:
1162 case SIM_EF_USIM_MWIS:
1163 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1164 if (meta_info->current_index == meta_info->rec_count) {
1165 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1167 meta_info->current_index++;
1168 _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
1172 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1173 meta_info->files.result = rt;
1174 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
1177 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1178 if (rt == SIM_ACCESS_SUCCESS) {
1179 meta_info->files.result = SIM_ACCESS_SUCCESS;
1181 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1188 case SIM_EF_OPLMN_ACT:
1189 case SIM_EF_CPHS_CPHS_INFO:
1190 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1191 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1192 case SIM_EF_CPHS_DYNAMICFLAGS:
1193 case SIM_EF_CPHS_DYNAMIC2FLAG:
1194 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1195 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1196 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
1200 dbg("File id not handled [0x%x]", meta_info->file_id);
1205 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
1207 struct tnoti_sim_status noti_data = {0, };
1209 if (sim_status != tcore_sim_get_status(o)) {
1210 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
1211 tcore_sim_get_status(o), sim_status);
1213 /* Update SIM Status */
1214 tcore_sim_set_status(o, sim_status);
1215 noti_data.sim_status = sim_status;
1217 /* Send notification */
1218 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1219 o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
1223 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
1225 const TcoreATResponse *resp = data;
1226 UserRequest *ur = NULL;
1227 CoreObject *o = NULL;
1228 GSList *tokens = NULL;
1229 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
1235 o = tcore_pending_ref_core_object(p);
1236 ur = tcore_pending_ref_user_request(p);
1238 if (resp->success > 0) {
1241 line = (const char *)resp->lines->data;
1242 tokens = tcore_at_tok_new(line);
1243 if (g_slist_length(tokens) != 1) {
1244 msg("Invalid message");
1245 tcore_at_tok_free(tokens);
1249 state = atoi(g_slist_nth_data(tokens, 0));
1250 dbg("SIM Type is %d", state);
1253 sim_type = SIM_TYPE_GSM;
1254 } else if (state == 1) {
1255 sim_type = SIM_TYPE_USIM;
1257 sim_type = SIM_TYPE_UNKNOWN;
1260 dbg("RESPONSE NOK");
1261 sim_type = SIM_TYPE_UNKNOWN;
1264 tcore_sim_set_type(o, sim_type);
1266 if (sim_type != SIM_TYPE_UNKNOWN) {
1267 /* set user request for using ur metainfo set/ref functionality */
1268 ur = tcore_user_request_new(NULL, NULL);
1269 _get_file_info(o, ur, SIM_EF_IMSI);
1272 tcore_at_tok_free(tokens);
1276 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
1278 const TcoreATResponse *resp = data;
1279 UserRequest *ur = NULL;
1280 CoreObject *o = NULL;
1281 struct imc_sim_property *meta_info = NULL;
1282 GSList *tokens = NULL;
1283 enum tel_sim_access_result rt;
1284 const char *line = NULL;
1290 o = tcore_pending_ref_core_object(p);
1291 ur = tcore_pending_ref_user_request(p);
1292 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1294 if (resp->success > 0) {
1297 line = (const char *)resp->lines->data;
1298 tokens = tcore_at_tok_new(line);
1299 if (g_slist_length(tokens) < 2) {
1300 err("Invalid message");
1301 tcore_at_tok_free(tokens);
1305 sw1 = atoi(g_slist_nth_data(tokens, 0));
1306 sw2 = atoi(g_slist_nth_data(tokens, 1));
1308 /*1. SIM access success case*/
1309 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1310 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
1311 unsigned short record_len = 0;
1312 char num_of_records = 0;
1313 unsigned char file_id_len = 0;
1314 unsigned short file_id = 0;
1315 unsigned short file_size = 0;
1316 unsigned short file_type = 0;
1317 unsigned short arr_file_id = 0;
1319 /* handling only last 3 bits */
1320 unsigned char file_type_tag = 0x07;
1321 unsigned char *ptr_data;
1325 char *recordData = NULL;
1326 hexData = g_slist_nth_data(tokens, 2);
1327 dbg("hexData: %s", hexData);
1328 dbg("hexData: %s", hexData + 1);
1330 tmp = util_removeQuotes(hexData);
1331 recordData = util_hexStringToBytes(tmp);
1332 util_hex_dump(" ", strlen(hexData) / 2, recordData);
1335 ptr_data = (unsigned char *)recordData;
1336 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1338 ETSI TS 102 221 v7.9.0
1340 '62' FCP template tag
1341 - Response for an EF
1342 '82' M File Descriptor
1343 '83' M File Identifier
1344 'A5' O Proprietary information
1345 '8A' M Life Cycle Status Integer
1346 '8B', '8C' or 'AB' C1 Security attributes
1348 '81' O Total file size
1349 '88' O Short File Identifier (SFI)
1352 /* rsim.res_len has complete data length received */
1354 /* FCP template tag - File Control Parameters tag*/
1355 if (*ptr_data == 0x62) {
1356 /* parse complete FCP tag*/
1357 /* increment to next byte */
1359 tag_len = *ptr_data++;
1360 dbg("tag_len: %02x", tag_len);
1361 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1362 if (*ptr_data == 0x82) {
1363 /* increment to next byte */
1367 /* unsigned char file_desc_len = *ptr_data++;*/
1368 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1369 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1370 /* consider only last 3 bits*/
1371 dbg("file_type_tag: %02x", file_type_tag);
1372 file_type_tag = file_type_tag & (*ptr_data);
1373 dbg("file_type_tag: %02x", file_type_tag);
1375 switch (file_type_tag) {
1376 /* increment to next byte */
1379 dbg("Getting FileType: [Transparent file type]");
1380 file_type = SIM_FTYPE_TRANSPARENT;
1382 /* increment to next byte */
1384 /* increment to next byte */
1389 dbg("Getting FileType: [Linear fixed file type]");
1390 /* increment to next byte */
1392 /* data coding byte - value 21 */
1395 memcpy(&record_len, ptr_data, 2);
1397 SWAPBYTES16(record_len);
1398 ptr_data = ptr_data + 2;
1399 num_of_records = *ptr_data++;
1400 /* Data lossy conversation from enum (int) to unsigned char */
1401 file_type = SIM_FTYPE_LINEAR_FIXED;
1405 dbg("Cyclic fixed file type");
1406 /* increment to next byte */
1408 /* data coding byte - value 21 */
1411 memcpy(&record_len, ptr_data, 2);
1413 SWAPBYTES16(record_len);
1414 ptr_data = ptr_data + 2;
1415 num_of_records = *ptr_data++;
1416 file_type = SIM_FTYPE_CYCLIC;
1420 dbg("not handled file type [0x%x]", *ptr_data);
1424 dbg("INVALID FCP received - DEbug!");
1425 tcore_at_tok_free(tokens);
1430 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1431 if (*ptr_data == 0x83) {
1432 /* increment to next byte */
1434 file_id_len = *ptr_data++;
1435 dbg("file_id_len: %02x", file_id_len);
1437 memcpy(&file_id, ptr_data, file_id_len);
1438 dbg("file_id: %x", file_id);
1441 SWAPBYTES16(file_id);
1442 dbg("file_id: %x", file_id);
1444 ptr_data = ptr_data + 2;
1445 dbg("Getting FileID=[0x%x]", file_id);
1447 dbg("INVALID FCP received - DEbug!");
1448 tcore_at_tok_free(tokens);
1453 /* proprietary information */
1454 if (*ptr_data == 0xA5) {
1455 unsigned short prop_len;
1456 /* increment to next byte */
1460 prop_len = *ptr_data;
1461 dbg("prop_len: %02x", prop_len);
1464 ptr_data = ptr_data + prop_len + 1;
1466 dbg("INVALID FCP received - DEbug!");
1469 /* life cycle status integer [8A][length:0x01][status]*/
1472 00000000 : No information given
1473 00000001 : creation state
1474 00000011 : initialization state
1475 000001-1 : operation state -activated
1476 000001-0 : operation state -deactivated
1477 000011-- : Termination state
1478 b8~b5 !=0, b4~b1=X : Proprietary
1479 Any other value : RFU
1481 if (*ptr_data == 0x8A) {
1482 /* increment to next byte */
1484 /* length - value 1 */
1487 switch (*ptr_data) {
1490 dbg("<RX> operation state -deactivated");
1496 dbg("<RX> operation state -activated");
1501 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1507 /* related to security attributes : currently not handled*/
1508 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1509 /* increment to next byte */
1511 /* if tag length is 3 */
1512 if (*ptr_data == 0x03) {
1513 /* increment to next byte */
1516 memcpy(&arr_file_id, ptr_data, 2);
1518 SWAPBYTES16(arr_file_id);
1519 ptr_data = ptr_data + 2;
1520 ptr_data++; /*arr_file_id_rec_num = *ptr_data++; */
1522 /* if tag length is not 3 */
1523 /* ignoring bytes */
1524 // ptr_data = ptr_data + 4;
1525 dbg("Useless security attributes, so jump to next tag");
1526 ptr_data = ptr_data + (*ptr_data + 1);
1529 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1530 tcore_at_tok_free(tokens);
1535 dbg("Current ptr_data value is [%x]", *ptr_data);
1537 /* file size excluding structural info*/
1538 if (*ptr_data == 0x80) {
1539 /* for EF file size is body of file and for Linear or cyclic it is
1540 * number of recXsizeof(one record)
1542 /* increment to next byte */
1544 /* length is 1 byte - value is 2 bytes or more */
1546 memcpy(&file_size, ptr_data, 2);
1548 SWAPBYTES16(file_size);
1549 ptr_data = ptr_data + 2;
1551 dbg("INVALID FCP received - DEbug!");
1552 tcore_at_tok_free(tokens);
1557 /* total file size including structural info*/
1558 if (*ptr_data == 0x81) {
1560 /* increment to next byte */
1563 /* len = *ptr_data; */
1565 ptr_data = ptr_data + 3;
1567 dbg("INVALID FCP received - DEbug!");
1568 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1571 /*short file identifier ignored*/
1572 if (*ptr_data == 0x88) {
1573 dbg("0x88: Do Nothing");
1577 dbg("INVALID FCP received - DEbug!");
1578 tcore_at_tok_free(tokens);
1582 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1583 unsigned char gsm_specific_file_data_len = 0;
1584 /* ignore RFU byte1 and byte2 */
1588 // file_size = p_info->response_len;
1589 memcpy(&file_size, ptr_data, 2);
1591 SWAPBYTES16(file_size);
1592 /* parsed file size */
1593 ptr_data = ptr_data + 2;
1595 memcpy(&file_id, ptr_data, 2);
1596 SWAPBYTES16(file_id);
1597 dbg("FILE id --> [%x]", file_id);
1598 ptr_data = ptr_data + 2;
1599 /* save file type - transparent, linear fixed or cyclic */
1600 file_type_tag = (*(ptr_data + 7));
1602 switch (*ptr_data) {
1605 dbg("RFU file type- not handled - Debug!");
1610 dbg("MF file type - not handled - Debug!");
1615 dbg("DF file type - not handled - Debug!");
1620 dbg("EF file type [%d] ", file_type_tag);
1621 /* increment to next byte */
1624 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1625 /* increament to next byte as this byte is RFU */
1628 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1630 /* increment to next byte */
1632 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1633 /* the INCREASE command is allowed on the selected cyclic file. */
1634 file_type = SIM_FTYPE_CYCLIC;
1636 /* bytes 9 to 11 give SIM file access conditions */
1638 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1640 /* byte 11 is invalidate and rehabilate nibbles */
1642 /* byte 12 - file status */
1644 /* byte 13 - GSM specific data */
1645 gsm_specific_file_data_len = *ptr_data;
1646 dbg("gsm_specific_file_data_len: %d", gsm_specific_file_data_len);
1648 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1650 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1651 record_len = *ptr_data;
1652 dbg("record length[%d], file size[%d]", record_len, file_size);
1654 if (record_len != 0)
1655 num_of_records = (file_size / record_len);
1657 dbg("Number of records [%d]", num_of_records);
1661 dbg("not handled file type");
1665 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
1668 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1669 meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
1671 meta_info->file_type = file_type;
1672 meta_info->data_size = file_size;
1673 meta_info->rec_length = record_len;
1674 meta_info->rec_count = num_of_records;
1675 meta_info->current_index = 0; // reset for new record type EF
1676 rt = SIM_ACCESS_SUCCESS;
1679 /*2. SIM access fail case*/
1680 dbg("error to get ef[0x%x]", meta_info->file_id);
1681 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1682 rt = _decode_status_word(sw1, sw2);
1684 ur = tcore_user_request_ref(ur);
1686 dbg("Calling _next_from_get_file_info");
1687 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1688 tcore_at_tok_free(tokens);
1690 dbg("RESPONSE NOK");
1691 dbg("error to get ef[0x%x]", meta_info->file_id);
1692 dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
1693 rt = SIM_ACCESS_FAILED;
1695 ur = tcore_user_request_ref(ur);
1696 _next_from_get_file_info(o, ur, meta_info->file_id, rt);
1701 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1703 const TcoreATResponse *resp = data;
1704 UserRequest *ur = NULL;
1705 CoreObject *o = NULL;
1706 struct imc_sim_property *meta_info = NULL;
1707 GSList *tokens = NULL;
1708 enum tel_sim_access_result rt;
1709 gboolean dr = FALSE;
1710 const char *line = NULL;
1719 o = tcore_pending_ref_core_object(p);
1720 ur = tcore_pending_ref_user_request(p);
1721 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
1723 if (resp->success > 0) {
1726 line = (const char *)resp->lines->data;
1727 tokens = tcore_at_tok_new(line);
1728 if (g_slist_length(tokens) != 3) {
1729 msg("Invalid message");
1730 tcore_at_tok_free(tokens);
1734 sw1 = atoi(g_slist_nth_data(tokens, 0));
1735 sw2 = atoi(g_slist_nth_data(tokens, 1));
1736 res = g_slist_nth_data(tokens, 2);
1738 tmp = util_removeQuotes(res);
1739 res = util_hexStringToBytes(tmp);
1740 res_len = strlen(tmp) / 2;
1741 dbg("Response: [%s] Response length: [%d]", res, res_len);
1743 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1744 rt = SIM_ACCESS_SUCCESS;
1745 meta_info->files.result = rt;
1747 dbg("File ID: [0x%x]", meta_info->file_id);
1748 switch (meta_info->file_id) {
1751 struct tel_sim_imsi *imsi = NULL;
1753 dbg("Data: [%s]", res);
1754 imsi = g_try_new0(struct tel_sim_imsi, 1);
1755 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1757 err("IMSI decoding failed");
1759 //_sim_check_identity(o, imsi);
1760 tcore_sim_set_imsi(o, imsi);
1769 dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
1772 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1773 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1774 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1775 case SIM_EF_LP: /* 1 byte encoding */
1776 if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
1777 && (meta_info->file_id == SIM_EF_LP)) {
1779 * 2G LP(0x6F05) has 1 byte for each language
1781 dr = tcore_sim_decode_lp(&meta_info->files.data.language,
1782 (unsigned char *)res, res_len);
1785 * 3G LI(0x6F05)/PL(0x2F05),
1786 * 2G ELP(0x2F05) has 2 bytes for each language
1788 dr = tcore_sim_decode_li(meta_info->file_id,
1789 &meta_info->files.data.language,
1790 (unsigned char *)res, res_len);
1795 dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
1796 (unsigned char *)res, res_len);
1800 dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
1801 (unsigned char *)res, res_len);
1804 case SIM_EF_SST: //EF UST has same address
1806 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1807 dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
1809 dbg("SST decoding failed");
1810 tcore_sim_set_service_table(o, NULL);
1812 int i = 0, size = sizeof(struct tel_sim_sst);
1814 meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
1815 if ((temp=g_try_malloc0(size + 1)) != NULL ) {
1816 memcpy(temp, &meta_info->files.data.svct.table.sst, size);
1817 for(i=0; i<size; i++) {
1823 dbg("svct.table.sst=[%s]", temp);
1826 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1828 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1829 dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
1831 dbg("SST decoding failed");
1832 tcore_sim_set_service_table(o, NULL);
1834 int i = 0, size = sizeof(struct tel_sim_ust);
1836 meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
1837 if ((temp=g_try_malloc0(size + 1)) != NULL ) {
1838 memcpy(temp, &meta_info->files.data.svct.table.ust, size);
1839 for(i=0; i<size; i++) {
1845 dbg("svct.table.ust=[%s]", temp);
1848 tcore_sim_set_service_table(o, &meta_info->files.data.svct);
1851 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(o));
1858 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
1859 dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
1860 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
1861 struct tel_sim_ecc *ecc = NULL;
1863 ecc = g_try_new0(struct tel_sim_ecc, 1);
1864 dbg("Index [%d]", meta_info->current_index);
1866 dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1868 memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1869 meta_info->files.data.ecc.ecc_count++;
1875 dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
1882 struct tel_sim_msisdn *msisdn = NULL;
1884 dbg("Index [%d]", meta_info->current_index);
1885 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1886 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1888 memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
1889 msisdn, sizeof(struct tel_sim_msisdn));
1891 meta_info->files.data.msisdn_list.count++;
1901 struct tel_sim_opl *opl = NULL;
1903 dbg("decode w/ index [%d]", meta_info->current_index);
1905 opl = g_try_new0(struct tel_sim_opl, 1);
1906 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1908 memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
1909 opl, sizeof(struct tel_sim_opl));
1910 meta_info->files.data.opl.opl_count++;
1920 struct tel_sim_pnn *pnn = NULL;
1922 dbg("decode w/ index [%d]", meta_info->current_index);
1924 pnn = g_try_new0(struct tel_sim_pnn, 1);
1925 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1927 memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
1928 pnn, sizeof(struct tel_sim_pnn));
1930 meta_info->files.data.pnn.pnn_count++;
1938 case SIM_EF_OPLMN_ACT:
1939 dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
1940 (unsigned char *)res, res_len);
1943 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1944 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1945 p_data->response, p_data->response_len);*/
1948 case SIM_EF_USIM_MBI: //linear type
1950 struct tel_sim_mbi *mbi = NULL;
1952 mbi = g_try_new0(struct tel_sim_mbi, 1);
1953 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
1955 memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
1956 mbi, sizeof(struct tel_sim_mbi));
1957 meta_info->mbi_list.profile_count++;
1959 dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
1960 dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].voice_index);
1961 dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].fax_index);
1962 dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].email_index);
1963 dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].other_index);
1964 dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].video_index);
1972 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1973 case SIM_EF_MBDN: //linear type
1974 dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
1975 (unsigned char *)res, res_len);
1976 meta_info->mb_count++;
1979 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1980 dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
1981 (unsigned char *)res, res_len);
1984 case SIM_EF_USIM_MWIS: //linear type
1986 struct tel_sim_mw *mw = NULL;
1988 mw = g_try_new0(struct tel_sim_mw, 1);
1990 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
1992 memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
1993 meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
1994 meta_info->files.data.mw.mw_list.profile_count++;
2002 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
2003 dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
2004 (unsigned char *)res, res_len);
2007 case SIM_EF_USIM_CFIS: //linear type
2009 struct tel_sim_cfis *cf = NULL;
2011 cf = g_try_new0(struct tel_sim_cfis, 1);
2012 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
2014 memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
2015 cf, sizeof(struct tel_sim_cfis));
2017 meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
2018 meta_info->files.data.cf.cf_list.profile_count++;
2026 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
2027 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
2030 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
2031 dr = tcore_sim_decode_ons((unsigned char*)&meta_info->files.data.cphs_net.full_name,
2032 (unsigned char *)res, res_len);
2033 dbg("meta_info->files.result[%d],meta_info->files.data.cphs_net.full_name[%s]",
2034 meta_info->files.result, meta_info->files.data.cphs_net.full_name);
2037 case SIM_EF_CPHS_DYNAMICFLAGS:
2038 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
2039 p_data->response, p_data->response_len);*/
2042 case SIM_EF_CPHS_DYNAMIC2FLAG:
2043 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
2044 p_data->response_len);*/
2047 case SIM_EF_CPHS_CPHS_INFO:
2048 dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
2049 (unsigned char *)res, res_len);
2052 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
2053 dr = tcore_sim_decode_short_ons((unsigned char*)&meta_info->files.data.cphs_net.short_name,
2054 (unsigned char *)res, res_len);
2057 case SIM_EF_CPHS_INFORMATION_NUMBERS:
2058 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
2062 dbg("File Decoding Failed - not handled File[0x%x]", meta_info->file_id);
2067 rt = _decode_status_word(sw1, sw2);
2068 meta_info->files.result = rt;
2076 tcore_at_tok_free(tokens);
2078 dbg("RESPONSE NOK");
2079 dbg("Error - File ID: [0x%x]", meta_info->file_id);
2080 rt = SIM_ACCESS_FAILED;
2083 /* Reference User Request */
2084 ur = tcore_user_request_ref(ur);
2087 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
2092 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
2094 const TcoreATResponse *resp = data;
2095 UserRequest *ur = NULL;
2096 CoreObject *o = NULL;
2097 struct imc_sim_property *sp = NULL;
2098 GSList *tokens = NULL;
2099 const char *line = NULL;
2101 int attempts_left = 0;
2102 int time_penalty = 0;
2106 o = tcore_pending_ref_core_object(p);
2107 sp = tcore_sim_ref_userdata(o);
2108 ur = tcore_pending_ref_user_request(p);
2110 if (resp->success > 0) {
2113 line = (const char *)resp->lines->data;
2114 tokens = tcore_at_tok_new(line);
2115 if (g_slist_length(tokens) < 3) {
2116 msg("Invalid message");
2117 tcore_at_tok_free(tokens);
2121 lock_type = atoi(g_slist_nth_data(tokens, 0));
2122 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2123 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2125 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2126 lock_type, attempts_left, time_penalty);
2128 switch (sp->current_sec_op) {
2129 case SEC_PIN1_VERIFY:
2130 case SEC_PIN2_VERIFY:
2131 case SEC_SIM_VERIFY:
2132 case SEC_ADM_VERIFY:
2134 struct tresp_sim_verify_pins v_pin = {0, };
2136 v_pin.result = SIM_INCORRECT_PASSWORD;
2137 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2138 v_pin.retry_count = attempts_left;
2139 tcore_user_request_send_response(ur, _find_resp_command(ur),
2140 sizeof(struct tresp_sim_verify_pins), &v_pin);
2144 case SEC_PUK1_VERIFY:
2145 case SEC_PUK2_VERIFY:
2147 struct tresp_sim_verify_puks v_puk = {0, };
2149 v_puk.result = SIM_INCORRECT_PASSWORD;
2150 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2151 v_puk.retry_count = attempts_left;
2152 tcore_user_request_send_response(ur, _find_resp_command(ur),
2153 sizeof(struct tresp_sim_verify_puks), &v_puk);
2157 case SEC_PIN1_CHANGE:
2158 case SEC_PIN2_CHANGE:
2160 struct tresp_sim_change_pins change_pin = {0, };
2162 change_pin.result = SIM_INCORRECT_PASSWORD;
2163 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2164 change_pin.retry_count = attempts_left;
2165 tcore_user_request_send_response(ur, _find_resp_command(ur),
2166 sizeof(struct tresp_sim_change_pins), &change_pin);
2170 case SEC_PIN1_DISABLE:
2171 case SEC_PIN2_DISABLE:
2172 case SEC_FDN_DISABLE:
2173 case SEC_SIM_DISABLE:
2174 case SEC_NET_DISABLE:
2175 case SEC_NS_DISABLE:
2176 case SEC_SP_DISABLE:
2177 case SEC_CP_DISABLE:
2179 struct tresp_sim_disable_facility dis_facility = {0, };
2181 dis_facility.result = SIM_INCORRECT_PASSWORD;
2182 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2183 dis_facility.retry_count = attempts_left;
2184 tcore_user_request_send_response(ur, _find_resp_command(ur),
2185 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2189 case SEC_PIN1_ENABLE:
2190 case SEC_PIN2_ENABLE:
2191 case SEC_FDN_ENABLE:
2192 case SEC_SIM_ENABLE:
2193 case SEC_NET_ENABLE:
2198 struct tresp_sim_enable_facility en_facility = {0, };
2200 en_facility.result = SIM_INCORRECT_PASSWORD;
2201 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2202 en_facility.retry_count = attempts_left;
2203 tcore_user_request_send_response(ur, _find_resp_command(ur),
2204 sizeof(struct tresp_sim_enable_facility), &en_facility);
2209 dbg("not handled sec op[%d]", sp->current_sec_op);
2214 tcore_at_tok_free(tokens);
2220 static gboolean _get_sim_type(CoreObject *o)
2222 TcoreHal *hal = NULL;
2223 TcoreATRequest *req = NULL;
2224 TcorePending *pending = NULL;
2225 UserRequest *ur = NULL;
2226 char *cmd_str = NULL;
2230 hal = tcore_object_get_hal(o);
2231 pending = tcore_pending_new(o, 0);
2233 cmd_str = g_strdup_printf("AT+XUICC?");
2234 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
2237 dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
2238 req->cmd, req->prefix, strlen(req->cmd));
2240 tcore_pending_set_request_data(pending, 0, req);
2241 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
2242 tcore_pending_link_user_request(pending, ur);
2243 tcore_hal_send_request(hal, pending);
2249 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
2251 TcoreHal *hal = NULL;
2252 TcorePending *pending = NULL;
2253 struct imc_sim_property meta_info = {0, };
2254 char *cmd_str = NULL;
2255 TReturn ret = TCORE_RETURN_FAILURE;
2260 meta_info.file_id = ef;
2261 dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
2262 hal = tcore_object_get_hal(o);
2263 dbg("hal: %x", hal);
2265 trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
2266 dbg("trt[%d]", trt);
2267 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
2268 dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
2270 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
2271 tcore_pending_link_user_request(pending, ur);
2272 ret = tcore_hal_send_request(hal, pending);
2273 if (TCORE_RETURN_SUCCESS != ret) {
2274 tcore_user_request_free(ur);
2279 return TCORE_RETURN_SUCCESS;
2282 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
2284 TcoreHal *hal = NULL;
2285 TcoreATRequest *req = NULL;
2286 TcorePending *pending = NULL;
2287 char *cmd_str = NULL;
2293 hal = tcore_object_get_hal(o);
2294 pending = tcore_pending_new(o, 0);
2296 dbg("file_id: %x", ef);
2298 p1 = (unsigned char) (offset & 0xFF00) >> 8;
2299 p2 = (unsigned char) offset & 0x00FF; // offset low
2300 p3 = (unsigned char) length;
2302 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
2304 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2307 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2308 req->cmd, req->prefix, strlen(req->cmd));
2310 tcore_pending_set_request_data(pending, 0, req);
2311 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2312 tcore_pending_link_user_request(pending, ur);
2313 tcore_hal_send_request(hal, pending);
2319 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
2321 TcoreHal *hal = NULL;
2322 TcoreATRequest *req = NULL;
2323 TcorePending *pending = NULL;
2324 char *cmd_str = NULL;
2331 hal = tcore_object_get_hal(o);
2332 pending = tcore_pending_new(o, 0);
2334 p1 = (unsigned char) index;
2335 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
2336 p3 = (unsigned char) length;
2338 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
2340 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
2343 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2344 req->cmd, req->prefix, strlen(req->cmd));
2346 tcore_pending_set_request_data(pending, 0, req);
2347 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
2348 tcore_pending_link_user_request(pending, ur);
2349 tcore_hal_send_request(hal, pending);
2355 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
2357 TcoreHal *hal = NULL;
2358 TcoreATRequest *req = NULL;
2359 TcorePending *pending = NULL;
2360 char *cmd_str = NULL;
2362 struct imc_sim_property *sp = NULL;
2366 hal = tcore_object_get_hal(o);
2367 pending = tcore_pending_new(o, 0);
2368 sp = tcore_sim_ref_userdata(o);
2370 switch (sp->current_sec_op) {
2371 case SEC_PIN1_VERIFY:
2372 case SEC_PIN1_CHANGE:
2373 case SEC_PIN1_ENABLE:
2374 case SEC_PIN1_DISABLE:
2378 case SEC_PIN2_VERIFY:
2379 case SEC_PIN2_CHANGE:
2380 case SEC_PIN2_ENABLE:
2381 case SEC_PIN2_DISABLE:
2382 case SEC_FDN_ENABLE:
2383 case SEC_FDN_DISABLE:
2387 case SEC_PUK1_VERIFY:
2391 case SEC_PUK2_VERIFY:
2395 case SEC_NET_ENABLE:
2396 case SEC_NET_DISABLE:
2401 case SEC_NS_DISABLE:
2406 case SEC_SP_DISABLE:
2411 case SEC_CP_DISABLE:
2415 case SEC_ADM_VERIFY:
2423 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2424 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2427 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
2428 req->cmd, req->prefix, strlen(req->cmd));
2430 tcore_pending_set_request_data(pending, 0, req);
2431 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
2432 tcore_pending_link_user_request(pending, ur);
2433 tcore_hal_send_request(hal, pending);
2436 return TCORE_RETURN_SUCCESS;
2439 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
2442 GSList *tokens = NULL;
2443 GSList *lines = NULL;
2445 dbg("Function entry");
2448 lines = (GSList *)event_info;
2449 if (1 != g_slist_length(lines)) {
2450 dbg("unsolicited msg but multiple line");
2453 line = (char *)(lines->data);
2454 tokens = tcore_at_tok_new(line);
2455 if (g_slist_length(tokens) != 1) {
2456 msg("Invalid message");
2457 tcore_at_tok_free(tokens);
2464 tcore_at_tok_free(tokens);
2468 static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
2469 unsigned int sms_ready)
2471 Server *server = tcore_plugin_ref_server(plugin);
2472 struct tnoti_sms_ready_status sms_ready_noti;
2477 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2478 if (co_sms == NULL) {
2479 err("Can't find SMS core object");
2483 if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2486 tcore_sms_set_ready_status(co_sms, sms_ready);
2488 if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
2489 sms_ready_noti.status = sms_ready;
2490 tcore_server_send_notification(server, co_sms,
2491 TNOTI_SMS_DEVICE_READY,
2492 sizeof(sms_ready_noti),
2499 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2501 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2502 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2503 GSList *tokens = NULL;
2507 enum telephony_sms_ready_status sms_state = 0;
2511 lines = (GSList *)event_info;
2512 if (g_slist_length(lines) != 1) {
2513 err("Unsolicited message BUT multiple lines");
2519 /* Create 'tokens' */
2520 tokens = tcore_at_tok_new(line);
2523 if (g_slist_length(tokens) == 4) {
2524 sim_state = atoi(g_slist_nth_data(tokens, 1));
2525 sms_state = atoi(g_slist_nth_data(tokens, 3));
2527 notify_sms_state(plugin, o, sms_state);
2528 } else if (g_slist_length(tokens) == 1) {
2529 sim_state = atoi(g_slist_nth_data(tokens, 0));
2531 err("Invalid message");
2535 switch (sim_state) {
2537 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2542 sim_status = SIM_STATUS_PIN_REQUIRED;
2543 dbg("PIN REQUIRED");
2547 sim_status = SIM_STATUS_INITIALIZING;
2548 dbg("PIN DISABLED AT BOOT UP");
2552 sim_status = SIM_STATUS_INITIALIZING;
2553 dbg("PIN VERIFIED");
2557 sim_status = SIM_STATUS_PUK_REQUIRED;
2558 dbg("PUK REQUIRED");
2562 sim_status = SIM_STATUS_CARD_BLOCKED;
2563 dbg("CARD PERMANENTLY BLOCKED");
2567 sim_status = SIM_STATUS_CARD_ERROR;
2568 dbg("SIM CARD ERROR");
2572 sim_status = SIM_STATUS_INIT_COMPLETED;
2573 dbg("SIM INIT COMPLETED");
2577 sim_status = SIM_STATUS_CARD_ERROR;
2578 dbg("SIM CARD ERROR");
2582 sim_status = SIM_STATUS_CARD_REMOVED;
2587 dbg("SIM SMS Ready");
2588 notify_sms_state(plugin, o, SMS_STATE_READY);
2592 sim_status = SIM_STATUS_UNKNOWN;
2593 dbg("SIM STATE UNKNOWN");
2597 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2601 switch (sim_status) {
2602 case SIM_STATUS_INIT_COMPLETED:
2603 dbg("[SIM] SIM INIT COMPLETED");
2604 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2611 case SIM_STATUS_CARD_REMOVED:
2612 dbg("[SIM] SIM CARD REMOVED");
2613 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2616 case SIM_STATUS_CARD_NOT_PRESENT:
2617 dbg("[SIM] SIM CARD NOT PRESENT");
2618 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2621 case SIM_STATUS_CARD_ERROR:
2622 dbg("[SIM] SIM CARD ERROR");
2623 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2627 dbg("SIM Status: [0x%02x]", sim_status);
2631 _sim_status_update(o, sim_status);
2634 tcore_at_tok_free(tokens);
2640 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2642 const TcoreATResponse *resp = data;
2643 CoreObject *o = NULL;
2647 o = tcore_pending_ref_core_object(p);
2649 if (resp->success > 0) {
2652 on_event_pin_status(o, resp->lines, NULL);
2654 dbg("RESPONSE NOK");
2660 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2661 unsigned int data_len, void *data, void *user_data)
2663 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2664 CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2667 return TCORE_HOOK_RETURN_CONTINUE;
2669 dbg("Get SIM status");
2671 sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2673 return TCORE_HOOK_RETURN_CONTINUE;
2676 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2678 const TcoreATResponse *resp = data;
2679 UserRequest *ur = NULL;
2680 CoreObject *co_sim = NULL;
2681 struct imc_sim_property *sp = NULL;
2682 GSList *tokens = NULL;
2683 struct tresp_sim_verify_pins res;
2689 co_sim = tcore_pending_ref_core_object(p);
2690 sp = tcore_sim_ref_userdata(co_sim);
2691 ur = tcore_pending_ref_user_request(p);
2693 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2695 if (resp->success > 0) {
2697 res.result = SIM_PIN_OPERATION_SUCCESS;
2699 /* Get PIN facility */
2700 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2701 if ((res.pin_type == SIM_PTYPE_PIN1)
2702 || (res.pin_type == SIM_PTYPE_SIM)) {
2703 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2704 /* Update SIM Status */
2705 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2710 tcore_user_request_send_response(ur, _find_resp_command(ur),
2711 sizeof(struct tresp_sim_verify_pins), &res);
2713 dbg("RESPONSE NOK");
2714 line = (const char *)resp->final_response;
2715 tokens = tcore_at_tok_new(line);
2716 if (g_slist_length(tokens) < 1) {
2717 dbg("Unkown Error OR String corrupted");
2718 res.result = TCORE_RETURN_3GPP_ERROR;
2721 tcore_user_request_send_response(ur, _find_resp_command(ur),
2722 sizeof(struct tresp_sim_verify_pins), &res);
2724 err = atoi(g_slist_nth_data(tokens, 0));
2725 dbg("Error: [%d]", err);
2727 ur = tcore_user_request_ref(ur);
2729 /* Get retry count */
2730 _get_retry_count(co_sim, ur);
2734 tcore_at_tok_free(tokens);
2740 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2742 const TcoreATResponse *resp = data;
2743 UserRequest *ur = NULL;
2744 CoreObject *co_sim = NULL;
2745 struct imc_sim_property *sp = NULL;
2746 GSList *tokens = NULL;
2747 struct tresp_sim_verify_puks res;
2753 co_sim = tcore_pending_ref_core_object(p);
2754 sp = tcore_sim_ref_userdata(co_sim);
2755 ur = tcore_pending_ref_user_request(p);
2757 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2759 if (resp->success > 0) {
2761 res.result = SIM_PIN_OPERATION_SUCCESS;
2762 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2765 tcore_user_request_send_response(ur, _find_resp_command(ur),
2766 sizeof(struct tresp_sim_verify_pins), &res);
2768 dbg("RESPONSE NOK");
2769 line = (const char *)resp->final_response;
2770 tokens = tcore_at_tok_new(line);
2772 if (g_slist_length(tokens) < 1) {
2773 dbg("Unkown Error OR String corrupted");
2774 res.result = TCORE_RETURN_3GPP_ERROR;
2777 tcore_user_request_send_response(ur, _find_resp_command(ur),
2778 sizeof(struct tresp_sim_verify_pins), &res);
2780 err = atoi(g_slist_nth_data(tokens, 0));
2781 dbg("Error: [%d]", err);
2782 ur = tcore_user_request_ref(ur);
2783 _get_retry_count(co_sim, ur);
2785 tcore_at_tok_free(tokens);
2790 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2792 const TcoreATResponse *resp = data;
2793 UserRequest *ur = NULL;
2794 CoreObject *co_sim = NULL;
2795 struct imc_sim_property *sp = NULL;
2796 GSList *tokens = NULL;
2797 struct tresp_sim_change_pins res;
2803 co_sim = tcore_pending_ref_core_object(p);
2804 sp = tcore_sim_ref_userdata(co_sim);
2805 ur = tcore_pending_ref_user_request(p);
2807 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2809 if (resp->success > 0) {
2811 res.result = SIM_PIN_OPERATION_SUCCESS;
2812 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2815 tcore_user_request_send_response(ur, _find_resp_command(ur),
2816 sizeof(struct tresp_sim_change_pins), &res);
2818 dbg("RESPONSE NOK");
2819 line = (const char *)resp->final_response;
2820 tokens = tcore_at_tok_new(line);
2822 if (g_slist_length(tokens) < 1) {
2823 dbg("Unkown Error OR String corrupted");
2824 res.result = TCORE_RETURN_3GPP_ERROR;
2827 tcore_user_request_send_response(ur, _find_resp_command(ur),
2828 sizeof(struct tresp_sim_change_pins), &res);
2830 err = atoi(g_slist_nth_data(tokens, 0));
2831 dbg("Error: [%d]", err);
2832 ur = tcore_user_request_ref(ur);
2833 _get_retry_count(co_sim, ur);
2837 tcore_at_tok_free(tokens);
2842 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2844 const TcoreATResponse *resp = data;
2845 UserRequest *ur = NULL;
2846 GSList *tokens = NULL;
2847 struct tresp_sim_get_facility_status *res = user_data;
2852 ur = tcore_pending_ref_user_request(p);
2854 res->result = SIM_PIN_OPERATION_SUCCESS;
2856 if (resp->success > 0) {
2859 line = (const char *)resp->lines->data;
2860 tokens = tcore_at_tok_new(line);
2861 if (g_slist_length(tokens) != 1) {
2862 msg("Invalid message");
2863 tcore_at_tok_free(tokens);
2867 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2869 dbg("RESPONSE NOK");
2870 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2875 tcore_user_request_send_response(ur, _find_resp_command(ur),
2876 sizeof(struct tresp_sim_get_facility_status), res);
2878 tcore_at_tok_free(tokens);
2883 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2885 const TcoreATResponse *resp = data;
2886 UserRequest *ur = NULL;
2887 CoreObject *co_sim = NULL;
2888 struct imc_sim_property *sp = NULL;
2889 GSList *tokens = NULL;
2890 struct tresp_sim_enable_facility res;
2895 co_sim = tcore_pending_ref_core_object(p);
2896 sp = tcore_sim_ref_userdata(co_sim);
2897 ur = tcore_pending_ref_user_request(p);
2899 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2901 res.result = SIM_CARD_ERROR;
2902 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2904 if (resp->success > 0) {
2907 line = (const char *)resp->lines->data;
2908 tokens = tcore_at_tok_new(line);
2909 if (g_slist_length(tokens) != 1) {
2910 msg("Invalid message");
2913 tcore_user_request_send_response(ur, _find_resp_command(ur),
2914 sizeof(struct tresp_sim_enable_facility), &res);
2915 tcore_at_tok_free(tokens);
2920 res.result = SIM_PIN_OPERATION_SUCCESS;
2924 tcore_user_request_send_response(ur, _find_resp_command(ur),
2925 sizeof(struct tresp_sim_enable_facility), &res);
2929 tcore_at_tok_free(tokens);
2931 dbg("RESPONSE NOK");
2932 ur = tcore_user_request_ref(ur);
2933 _get_retry_count(co_sim, ur);
2938 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2940 const TcoreATResponse *resp = data;
2941 UserRequest *ur = NULL;
2942 CoreObject *co_sim = NULL;
2943 struct imc_sim_property *sp = NULL;
2944 GSList *tokens = NULL;
2945 struct tresp_sim_disable_facility res;
2950 co_sim = tcore_pending_ref_core_object(p);
2951 sp = tcore_sim_ref_userdata(co_sim);
2952 ur = tcore_pending_ref_user_request(p);
2954 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2956 res.result = SIM_CARD_ERROR;
2957 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2959 if (resp->success > 0) {
2962 line = (const char *)resp->lines->data;
2963 tokens = tcore_at_tok_new(line);
2964 if (g_slist_length(tokens) != 1) {
2965 msg("Invalid message");
2968 tcore_user_request_send_response(ur, _find_resp_command(ur),
2969 sizeof(struct tresp_sim_disable_facility), &res);
2970 tcore_at_tok_free(tokens);
2975 res.result = SIM_PIN_OPERATION_SUCCESS;
2978 tcore_user_request_send_response(ur, _find_resp_command(ur),
2979 sizeof(struct tresp_sim_disable_facility), &res);
2983 tcore_at_tok_free(tokens);
2985 dbg("RESPONSE NOK");
2986 ur = tcore_user_request_ref(ur);
2987 _get_retry_count(co_sim, ur);
2992 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2994 const TcoreATResponse *response = (TcoreATResponse *)data;
2995 UserRequest *ur = NULL;
2996 GSList *tokens = NULL;
2997 struct treq_sim_get_lock_info *req_data = NULL;
2998 struct tresp_sim_get_lock_info resp;
3000 int pin1_attempts_left = 0;
3001 int puk1_attempts_left = 0;
3002 int pin2_attempts_left = 0;
3003 int puk2_attempts_left = 0;
3004 int length_tokens = 0;
3008 memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
3010 ur = tcore_pending_ref_user_request(p);
3012 if (!ur || !response) {
3013 err("NULL data : ur[%p], response[%p]", ur, response);
3014 resp.result = SIM_CARD_ERROR;
3015 tcore_user_request_send_response(ur, _find_resp_command(ur),
3016 sizeof(struct tresp_sim_get_lock_info), &resp);
3020 req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
3022 resp.result = SIM_PIN_OPERATION_SUCCESS;
3023 resp.type = req_data->type;
3025 if (response->success > 0) {
3027 if (response->lines) {
3028 line = (const char *)response->lines->data;
3029 tokens = tcore_at_tok_new(line);
3030 length_tokens = g_slist_length(tokens);
3031 dbg("No of Tokens [%d]",length_tokens);
3032 switch (length_tokens) {
3034 puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
3036 puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
3038 pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
3040 pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
3043 err("Invalid response");
3044 tcore_at_tok_free(tokens);
3045 resp.result = SIM_CARD_ERROR;
3046 tcore_user_request_send_response(ur, _find_resp_command(ur),
3047 sizeof(struct tresp_sim_get_lock_info), &resp);
3052 dbg("PIN1 attempts = %d, PUK1 attempts = %d",
3053 pin1_attempts_left, puk1_attempts_left);
3054 dbg("PIN2 attempts = %d, PUK2 attempts = %d",
3055 pin2_attempts_left, puk2_attempts_left);
3057 resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
3061 case SIM_FACILITY_SC :
3062 resp.retry_count = pin1_attempts_left;
3063 if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3064 resp.lock_status = SIM_LOCK_STATUS_PIN;
3065 } else if (pin1_attempts_left == 0){
3066 if (puk1_attempts_left) {
3067 resp.lock_status = SIM_LOCK_STATUS_PUK;
3068 resp.retry_count = puk1_attempts_left;
3071 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3075 case SIM_FACILITY_FD :
3076 resp.retry_count = pin2_attempts_left;
3077 if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
3078 resp.lock_status = SIM_LOCK_STATUS_PIN2;
3079 } else if (pin2_attempts_left == 0){
3080 if (puk2_attempts_left) {
3081 resp.lock_status = SIM_LOCK_STATUS_PUK2;
3082 resp.retry_count = puk2_attempts_left;
3085 resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
3090 err("Unhandled facility type : [%d]", resp.type);
3092 dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
3093 tcore_at_tok_free(tokens);
3096 err("RESPONSE NOK");
3097 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
3101 tcore_user_request_send_response(ur, _find_resp_command(ur),
3102 sizeof(struct tresp_sim_get_lock_info), &resp);
3105 void on_response_update_file (TcorePending *p, int data_len, const void *data, void *user_data)
3107 UserRequest *ur = NULL;
3108 GSList *tokens = NULL;
3109 const char *line = NULL;
3110 const TcoreATResponse *response = (TcoreATResponse *)data;
3111 CoreObject *co_sim = NULL;
3112 struct imc_sim_property *meta_info = NULL;
3113 struct tresp_sim_set_data resp;
3116 gboolean cphs_sim = FALSE;
3117 enum tcore_request_command command;
3120 memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
3122 ur = tcore_pending_ref_user_request(p);
3123 command = tcore_user_request_get_command(ur);
3124 co_sim = tcore_pending_ref_core_object(p);
3125 cphs_sim = tcore_sim_get_cphs_status(co_sim);
3126 meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
3128 if (!ur || !co_sim || !meta_info || !response) {
3129 err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
3130 resp.result = SIM_CARD_ERROR;
3133 if (response->success > 0) {
3135 if (response->lines) {
3136 line = (const char *)response->lines->data;
3137 tokens = tcore_at_tok_new(line);
3138 if (g_slist_length(tokens) < 2) {
3139 err("Invalid response");
3140 resp.result = SIM_CARD_ERROR;
3142 sw1 = atoi(g_slist_nth_data(tokens, 0));
3143 sw2 = atoi(g_slist_nth_data(tokens, 1));
3145 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
3146 resp.result = SIM_ACCESS_SUCCESS;
3148 resp.result = _decode_status_word(sw1, sw2);
3151 tcore_at_tok_free(tokens);
3154 err("RESPONSE NOK");
3155 resp.result = SIM_ACCESS_FAILED;
3159 if (cphs_sim == FALSE){
3161 case TREQ_SIM_SET_MAILBOX:
3162 if (meta_info->file_id == SIM_EF_USIM_MBI) {
3163 if (resp.result == SIM_ACCESS_SUCCESS) {
3164 ur = tcore_user_request_ref(ur);
3165 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3167 dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
3168 memset(meta_info, 0x00, sizeof(struct imc_sim_property));
3169 ur = tcore_user_request_ref(ur);
3170 _get_file_info(co_sim, ur, SIM_EF_MBDN);
3180 case TREQ_SIM_SET_MAILBOX:
3182 if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
3183 _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3188 case TREQ_SIM_SET_CALLFORWARDING:
3190 if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
3191 _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3196 case TREQ_SIM_SET_MESSAGEWAITING:
3198 if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
3199 _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3211 tcore_user_request_send_response(ur, _find_resp_command(ur),
3212 sizeof(struct tresp_sim_set_data), &resp);
3215 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
3217 const TcoreATResponse *resp = data;
3218 UserRequest *ur = NULL;
3219 struct tresp_sim_transmit_apdu res;
3224 ur = tcore_pending_ref_user_request(p);
3226 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
3227 res.result = SIM_ACCESS_FAILED;
3229 if (resp->success > 0) {
3232 GSList *tokens = NULL;
3234 char *decoded_data = NULL;
3235 line = (const char *)resp->lines->data;
3236 tokens = tcore_at_tok_new(line);
3237 if (g_slist_length(tokens) != 2) {
3238 msg("Invalid message");
3239 tcore_at_tok_free(tokens);
3240 res.result = SIM_CARD_ERROR;
3244 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3245 decoded_data = util_hexStringToBytes(tmp);
3246 res.apdu_resp_length = strlen(tmp) / 2;
3247 res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
3249 memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
3251 g_free(decoded_data);
3252 res.result = SIM_ACCESS_SUCCESS;
3253 tcore_at_tok_free(tokens);
3256 dbg("RESPONSE NOK");
3262 tcore_user_request_send_response(ur, _find_resp_command(ur),
3263 sizeof(struct tresp_sim_transmit_apdu), &res);
3268 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
3270 const TcoreATResponse *resp = data;
3271 UserRequest *ur = NULL;
3272 GSList *tokens = NULL;
3273 struct tresp_sim_get_atr res;
3278 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
3279 ur = tcore_pending_ref_user_request(p);
3281 res.result = SIM_ACCESS_FAILED;
3282 if (resp->success > 0) {
3286 char *decoded_data = NULL;
3287 line = (const char *)resp->lines->data;
3288 tokens = tcore_at_tok_new(line);
3289 if (g_slist_length(tokens) < 1) {
3290 msg("Invalid message");
3294 tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
3295 decoded_data = util_hexStringToBytes(tmp);
3297 res.atr_length = strlen(tmp) / 2;
3298 memcpy((char *)res.atr, decoded_data, res.atr_length);
3300 g_free(decoded_data);
3301 res.result = SIM_ACCESS_SUCCESS;
3304 dbg("RESPONSE NOK");
3310 tcore_user_request_send_response(ur, _find_resp_command(ur),
3311 sizeof(struct tresp_sim_get_atr), &res);
3313 tcore_at_tok_free(tokens);
3317 static void on_response_req_authentication(TcorePending *p, int data_len,
3318 const void *data, void *user_data)
3320 const TcoreATResponse *at_resp = data;
3321 GSList *tokens = NULL;
3322 struct tresp_sim_req_authentication resp_auth;
3323 const struct treq_sim_req_authentication *req_data;
3324 UserRequest *ur = tcore_pending_ref_user_request(p);
3328 memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
3330 if (at_resp == NULL) {
3331 err("at_resp is NULL");
3332 resp_auth.result = SIM_ACCESS_FAILED;
3333 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3337 req_data = tcore_user_request_ref_data(ur, NULL);
3338 if (req_data == NULL) {
3339 err("req_data is NULL");
3340 resp_auth.result = SIM_ACCESS_FAILED;
3341 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3344 resp_auth.auth_type = req_data->auth_type;
3346 if (at_resp->success == TRUE) {
3351 if (at_resp->lines != NULL) {
3352 line = at_resp->lines->data;
3353 dbg("Received data: [%s]", line);
3355 err("at_resp->lines is NULL");
3356 resp_auth.result = SIM_ACCESS_FAILED;
3357 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3361 tokens = tcore_at_tok_new(line);
3362 if (tokens == NULL) {
3363 err("tokens is NULL");
3364 resp_auth.result = SIM_ACCESS_FAILED;
3365 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3369 status = atoi(g_slist_nth_data(tokens, 0));
3372 dbg("Authentications successful");
3373 resp_auth.auth_result = SIM_AUTH_NO_ERROR;
3376 err("Synchronize fail");
3377 resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
3381 resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
3384 err("Does not support security context");
3385 resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
3388 err("Other failure");
3389 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3393 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
3395 char *convert_kc, *convert_sres;
3397 kc = g_slist_nth_data(tokens, 1);
3399 kc = tcore_at_tok_extract(kc);
3400 dbg("Kc: [%s]", kc);
3401 convert_kc = util_hexStringToBytes(kc);
3402 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3403 resp_auth.authentication_key_length = strlen(convert_kc);
3404 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3407 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3413 sres = g_slist_nth_data(tokens, 2);
3415 sres = tcore_at_tok_extract(sres);
3416 dbg("SRES: [%s]", sres);
3417 convert_sres = util_hexStringToBytes(sres);
3418 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3419 resp_auth.resp_length = strlen(convert_sres);
3420 memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
3422 err("Invalid SRES");
3423 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3426 g_free(convert_sres);
3428 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
3429 || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3433 err("RESPONSE NOK");
3434 resp_auth.result = SIM_ACCESS_FAILED;
3435 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3439 tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3440 sizeof(struct tresp_sim_req_authentication), &resp_auth);
3442 tcore_at_tok_free(tokens);
3445 static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
3447 TcoreHal *hal = NULL;
3448 TcoreATRequest *req = NULL;
3449 TcorePending *pending = NULL;
3450 char *cmd_str = NULL;
3451 const struct treq_sim_verify_pins *req_data = NULL;
3452 struct imc_sim_property *sp = NULL;
3453 TReturn ret = TCORE_RETURN_FAILURE;
3457 if ((o == NULL )|| (ur == NULL))
3458 return TCORE_RETURN_EINVAL;
3460 hal = tcore_object_get_hal(o);
3461 if (FALSE == tcore_hal_get_power_state(hal)) {
3462 err("CP NOT READY");
3463 return TCORE_RETURN_ENOSYS;
3466 sp = tcore_sim_ref_userdata(o);
3467 pending = tcore_pending_new(o, 0);
3468 req_data = tcore_user_request_ref_data(ur, NULL);
3470 if (req_data->pin_type == SIM_PTYPE_PIN1) {
3471 sp->current_sec_op = SEC_PIN1_VERIFY;
3472 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3473 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3474 sp->current_sec_op = SEC_PIN2_VERIFY;
3475 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3476 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3477 sp->current_sec_op = SEC_SIM_VERIFY;
3478 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3479 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3480 sp->current_sec_op = SEC_ADM_VERIFY;
3481 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3483 tcore_pending_free(pending);
3484 return TCORE_RETURN_EINVAL;
3487 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3490 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3491 req->cmd, req->prefix, strlen(req->cmd));
3493 tcore_pending_set_request_data(pending, 0, req);
3494 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3495 tcore_pending_link_user_request(pending, ur);
3496 ret = tcore_hal_send_request(hal, pending);
3502 static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
3504 TcoreHal *hal = NULL;
3505 TcoreATRequest *req = NULL;
3506 TcorePending *pending = NULL;
3507 char *cmd_str = NULL;
3508 const struct treq_sim_verify_puks *req_data;
3509 struct imc_sim_property *sp = NULL;
3510 TReturn ret = TCORE_RETURN_FAILURE;
3514 if ((o == NULL )|| (ur == NULL))
3515 return TCORE_RETURN_EINVAL;
3517 hal = tcore_object_get_hal(o);
3518 if (FALSE == tcore_hal_get_power_state(hal)) {
3519 err("CP NOT READY");
3520 return TCORE_RETURN_ENOSYS;
3523 sp = tcore_sim_ref_userdata(o);
3524 pending = tcore_pending_new(o, 0);
3525 req_data = tcore_user_request_ref_data(ur, NULL);
3527 if (req_data->puk_type == SIM_PTYPE_PUK1) {
3528 sp->current_sec_op = SEC_PUK1_VERIFY;
3529 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3530 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3531 sp->current_sec_op = SEC_PUK2_VERIFY;
3532 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3534 tcore_pending_free(pending);
3535 return TCORE_RETURN_EINVAL;
3538 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3541 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3542 req->cmd, req->prefix, strlen(req->cmd));
3544 tcore_pending_set_request_data(pending, 0, req);
3545 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3546 tcore_pending_link_user_request(pending, ur);
3547 ret = tcore_hal_send_request(hal, pending);
3553 static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
3555 TcoreHal *hal = NULL;
3556 TcoreATRequest *req = NULL;
3557 TcorePending *pending = NULL;
3558 char *cmd_str = NULL;
3559 const struct treq_sim_change_pins *req_data;
3560 struct imc_sim_property *sp = NULL;
3563 TReturn ret = TCORE_RETURN_FAILURE;
3567 if ((o == NULL )|| (ur == NULL))
3568 return TCORE_RETURN_EINVAL;
3570 hal = tcore_object_get_hal(o);
3571 if (FALSE == tcore_hal_get_power_state(hal)) {
3572 err("CP NOT READY");
3573 return TCORE_RETURN_ENOSYS;
3576 sp = tcore_sim_ref_userdata(o);
3577 pending = tcore_pending_new(o, 0);
3578 req_data = tcore_user_request_ref_data(ur, NULL);
3580 if (req_data->type == SIM_PTYPE_PIN1) {
3581 sp->current_sec_op = SEC_PIN1_CHANGE;
3582 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3583 } else if (req_data->type == SIM_PTYPE_PIN2) {
3584 sp->current_sec_op = SEC_PIN2_CHANGE;
3585 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3587 tcore_pending_free(pending);
3588 return TCORE_RETURN_EINVAL;
3590 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3593 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3594 req->cmd, req->prefix, strlen(req->cmd));
3596 tcore_pending_set_request_data(pending, 0, req);
3597 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3598 tcore_pending_link_user_request(pending, ur);
3599 ret = tcore_hal_send_request(hal, pending);
3605 static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
3607 TcoreHal *hal = NULL;
3608 TcoreATRequest *req = NULL;
3609 TcorePending *pending = NULL;
3610 char *cmd_str = NULL;
3611 const struct treq_sim_get_facility_status *req_data;
3612 struct tresp_sim_get_facility_status *res;
3614 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
3615 TReturn ret = TCORE_RETURN_FAILURE;
3619 if ((o == NULL )|| (ur == NULL))
3620 return TCORE_RETURN_EINVAL;
3622 hal = tcore_object_get_hal(o);
3623 if (FALSE == tcore_hal_get_power_state(hal)) {
3624 err("CP NOT READY");
3625 return TCORE_RETURN_ENOSYS;
3628 pending = tcore_pending_new(o, 0);
3629 req_data = tcore_user_request_ref_data(ur, NULL);
3631 res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3633 tcore_pending_free(pending);
3634 return TCORE_RETURN_ENOMEM;
3637 res->type = req_data->type;
3639 if (req_data->type == SIM_FACILITY_PS) {
3640 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3641 } else if (req_data->type == SIM_FACILITY_SC) {
3642 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3643 } else if (req_data->type == SIM_FACILITY_FD) {
3644 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3645 } else if (req_data->type == SIM_FACILITY_PN) {
3646 fac = "PN"; /*Network Personalization*/
3647 } else if (req_data->type == SIM_FACILITY_PU) {
3648 fac = "PU"; /*network sUbset Personalization*/
3649 } else if (req_data->type == SIM_FACILITY_PP) {
3650 fac = "PP"; /*service Provider Personalization*/
3651 } else if (req_data->type == SIM_FACILITY_PC) {
3652 fac = "PC"; /*Corporate Personalization*/
3654 return TCORE_RETURN_EINVAL;
3656 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3657 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3660 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3661 req->cmd, req->prefix, strlen(req->cmd));
3663 tcore_pending_set_request_data(pending, 0, req);
3664 tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3665 tcore_pending_link_user_request(pending, ur);
3666 ret = tcore_hal_send_request(hal, pending);
3672 static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
3674 TcoreHal *hal = NULL;
3675 TcoreATRequest *req = NULL;
3676 TcorePending *pending = NULL;
3677 char *cmd_str = NULL;
3678 const struct treq_sim_enable_facility *req_data;
3679 struct imc_sim_property *sp = NULL;
3681 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
3682 TReturn ret = TCORE_RETURN_FAILURE;
3686 if ((o == NULL )|| (ur == NULL))
3687 return TCORE_RETURN_EINVAL;
3689 hal = tcore_object_get_hal(o);
3690 if (FALSE == tcore_hal_get_power_state(hal)) {
3691 err("CP NOT READY");
3692 return TCORE_RETURN_ENOSYS;
3695 sp = tcore_sim_ref_userdata(o);
3696 pending = tcore_pending_new(o, 0);
3697 req_data = tcore_user_request_ref_data(ur, NULL);
3699 if (req_data->type == SIM_FACILITY_PS) {
3700 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3701 sp->current_sec_op = SEC_SIM_ENABLE;
3702 } else if (req_data->type == SIM_FACILITY_SC) {
3703 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3704 sp->current_sec_op = SEC_PIN1_ENABLE;
3705 } else if (req_data->type == SIM_FACILITY_FD) {
3706 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3707 sp->current_sec_op = SEC_FDN_ENABLE;
3708 } else if (req_data->type == SIM_FACILITY_PN) {
3709 fac = "PN"; /*Network Personalization*/
3710 sp->current_sec_op = SEC_NET_ENABLE;
3711 } else if (req_data->type == SIM_FACILITY_PU) {
3712 fac = "PU"; /*network sUbset Personalization*/
3713 sp->current_sec_op = SEC_NS_ENABLE;
3714 } else if (req_data->type == SIM_FACILITY_PP) {
3715 fac = "PP"; /*service Provider Personalization*/
3716 sp->current_sec_op = SEC_SP_ENABLE;
3717 } else if (req_data->type == SIM_FACILITY_PC) {
3718 fac = "PC"; /*Corporate Personalization*/
3719 sp->current_sec_op = SEC_CP_ENABLE;
3721 return TCORE_RETURN_EINVAL;
3723 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3724 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3727 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3728 req->cmd, req->prefix, strlen(req->cmd));
3730 tcore_pending_set_request_data(pending, 0, req);
3731 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3732 tcore_pending_link_user_request(pending, ur);
3733 ret = tcore_hal_send_request(hal, pending);
3739 static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
3742 TcoreATRequest *req;
3743 TcorePending *pending = NULL;
3744 char *cmd_str = NULL;
3745 const struct treq_sim_enable_facility *req_data;
3746 struct imc_sim_property *sp = NULL;
3748 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
3749 TReturn ret = TCORE_RETURN_FAILURE;
3753 if ((o == NULL )|| (ur == NULL))
3754 return TCORE_RETURN_EINVAL;
3756 hal = tcore_object_get_hal(o);
3757 if (FALSE == tcore_hal_get_power_state(hal)) {
3758 err("CP NOT READY");
3759 return TCORE_RETURN_ENOSYS;
3762 sp = tcore_sim_ref_userdata(o);
3763 pending = tcore_pending_new(o, 0);
3764 req_data = tcore_user_request_ref_data(ur, NULL);
3766 if (req_data->type == SIM_FACILITY_PS) {
3767 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3768 sp->current_sec_op = SEC_SIM_DISABLE;
3769 } else if (req_data->type == SIM_FACILITY_SC) {
3770 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3771 sp->current_sec_op = SEC_PIN1_DISABLE;
3772 } else if (req_data->type == SIM_FACILITY_FD) {
3773 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3774 sp->current_sec_op = SEC_FDN_DISABLE;
3775 } else if (req_data->type == SIM_FACILITY_PN) {
3776 fac = "PN"; /*Network Personalization*/
3777 sp->current_sec_op = SEC_NET_DISABLE;
3778 } else if (req_data->type == SIM_FACILITY_PU) {
3779 fac = "PU"; /*network sUbset Personalization*/
3780 sp->current_sec_op = SEC_NS_DISABLE;
3781 } else if (req_data->type == SIM_FACILITY_PP) {
3782 fac = "PP"; /*service Provider Personalization*/
3783 sp->current_sec_op = SEC_SP_DISABLE;
3784 } else if (req_data->type == SIM_FACILITY_PC) {
3785 fac = "PC"; /*Corporate Personalization*/
3786 sp->current_sec_op = SEC_CP_DISABLE;
3788 return TCORE_RETURN_EINVAL;
3790 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3791 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3794 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3795 req->cmd, req->prefix, strlen(req->cmd));
3797 tcore_pending_set_request_data(pending, 0, req);
3798 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
3799 tcore_pending_link_user_request(pending, ur);
3800 ret = tcore_hal_send_request(hal, pending);
3806 static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
3808 TcoreHal *hal = NULL;
3809 TcoreATRequest *req = NULL;
3810 TcorePending *pending = NULL;
3814 hal = tcore_object_get_hal(o);
3815 pending = tcore_pending_new(o, 0);
3817 if ((o == NULL )|| (ur == NULL)) {
3818 tcore_pending_free(pending);
3819 return TCORE_RETURN_EINVAL;
3821 req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
3823 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3824 req->cmd, req->prefix, strlen(req->cmd));
3826 tcore_pending_set_request_data(pending, 0, req);
3827 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
3828 tcore_pending_link_user_request(pending, ur);
3829 tcore_hal_send_request(hal, pending);
3832 return TCORE_RETURN_SUCCESS;
3835 static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
3837 TReturn api_ret = TCORE_RETURN_SUCCESS;
3838 enum tcore_request_command command;
3842 if ((o == NULL )|| (ur == NULL))
3843 return TCORE_RETURN_EINVAL;
3845 command = tcore_user_request_get_command(ur);
3846 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3847 err("CP NOT READY");
3848 return TCORE_RETURN_ENOSYS;
3852 case TREQ_SIM_GET_ECC:
3853 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
3856 case TREQ_SIM_GET_LANGUAGE:
3857 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
3858 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
3859 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
3860 api_ret = _get_file_info(o, ur, SIM_EF_LP);
3862 api_ret = TCORE_RETURN_ENOSYS;
3865 case TREQ_SIM_GET_ICCID:
3866 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
3869 case TREQ_SIM_GET_MAILBOX:
3870 if (tcore_sim_get_cphs_status(o))
3871 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3873 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
3876 case TREQ_SIM_GET_CALLFORWARDING:
3877 if (tcore_sim_get_cphs_status(o))
3878 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3880 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3883 case TREQ_SIM_GET_MESSAGEWAITING:
3884 if (tcore_sim_get_cphs_status(o))
3885 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3887 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3890 case TREQ_SIM_GET_CPHS_INFO:
3891 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3894 case TREQ_SIM_GET_MSISDN:
3895 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3898 case TREQ_SIM_GET_SPN:
3899 dbg("enter case SPN");
3900 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3903 case TREQ_SIM_GET_SPDI:
3904 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3907 case TREQ_SIM_GET_OPL:
3908 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3911 case TREQ_SIM_GET_PNN:
3912 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3915 case TREQ_SIM_GET_CPHS_NETNAME:
3916 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3919 case TREQ_SIM_GET_OPLMNWACT:
3920 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3923 case TREQ_SIM_GET_SERVICE_TABLE:
3924 api_ret = _get_file_info(o, ur, SIM_EF_SST);
3928 dbg("error - not handled read treq command[%d]", command);
3929 api_ret = TCORE_RETURN_EINVAL;
3937 static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
3939 TReturn ret_code = TCORE_RETURN_SUCCESS;
3940 enum tcore_request_command command;
3941 enum tel_sim_file_id ef = SIM_EF_INVALID;
3942 struct imc_sim_property meta_info = {0, };
3943 enum tel_sim_type sim_type;
3944 gboolean cphs_sim = FALSE;
3947 command = tcore_user_request_get_command(ur);
3948 cphs_sim = tcore_sim_get_cphs_status(co_sim);
3949 sim_type = tcore_sim_get_type(co_sim);
3951 if ((co_sim == NULL )|| (ur == NULL)) {
3952 return TCORE_RETURN_EINVAL;
3956 case TREQ_SIM_SET_LANGUAGE:
3957 if (sim_type == SIM_TYPE_GSM)
3958 ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
3959 else if (sim_type == SIM_TYPE_USIM)
3960 ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
3962 ret_code = TCORE_RETURN_ENOSYS;
3965 case TREQ_SIM_SET_MAILBOX:
3968 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
3972 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])) {
3973 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
3974 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
3976 dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
3977 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3981 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
3986 case TREQ_SIM_SET_CALLFORWARDING:
3988 const struct treq_sim_set_callforwarding *cf = NULL;
3989 cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
3993 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
3996 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])) {
3997 if (cf->b_cphs == FALSE) {
3998 ef = SIM_EF_USIM_CFIS;
4000 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
4002 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4003 ret_code = _get_file_info(co_sim, ur, ef);
4005 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4006 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
4010 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
4013 ret_code = TCORE_RETURN_EINVAL;
4018 case TREQ_SIM_SET_MESSAGEWAITING:
4020 const struct treq_sim_set_messagewaiting *mw = NULL;
4021 mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
4024 struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
4027 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] )) {
4028 if (mw->b_cphs == FALSE) {
4029 ef = SIM_EF_USIM_MWIS;
4031 ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
4033 tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
4034 ret_code = _get_file_info(co_sim, ur, ef);
4036 dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
4037 ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
4041 ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
4044 ret_code = TCORE_RETURN_EINVAL;
4051 err("Unhandled UPDATE command[%d]", command);
4052 return TCORE_RETURN_EINVAL;
4059 static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
4061 const struct treq_sim_transmit_apdu *req_data;
4062 TcoreHal *hal = NULL;
4063 char *cmd_str = NULL;
4066 TReturn ret = TCORE_RETURN_FAILURE;
4070 if ((o == NULL )|| (ur == NULL))
4071 return TCORE_RETURN_EINVAL;
4073 hal = tcore_object_get_hal(o);
4074 if (FALSE == tcore_hal_get_power_state(hal)) {
4075 err("CP NOT READY");
4076 return TCORE_RETURN_ENOSYS;
4079 req_data = tcore_user_request_ref_data(ur, NULL);
4081 apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
4082 result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
4083 dbg("result %d", result);
4085 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", (unsigned int)strlen(apdu), apdu);
4087 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
4088 TCORE_AT_SINGLELINE, ur,
4089 on_response_transmit_apdu, hal,
4090 NULL, NULL, 0, NULL, NULL);
4098 static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
4100 TcoreHal *hal = NULL;
4104 if ((o == NULL )|| (ur == NULL)) {
4105 err("Invalid parameters");
4106 return TCORE_RETURN_EINVAL;
4109 hal = tcore_object_get_hal(o);
4110 if (FALSE == tcore_hal_get_power_state(hal)) {
4111 err("CP NOT READY");
4112 return TCORE_RETURN_ENOSYS;
4115 return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
4116 TCORE_AT_SINGLELINE, ur,
4117 on_response_get_atr, hal,
4118 NULL, NULL, 0, NULL, NULL);
4121 static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
4123 const struct treq_sim_req_authentication *req_data;
4124 char *cmd_str = NULL;
4125 enum tel_sim_type sim_type;
4128 TReturn ret = TCORE_RETURN_FAILURE;
4129 char *convert_rand = NULL;
4130 char *convert_autn = NULL;
4134 req_data = tcore_user_request_ref_data(ur, NULL);
4135 if (req_data == NULL) {
4136 err("req_data is NULL");
4140 if (req_data->rand_data != NULL) {
4141 convert_rand = util_hex_to_string(req_data->rand_data,
4142 strlen(req_data->rand_data));
4143 dbg("Convert RAND hex to string: [%s]", convert_rand);
4145 err("rand_data is NULL");
4149 sim_type = tcore_sim_get_type(co);
4156 err("Not supported");
4157 ret = TCORE_RETURN_ENOSYS;
4161 switch (req_data->auth_type) {
4162 case SIM_AUTH_TYPE_GSM:
4164 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"", session_id,
4165 context_type, convert_rand);
4167 case SIM_AUTH_TYPE_3G:
4169 if (req_data->autn_data != NULL) {
4170 convert_autn = util_hex_to_string(req_data->autn_data,
4171 strlen(req_data->autn_data));
4172 dbg("Convert AUTN hex to string: [%s]", convert_autn);
4174 err("autn_data is NULL");
4177 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
4178 session_id, context_type,
4179 convert_rand, convert_autn);
4182 err("Not supported");
4183 ret = TCORE_RETURN_ENOSYS;
4187 ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
4188 TCORE_AT_SINGLELINE, ur,
4189 on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
4193 g_free(convert_rand);
4194 g_free(convert_autn);
4199 /* SIM Operations */
4200 static struct tcore_sim_operations sim_ops = {
4201 .verify_pins = imc_verify_pins,
4202 .verify_puks = imc_verify_puks,
4203 .change_pins = imc_change_pins,
4204 .get_facility_status = imc_get_facility_status,
4205 .enable_facility = imc_enable_facility,
4206 .disable_facility = imc_disable_facility,
4207 .get_lock_info = imc_get_lock_info,
4208 .read_file = imc_read_file,
4209 .update_file = imc_update_file,
4210 .transmit_apdu = imc_transmit_apdu,
4211 .get_atr = imc_get_atr,
4212 .req_authentication = imc_req_authentication,
4213 .set_powerstate = NULL,
4216 gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
4218 struct imc_sim_property *meta_info;
4222 /* Set operations */
4223 tcore_sim_set_ops(co_sim, &sim_ops);
4225 meta_info = g_try_new0(struct imc_sim_property, 1);
4226 if (meta_info == NULL)
4229 tcore_sim_link_userdata(co_sim, meta_info);
4231 tcore_object_add_callback(co_sim, "+XLOCK:",
4232 on_event_facility_lock_status, NULL);
4233 tcore_object_add_callback(co_sim, "+XSIM:",
4234 on_event_pin_status, NULL);
4236 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
4237 TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
4244 void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
4246 struct imc_sim_property *meta_info;
4248 meta_info = tcore_sim_ref_userdata(co_sim);