4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <core_object.h>
32 #include <user_request.h>
39 #define ID_RESERVED_AT 0x0229
41 #define SWAPBYTES16(x) \
43 unsigned short int data = *(unsigned short int *) &(x); \
44 data = ((data & 0xff00) >> 8) | \
45 ((data & 0x00ff) << 8); \
46 *(unsigned short int *) &(x) = data; \
49 enum s_sim_file_type_e {
50 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
51 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
52 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
53 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
54 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
69 SEC_PIN2_DISABLE, // 10
90 SEC_SIM_UNKNOWN = 0xff
93 struct s_sim_property {
94 gboolean b_valid; /**< Valid or not */
95 enum tel_sim_file_id file_id; /**< File identifier */
96 enum s_sim_file_type_e file_type; /**< File type and structure */
97 int rec_length; /**< Length of one record in file */
98 int rec_count; /**< Number of records in file */
99 int data_size; /**< File size */
100 int current_index; /**< current index to read */
101 enum tel_sim_status first_recv_status;
102 enum s_sim_sec_op_e current_sec_op; /**< current index to read */
103 struct tel_sim_mbi_list mbi_list;
104 struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
105 struct tresp_sim_read files;
108 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
109 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
110 static gboolean _get_sim_type(CoreObject *o);
111 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
112 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
113 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
114 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
115 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
117 static enum tcore_response_command _find_resp_command(UserRequest *ur)
119 enum tcore_request_command command;
121 command = tcore_user_request_get_command(ur);
123 case TREQ_SIM_VERIFY_PINS:
124 return TRESP_SIM_VERIFY_PINS;
127 case TREQ_SIM_VERIFY_PUKS:
128 return TRESP_SIM_VERIFY_PUKS;
131 case TREQ_SIM_CHANGE_PINS:
132 return TRESP_SIM_CHANGE_PINS;
135 case TREQ_SIM_GET_FACILITY_STATUS:
136 return TRESP_SIM_GET_FACILITY_STATUS;
139 case TREQ_SIM_DISABLE_FACILITY:
140 return TRESP_SIM_DISABLE_FACILITY;
143 case TREQ_SIM_ENABLE_FACILITY:
144 return TRESP_SIM_ENABLE_FACILITY;
147 case TREQ_SIM_GET_LOCK_INFO:
148 return TRESP_SIM_GET_LOCK_INFO;
151 case TREQ_SIM_TRANSMIT_APDU:
152 return TRESP_SIM_TRANSMIT_APDU;
155 case TREQ_SIM_GET_ATR:
156 return TRESP_SIM_GET_ATR;
159 case TREQ_SIM_GET_ECC:
160 return TRESP_SIM_GET_ECC;
163 case TREQ_SIM_GET_LANGUAGE:
164 return TRESP_SIM_GET_LANGUAGE;
167 case TREQ_SIM_SET_LANGUAGE:
168 return TRESP_SIM_SET_LANGUAGE;
171 case TREQ_SIM_GET_ICCID:
172 return TRESP_SIM_GET_ICCID;
175 case TREQ_SIM_GET_MAILBOX:
176 return TRESP_SIM_GET_MAILBOX;
179 case TREQ_SIM_GET_CALLFORWARDING:
180 return TRESP_SIM_GET_CALLFORWARDING;
183 case TREQ_SIM_SET_CALLFORWARDING:
184 return TRESP_SIM_SET_CALLFORWARDING;
187 case TREQ_SIM_GET_MESSAGEWAITING:
188 return TRESP_SIM_GET_MESSAGEWAITING;
191 case TREQ_SIM_GET_CPHS_INFO:
192 return TRESP_SIM_GET_CPHS_INFO;
195 case TREQ_SIM_GET_MSISDN:
196 return TRESP_SIM_GET_MSISDN;
199 case TREQ_SIM_GET_SPN:
200 return TRESP_SIM_GET_SPN;
203 case TREQ_SIM_GET_SPDI:
204 return TRESP_SIM_GET_SPDI;
207 case TREQ_SIM_GET_OPL:
208 return TRESP_SIM_GET_OPL;
211 case TREQ_SIM_GET_PNN:
212 return TRESP_SIM_GET_PNN;
215 case TREQ_SIM_GET_CPHS_NETNAME:
216 return TRESP_SIM_GET_CPHS_NETNAME;
219 case TREQ_SIM_GET_OPLMNWACT:
220 return TRESP_SIM_GET_OPLMNWACT;
223 case TREQ_SIM_REQ_AUTHENTICATION:
224 return TRESP_SIM_REQ_AUTHENTICATION;
230 return TRESP_UNKNOWN;
233 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
237 dbg("current sec_op[%d]", op);
240 case SEC_PIN1_VERIFY:
241 case SEC_PIN1_CHANGE:
242 ret_type = SIM_PTYPE_PIN1;
245 case SEC_PIN2_VERIFY:
246 case SEC_PIN2_CHANGE:
247 ret_type = SIM_PTYPE_PIN2;
250 case SEC_PUK1_VERIFY:
251 ret_type = SIM_PTYPE_PUK1;
254 case SEC_PUK2_VERIFY:
255 ret_type = SIM_PTYPE_PUK2;
259 ret_type = SIM_PTYPE_SIM;
263 ret_type = SIM_PTYPE_ADM;
266 case SEC_PIN1_ENABLE:
267 case SEC_PIN1_DISABLE:
268 case SEC_PIN1_STATUS:
269 ret_type = SIM_FACILITY_SC;
273 case SEC_SIM_DISABLE:
275 ret_type = SIM_FACILITY_PS;
279 case SEC_NET_DISABLE:
281 ret_type = SIM_FACILITY_PN;
287 ret_type = SIM_FACILITY_PU;
293 ret_type = SIM_FACILITY_PP;
299 ret_type = SIM_FACILITY_PC;
303 case SEC_FDN_DISABLE:
305 ret_type = SIM_FACILITY_FD;
309 dbg("not handled current sec op[%d]", op)
315 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
317 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
319 if (status_word1 == 0x93 && status_word2 == 0x00) {
320 rst = SIM_ACCESS_FAILED;
321 /*Failed SIM request command*/
322 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
323 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
324 rst = SIM_ACCESS_FAILED;
325 /*Failed SIM request command*/
326 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
327 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
328 rst = SIM_ACCESS_FAILED;
329 /*Failed SIM request command*/
330 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
331 status_word1, status_word2);
332 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
333 rst = SIM_ACCESS_FILE_NOT_FOUND;
334 /*Failed SIM request command*/
335 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
336 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
337 rst = SIM_ACCESS_FAILED; /* MOdem not support */
338 /*Failed SIM request command*/
339 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
340 status_word1, status_word2);
341 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
342 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
343 /*Failed SIM request command*/
344 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
345 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
346 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
347 /*Failed SIM request command*/
348 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
349 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
350 status_word1, status_word2);
351 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
352 status_word1, status_word2);
353 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
354 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
355 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
356 /*Failed SIM request command*/
357 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
358 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
359 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
360 /*Failed SIM request command*/
361 dbg(" error - Contradiction with invalidation status [%x][%x]",
362 status_word1, status_word2);
363 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
364 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
365 /*Failed SIM request command*/
366 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
367 status_word1, status_word2);
368 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
369 status_word1, status_word2);
370 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
371 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
372 rst = SIM_ACCESS_FAILED;
373 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
374 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
375 rst = SIM_ACCESS_FAILED;
376 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
377 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
378 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
379 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
380 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
381 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
382 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
383 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
384 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
385 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
386 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
387 rst = SIM_ACCESS_FAILED;
388 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
389 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
390 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
391 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
392 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
393 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
394 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
396 rst = SIM_ACCESS_CARD_ERROR;
397 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
402 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
405 Storage *strg = NULL;
406 char *old_imsi = NULL;
407 char new_imsi[15 + 1] = {0, };
409 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
411 dbg("there is no valid server at this point");
414 strg = (Storage *) tcore_server_find_storage(s, "vconf");
416 dbg("there is no valid storage plugin");
419 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
420 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
421 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
423 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
424 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
426 if (old_imsi != NULL) {
427 if (strncmp(old_imsi, new_imsi, 15) != 0) {
429 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
430 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
432 tcore_sim_set_identification(o, TRUE);
435 tcore_sim_set_identification(o, FALSE);
438 dbg("OLD SIM VALUE IS NULL. NEW SIM");
439 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
440 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
442 tcore_sim_set_identification(o, TRUE);
447 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
449 struct tresp_sim_read resp = {0, };
450 struct s_sim_property *file_meta = NULL;
452 dbg("EF[0x%x] access Result[%d]", ef, rt);
455 memset(&resp.data, 0x00, sizeof(resp.data));
456 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
458 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
459 && (rt != SIM_ACCESS_SUCCESS)) {
460 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
466 if (rt == SIM_ACCESS_SUCCESS) {
467 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
468 /* if (po->language_file == 0x00)
469 po->language_file = SIM_EF_ELP;*/
470 _get_file_data(o, ur, ef, 0, file_meta->data_size);
472 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
473 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
474 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
475 _get_file_info(o, ur, SIM_EF_LP);
476 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
478 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
479 /* EFELPand EFLI not present at this point. */
480 /* po->language.lang_cnt = 0;*/
481 tcore_user_request_send_response(ur, _find_resp_command(ur),
482 sizeof(struct tresp_sim_read), &resp);
488 case SIM_EF_LP: // same with SIM_EF_USIM_LI
489 if (rt == SIM_ACCESS_SUCCESS) {
490 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
491 _get_file_data(o, ur, ef, 0, file_meta->data_size);
493 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
494 tcore_sim_get_type(o));
495 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
496 tcore_user_request_send_response(ur, _find_resp_command(ur),
497 sizeof(struct tresp_sim_read), &resp);
500 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
501 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
502 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
503 _get_file_info(o, ur, SIM_EF_ELP);
509 if (rt == SIM_ACCESS_SUCCESS) {
510 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
511 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
513 /* EFELIand EFPL not present, so set language count as zero and select ECC */
515 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
516 tcore_user_request_send_response(ur, _find_resp_command(ur),
517 sizeof(struct tresp_sim_read), &resp);
523 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
524 _get_file_data(o, ur, ef, 0, file_meta->data_size);
525 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
526 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
527 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
530 file_meta->current_index++;
531 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
540 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
541 case SIM_EF_CPHS_VOICE_MSG_WAITING:
542 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
543 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
544 case SIM_EF_CPHS_DYNAMICFLAGS:
545 case SIM_EF_CPHS_DYNAMIC2FLAG:
546 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
547 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
548 _get_file_data(o, ur, ef, 0, file_meta->data_size);
551 case SIM_EF_CPHS_CPHS_INFO:
552 if (rt == SIM_ACCESS_SUCCESS) {
553 tcore_sim_set_cphs_status(o, TRUE);
554 if (!tcore_user_request_ref_communicator(ur)) {
555 dbg("internal CPHS INFO request before sim status update");
556 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
558 dbg("external CPHS INFO request");
559 _get_file_data(o, ur, ef, 0, file_meta->data_size);
562 tcore_sim_set_cphs_status(o, FALSE);
563 if (!tcore_user_request_ref_communicator(ur)) {
564 dbg("internal CPHS INFO request before sim status update");
565 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
567 dbg("external CPHS INFO request");
568 tcore_user_request_send_response(ur, _find_resp_command(ur),
569 sizeof(struct tresp_sim_read), &resp);
575 case SIM_EF_USIM_CFIS:
576 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
577 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
579 file_meta->current_index++;
580 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
585 case SIM_EF_USIM_MWIS:
586 case SIM_EF_USIM_MBI:
588 case SIM_EF_CPHS_MAILBOX_NUMBERS:
589 case SIM_EF_CPHS_INFORMATION_NUMBERS:
590 file_meta->current_index++;
591 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
595 dbg("error - File id for get file info [0x%x]", ef);
601 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
603 struct s_sim_property *file_meta = NULL;
607 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
608 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
609 switch (file_meta->file_id) {
614 if (decode_ret == TRUE) {
615 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
616 /* po->language_file = SIM_EF_LP;*/
617 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
618 /* po->language_file = SIM_EF_ELP;*/
620 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
623 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
624 - EFELP is not available;
625 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
626 - the ME does not support any of the languages in EFELP.
629 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
630 - if the EFLI has the value 'FFFF' in its highest priority position
631 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
633 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
634 if (file_meta->file_id == SIM_EF_LP) {
635 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
637 _get_file_info(o, ur, SIM_EF_LP);
639 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
640 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
641 _get_file_info(o, ur, SIM_EF_ELP);
643 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
650 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
651 if (file_meta->current_index == file_meta->rec_count) {
652 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
654 file_meta->current_index++;
655 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
657 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
658 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
660 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
665 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
666 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
670 if (file_meta->current_index == file_meta->rec_count) {
671 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
673 file_meta->current_index++;
674 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
679 if (file_meta->current_index == file_meta->rec_count) {
680 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
682 file_meta->current_index++;
683 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
688 if (file_meta->current_index == file_meta->rec_count) {
689 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
691 file_meta->current_index++;
692 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
696 case SIM_EF_USIM_CFIS:
697 case SIM_EF_USIM_MWIS:
698 case SIM_EF_USIM_MBI:
700 case SIM_EF_CPHS_MAILBOX_NUMBERS:
701 case SIM_EF_CPHS_INFORMATION_NUMBERS:
702 if (file_meta->current_index == file_meta->rec_count) {
703 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
705 file_meta->current_index++;
706 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
710 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
711 file_meta->files.result = rt;
712 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
713 memcpy(file_meta->files.data.cphs_net.full_name, file_meta->files.data.cphs_net.full_name, strlen((char *) file_meta->files.data.cphs_net.full_name));
715 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
718 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
719 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
720 file_meta->files.result = SIM_ACCESS_SUCCESS;
722 if (strlen((char *) file_meta->files.data.cphs_net.full_name)) {
723 memcpy(&file_meta->files.data.cphs_net.full_name, &file_meta->files.data.cphs_net.full_name, strlen((char *) file_meta->files.data.cphs_net.full_name));
725 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
732 case SIM_EF_OPLMN_ACT:
733 case SIM_EF_CPHS_CPHS_INFO:
734 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
735 case SIM_EF_CPHS_VOICE_MSG_WAITING:
736 case SIM_EF_CPHS_DYNAMICFLAGS:
737 case SIM_EF_CPHS_DYNAMIC2FLAG:
738 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
739 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
740 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
744 dbg("File id not handled [0x%x]", file_meta->file_id);
749 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
751 struct tnoti_sim_status noti_data = {0, };
753 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
754 tcore_sim_set_status(o, sim_status);
755 noti_data.sim_status = sim_status;
756 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
757 sizeof(struct tnoti_sim_status), ¬i_data);
760 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
762 const TcoreATResponse *resp = data;
763 UserRequest *ur = NULL;
764 CoreObject *co_sim = NULL;
765 struct s_sim_property *sp = NULL;
766 GSList *tokens = NULL;
767 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
771 dbg(" Function entry ");
773 co_sim = tcore_pending_ref_core_object(p);
774 sp = tcore_sim_ref_userdata(co_sim);
775 ur = tcore_pending_ref_user_request(p);
777 if (resp->success > 0) {
780 line = (const char *) resp->lines->data;
781 tokens = tcore_at_tok_new(line);
782 if (g_slist_length(tokens) != 1) {
783 msg("invalid message");
784 tcore_at_tok_free(tokens);
788 state = atoi(g_slist_nth_data(tokens, 0));
789 dbg("SIM Type is %d", state);
792 sim_type = SIM_TYPE_GSM;
793 } else if (state == 1) {
794 sim_type = SIM_TYPE_USIM;
796 sim_type = SIM_TYPE_UNKNOWN;
800 sim_type = SIM_TYPE_UNKNOWN;
803 tcore_sim_set_type(co_sim, sim_type);
804 _sim_status_update(co_sim, sp->first_recv_status);
805 tcore_at_tok_free(tokens);
806 dbg(" Function exit");
809 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
811 const TcoreATResponse *resp = data;
812 UserRequest *ur = NULL;
813 CoreObject *co_sim = NULL;
814 struct s_sim_property *file_meta = NULL;
815 GSList *tokens = NULL;
816 enum tel_sim_access_result rt;
817 const char *line = NULL;
821 dbg(" Function entry ");
823 co_sim = tcore_pending_ref_core_object(p);
824 ur = tcore_pending_ref_user_request(p);
825 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
827 if (resp->success > 0) {
830 line = (const char *) resp->lines->data;
831 tokens = tcore_at_tok_new(line);
832 if (g_slist_length(tokens) < 2) {
833 err("invalid message");
834 tcore_at_tok_free(tokens);
838 sw1 = atoi(g_slist_nth_data(tokens, 0));
839 sw2 = atoi(g_slist_nth_data(tokens, 1));
841 /*1. SIM access success case*/
842 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
843 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
844 unsigned short record_len = 0;
845 char num_of_records = 0;
846 unsigned char file_id_len = 0;
847 unsigned short file_id = 0;
848 unsigned short file_size = 0;
849 unsigned short file_type = 0;
850 unsigned short arr_file_id = 0;
851 int arr_file_id_rec_num = 0;
853 /* handling only last 3 bits */
854 unsigned char file_type_tag = 0x07;
855 unsigned char *ptr_data;
859 char *recordData = NULL;
860 hexData = g_slist_nth_data(tokens, 2);
861 dbg("hexData: %s", hexData);
862 dbg("hexData: %s", hexData + 1);
864 tmp = util_removeQuotes(hexData);
865 recordData = util_hexStringToBytes(tmp);
866 util_hex_dump(" ", strlen(hexData) / 2, recordData);
869 ptr_data = (unsigned char *) recordData;
870 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
872 ETSI TS 102 221 v7.9.0
874 '62' FCP template tag
876 '82' M File Descriptor
877 '83' M File Identifier
878 'A5' O Proprietary information
879 '8A' M Life Cycle Status Integer
880 '8B', '8C' or 'AB' C1 Security attributes
882 '81' O Total file size
883 '88' O Short File Identifier (SFI)
886 /* rsim.res_len has complete data length received */
888 /* FCP template tag - File Control Parameters tag*/
889 if (*ptr_data == 0x62) {
890 /* parse complete FCP tag*/
891 /* increment to next byte */
893 tag_len = *ptr_data++;
894 dbg("tag_len: %02x", tag_len);
895 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
896 if (*ptr_data == 0x82) {
897 /* increment to next byte */
901 /* unsigned char file_desc_len = *ptr_data++;*/
902 /* dbg("file descriptor length: [%d]", file_desc_len);*/
903 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
904 /* consider only last 3 bits*/
905 dbg("file_type_tag: %02x", file_type_tag);
906 file_type_tag = file_type_tag & (*ptr_data);
907 dbg("file_type_tag: %02x", file_type_tag);
909 switch (file_type_tag) {
910 /* increment to next byte */
913 dbg("Getting FileType: [Transparent file type]");
914 file_type = SIM_FTYPE_TRANSPARENT;
916 /* increment to next byte */
918 /* increment to next byte */
923 dbg("Getting FileType: [Linear fixed file type]");
924 /* increment to next byte */
926 /* data coding byte - value 21 */
929 memcpy(&record_len, ptr_data, 2);
931 SWAPBYTES16(record_len);
932 ptr_data = ptr_data + 2;
933 num_of_records = *ptr_data++;
934 /* Data lossy conversation from enum (int) to unsigned char */
935 file_type = SIM_FTYPE_LINEAR_FIXED;
939 dbg(" Cyclic fixed file type");
940 /* increment to next byte */
942 /* data coding byte - value 21 */
945 memcpy(&record_len, ptr_data, 2);
947 SWAPBYTES16(record_len);
948 ptr_data = ptr_data + 2;
949 num_of_records = *ptr_data++;
950 file_type = SIM_FTYPE_CYCLIC;
954 dbg("not handled file type [0x%x]", *ptr_data);
958 dbg("INVALID FCP received - DEbug!");
959 tcore_at_tok_free(tokens);
964 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
965 if (*ptr_data == 0x83) {
966 /* increment to next byte */
968 file_id_len = *ptr_data++;
969 dbg("file_id_len: %02x", file_id_len);
971 memcpy(&file_id, ptr_data, file_id_len);
972 dbg("file_id: %x", file_id);
975 SWAPBYTES16(file_id);
976 dbg("file_id: %x", file_id);
978 ptr_data = ptr_data + 2;
979 dbg("Getting FileID=[0x%x]", file_id);
981 dbg("INVALID FCP received - DEbug!");
982 tcore_at_tok_free(tokens);
987 /* proprietary information */
988 if (*ptr_data == 0xA5) {
989 unsigned short prop_len;
990 /* increment to next byte */
994 prop_len = *ptr_data;
995 dbg("prop_len: %02x", prop_len);
998 ptr_data = ptr_data + prop_len + 1;
1000 dbg("INVALID FCP received - DEbug!");
1003 /* life cycle status integer [8A][length:0x01][status]*/
1006 00000000 : No information given
1007 00000001 : creation state
1008 00000011 : initialization state
1009 000001-1 : operation state -activated
1010 000001-0 : operation state -deactivated
1011 000011-- : Termination state
1012 b8~b5 !=0, b4~b1=X : Proprietary
1013 Any other value : RFU
1015 if (*ptr_data == 0x8A) {
1016 /* increment to next byte */
1018 /* length - value 1 */
1021 switch (*ptr_data) {
1024 dbg("<RX> operation state -deactivated");
1030 dbg("<RX> operation state -activated");
1035 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1041 /* related to security attributes : currently not handled*/
1042 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1043 /* increment to next byte */
1045 /* if tag length is 3 */
1046 if (*ptr_data == 0x03) {
1047 /* increment to next byte */
1050 memcpy(&arr_file_id, ptr_data, 2);
1052 SWAPBYTES16(arr_file_id);
1053 ptr_data = ptr_data + 2;
1054 arr_file_id_rec_num = *ptr_data++;
1056 /* if tag length is not 3 */
1057 /* ignoring bytes */
1058 // ptr_data = ptr_data + 4;
1059 dbg("Useless security attributes, so jump to next tag");
1060 ptr_data = ptr_data + (*ptr_data + 1);
1063 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1064 tcore_at_tok_free(tokens);
1069 dbg("Current ptr_data value is [%x]", *ptr_data);
1071 /* file size excluding structural info*/
1072 if (*ptr_data == 0x80) {
1073 /* for EF file size is body of file and for Linear or cyclic it is
1074 * number of recXsizeof(one record)
1076 /* increment to next byte */
1078 /* length is 1 byte - value is 2 bytes or more */
1080 memcpy(&file_size, ptr_data, 2);
1082 SWAPBYTES16(file_size);
1083 ptr_data = ptr_data + 2;
1085 dbg("INVALID FCP received - DEbug!");
1086 tcore_at_tok_free(tokens);
1091 /* total file size including structural info*/
1092 if (*ptr_data == 0x81) {
1094 /* increment to next byte */
1099 ptr_data = ptr_data + 3;
1101 dbg("INVALID FCP received - DEbug!");
1102 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1105 /*short file identifier ignored*/
1106 if (*ptr_data == 0x88) {
1107 dbg("0x88: Do Nothing");
1111 dbg("INVALID FCP received - DEbug!");
1112 tcore_at_tok_free(tokens);
1116 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1117 unsigned char gsm_specific_file_data_len = 0;
1118 /* ignore RFU byte1 and byte2 */
1122 // file_size = p_info->response_len;
1123 memcpy(&file_size, ptr_data, 2);
1125 SWAPBYTES16(file_size);
1126 /* parsed file size */
1127 ptr_data = ptr_data + 2;
1129 memcpy(&file_id, ptr_data, 2);
1130 SWAPBYTES16(file_id);
1131 dbg(" FILE id --> [%x]", file_id);
1132 ptr_data = ptr_data + 2;
1133 /* save file type - transparent, linear fixed or cyclic */
1134 file_type_tag = (*(ptr_data + 7));
1136 switch (*ptr_data) {
1139 dbg(" RFU file type- not handled - Debug!");
1144 dbg(" MF file type - not handled - Debug!");
1149 dbg(" DF file type - not handled - Debug!");
1154 dbg(" EF file type [%d] ", file_type_tag);
1155 /* increment to next byte */
1158 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1159 /* increament to next byte as this byte is RFU */
1162 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1164 /* increment to next byte */
1166 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1167 /* the INCREASE command is allowed on the selected cyclic file. */
1168 file_type = SIM_FTYPE_CYCLIC;
1170 /* bytes 9 to 11 give SIM file access conditions */
1172 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1174 /* byte 11 is invalidate and rehabilate nibbles */
1176 /* byte 12 - file status */
1178 /* byte 13 - GSM specific data */
1179 gsm_specific_file_data_len = *ptr_data;
1181 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1183 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1184 record_len = *ptr_data;
1185 dbg("record length[%d], file size[%d]", record_len, file_size);
1187 if (record_len != 0)
1188 num_of_records = (file_size / record_len);
1190 dbg("Number of records [%d]", num_of_records);
1194 dbg(" not handled file type");
1198 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1201 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1202 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1204 file_meta->file_type = file_type;
1205 file_meta->data_size = file_size;
1206 file_meta->rec_length = record_len;
1207 file_meta->rec_count = num_of_records;
1208 file_meta->current_index = 0; // reset for new record type EF
1209 rt = SIM_ACCESS_SUCCESS;
1212 /*2. SIM access fail case*/
1213 dbg("error to get ef[0x%x]", file_meta->file_id);
1214 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1215 rt = _decode_status_word(sw1, sw2);
1217 ur = tcore_user_request_ref(ur);
1219 dbg("Calling _next_from_get_file_info");
1220 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1221 tcore_at_tok_free(tokens);
1223 dbg("RESPONSE NOK");
1224 dbg("error to get ef[0x%x]", file_meta->file_id);
1225 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1226 rt = SIM_ACCESS_FAILED;
1228 ur = tcore_user_request_ref(ur);
1229 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1231 dbg(" Function exit");
1234 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1236 const TcoreATResponse *resp = data;
1237 UserRequest *ur = NULL;
1238 CoreObject *co_sim = NULL;
1239 struct s_sim_property *file_meta = NULL;
1240 GSList *tokens = NULL;
1241 enum tel_sim_access_result rt;
1242 struct tel_sim_imsi *imsi = NULL;
1243 struct tel_sim_service_table *svct = NULL;
1244 struct tel_sim_ecc *ecc = NULL;
1245 struct tel_sim_msisdn *msisdn = NULL;
1246 struct tel_sim_opl *opl = NULL;
1247 struct tel_sim_pnn *pnn = NULL;
1248 struct tel_sim_cfis *cf = NULL;
1249 struct tel_sim_mbi *mbi = NULL;
1250 struct tel_sim_mw *mw = NULL;
1251 gboolean dr = FALSE;
1252 const char *line = NULL;
1259 dbg(" Function entry ");
1261 co_sim = tcore_pending_ref_core_object(p);
1262 ur = tcore_pending_ref_user_request(p);
1263 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
1265 if (resp->success > 0) {
1268 line = (const char *) resp->lines->data;
1269 tokens = tcore_at_tok_new(line);
1270 if (g_slist_length(tokens) != 3) {
1271 msg("invalid message");
1272 tcore_at_tok_free(tokens);
1276 sw1 = atoi(g_slist_nth_data(tokens, 0));
1277 sw2 = atoi(g_slist_nth_data(tokens, 1));
1278 res = g_slist_nth_data(tokens, 2);
1280 tmp = util_removeQuotes(res);
1281 res = util_hexStringToBytes(tmp);
1282 res_len = strlen((const char *) res);
1283 dbg("res: %s res_len: %d", res, res_len);
1285 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1286 rt = SIM_ACCESS_SUCCESS;
1287 file_meta->files.result = rt;
1288 dbg("file_meta->file_id : %x", file_meta->file_id);
1290 switch (file_meta->file_id) {
1293 dbg("res: %s", res);
1294 imsi = calloc(sizeof(struct tel_sim_imsi),1);
1295 dr = tcore_sim_decode_imsi(imsi, (unsigned char *) res, res_len);
1297 dbg("imsi decoding failed");
1299 _sim_check_identity(co_sim, imsi);
1300 tcore_sim_set_imsi(co_sim, imsi);
1308 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
1311 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
1312 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1313 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
1314 case SIM_EF_LP: /* 1 byte encoding*/
1315 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1316 /*2G LP(0x6F05) has 1 byte for each language*/
1317 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
1319 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1320 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
1325 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
1329 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
1332 case SIM_EF_SST: //EF UST has same address
1333 svct = calloc(sizeof(struct tel_sim_service_table),1);
1334 if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1335 dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *) res, res_len);
1336 }else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1337 dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *) res, res_len);
1339 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1342 dbg("SST/UST decoding failed");
1344 tcore_sim_set_service_table(co_sim, svct);
1351 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1352 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
1353 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1354 ecc = calloc(sizeof(struct tel_sim_ecc),1);
1355 dbg("decode w/ index [%d]", file_meta->current_index);
1356 dr = tcore_sim_decode_uecc(ecc, (unsigned char *) res, res_len);
1358 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1359 file_meta->files.data.ecc.ecc_count++;
1364 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
1369 dbg("decode w/ index [%d]", file_meta->current_index);
1370 msisdn = calloc(sizeof(struct tel_sim_msisdn),1);
1371 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *) res, res_len);
1373 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], msisdn, sizeof(struct tel_sim_msisdn));
1374 file_meta->files.data.msisdn_list.count++;
1381 dbg("decode w/ index [%d]", file_meta->current_index);
1382 opl = calloc(sizeof(struct tel_sim_opl),1);
1383 dr = tcore_sim_decode_opl(opl, (unsigned char *) res, res_len);
1385 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], opl, sizeof(struct tel_sim_opl));
1386 file_meta->files.data.opl.opl_count++;
1391 dbg("decode w/ index [%d]", file_meta->current_index);
1392 pnn = calloc(sizeof(struct tel_sim_pnn),1);
1393 dr = tcore_sim_decode_pnn(pnn, (unsigned char *) res, res_len);
1395 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], pnn, sizeof(struct tel_sim_pnn));
1396 file_meta->files.data.pnn.pnn_count++;
1402 case SIM_EF_OPLMN_ACT:
1403 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
1406 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1407 /* dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1410 case SIM_EF_USIM_MBI: //linear type
1411 mbi = calloc(sizeof(struct tel_sim_mbi),1);
1412 dr = tcore_sim_decode_mbi(mbi, (unsigned char *) res, res_len);
1414 memcpy( &file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count], mbi, sizeof(struct tel_sim_mbi) );
1415 file_meta->mbi_list.profile_count++;
1416 dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
1417 dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
1418 dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
1419 dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
1420 dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
1421 dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
1427 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1428 case SIM_EF_MBDN: //linear type
1429 dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info, (unsigned char *) res, res_len);
1430 file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
1433 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1434 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw, (unsigned char *) res, res_len);
1437 case SIM_EF_USIM_MWIS: //linear type
1438 mw = calloc(sizeof(struct tel_sim_mw),1);
1439 dr = tcore_sim_decode_mwis(mw, (unsigned char *) res, res_len);
1441 memcpy( &file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw) );
1442 file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
1443 file_meta->files.data.mw.mw_list.profile_count++;
1449 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
1450 dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf, (unsigned char *) res, res_len);
1453 case SIM_EF_USIM_CFIS: //linear type
1454 cf = calloc(sizeof(struct tel_sim_cfis),1);
1455 dr = tcore_sim_decode_cfis(cf, (unsigned char *) res, res_len);
1457 memcpy( &file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count], cf, sizeof(struct tel_sim_cfis) );
1458 file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
1459 file_meta->files.data.cf.cf_list.profile_count++;
1465 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1466 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1469 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1470 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
1471 dbg(" file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]", file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1474 case SIM_EF_CPHS_DYNAMICFLAGS:
1475 /* dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, p_data->response, p_data->response_len);*/
1478 case SIM_EF_CPHS_DYNAMIC2FLAG:
1479 /* dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response, p_data->response_len);*/
1482 case SIM_EF_CPHS_CPHS_INFO:
1483 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
1486 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1487 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
1490 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1491 /* dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1495 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1500 rt = _decode_status_word(sw1, sw2);
1501 file_meta->files.result = rt;
1505 tcore_at_tok_free(tokens);
1507 dbg("RESPONSE NOK");
1508 dbg("error to get ef[0x%x]", file_meta->file_id);
1509 rt = SIM_ACCESS_FAILED;
1511 ur = tcore_user_request_ref(ur);
1513 dbg("Calling _next_from_get_file_data");
1514 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1515 dbg(" Function exit");
1518 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1520 const TcoreATResponse *resp = data;
1521 UserRequest *ur = NULL;
1522 CoreObject *co_sim = NULL;
1523 struct s_sim_property *sp = NULL;
1524 GSList *tokens = NULL;
1525 const char *line = NULL;
1526 struct tresp_sim_verify_pins v_pin = {0, };
1527 struct tresp_sim_verify_puks v_puk = {0, };
1528 struct tresp_sim_change_pins change_pin = {0, };
1529 struct tresp_sim_disable_facility dis_facility = {0, };
1530 struct tresp_sim_enable_facility en_facility = {0, };
1532 int attempts_left = 0;
1533 int time_penalty = 0;
1535 dbg(" Function entry ");
1537 co_sim = tcore_pending_ref_core_object(p);
1538 sp = tcore_sim_ref_userdata(co_sim);
1539 ur = tcore_pending_ref_user_request(p);
1541 if (resp->success > 0) {
1544 line = (const char *) resp->lines->data;
1545 tokens = tcore_at_tok_new(line);
1546 if (g_slist_length(tokens) < 3) {
1547 msg("invalid message");
1548 tcore_at_tok_free(tokens);
1552 lock_type = atoi(g_slist_nth_data(tokens, 0));
1553 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1554 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1556 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1557 lock_type, attempts_left, time_penalty);
1559 switch (sp->current_sec_op) {
1560 case SEC_PIN1_VERIFY:
1561 case SEC_PIN2_VERIFY:
1562 case SEC_SIM_VERIFY:
1563 case SEC_ADM_VERIFY:
1564 v_pin.result = SIM_INCORRECT_PASSWORD;
1565 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1566 v_pin.retry_count = attempts_left;
1567 tcore_user_request_send_response(ur, _find_resp_command(ur),
1568 sizeof(struct tresp_sim_verify_pins), &v_pin);
1571 case SEC_PUK1_VERIFY:
1572 case SEC_PUK2_VERIFY:
1573 v_puk.result = SIM_INCORRECT_PASSWORD;
1574 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1575 v_puk.retry_count = attempts_left;
1576 tcore_user_request_send_response(ur, _find_resp_command(ur),
1577 sizeof(struct tresp_sim_verify_puks), &v_puk);
1580 case SEC_PIN1_CHANGE:
1581 case SEC_PIN2_CHANGE:
1582 change_pin.result = SIM_INCORRECT_PASSWORD;
1583 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1584 change_pin.retry_count = attempts_left;
1585 tcore_user_request_send_response(ur, _find_resp_command(ur),
1586 sizeof(struct tresp_sim_change_pins), &change_pin);
1589 case SEC_PIN1_DISABLE:
1590 case SEC_PIN2_DISABLE:
1591 case SEC_FDN_DISABLE:
1592 case SEC_SIM_DISABLE:
1593 case SEC_NET_DISABLE:
1594 case SEC_NS_DISABLE:
1595 case SEC_SP_DISABLE:
1596 case SEC_CP_DISABLE:
1597 dis_facility.result = SIM_INCORRECT_PASSWORD;
1598 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1599 dis_facility.retry_count = attempts_left;
1600 tcore_user_request_send_response(ur, _find_resp_command(ur),
1601 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1604 case SEC_PIN1_ENABLE:
1605 case SEC_PIN2_ENABLE:
1606 case SEC_FDN_ENABLE:
1607 case SEC_SIM_ENABLE:
1608 case SEC_NET_ENABLE:
1612 en_facility.result = SIM_INCORRECT_PASSWORD;
1613 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1614 en_facility.retry_count = attempts_left;
1615 tcore_user_request_send_response(ur, _find_resp_command(ur),
1616 sizeof(struct tresp_sim_enable_facility), &en_facility);
1620 dbg("not handled sec op[%d]", sp->current_sec_op);
1623 tcore_at_tok_free(tokens);
1625 dbg(" Function exit");
1628 static gboolean _get_sim_type(CoreObject *o)
1630 TcoreHal *hal = NULL;
1631 TcoreATRequest *req = NULL;
1632 TcorePending *pending = NULL;
1633 UserRequest *ur = NULL;
1634 char *cmd_str = NULL;
1636 dbg(" Function entry ");
1638 hal = tcore_object_get_hal(o);
1639 pending = tcore_pending_new(o, 0);
1641 cmd_str = g_strdup_printf("AT+XUICC?");
1642 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1644 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1646 tcore_pending_set_request_data(pending, 0, req);
1647 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1648 tcore_pending_link_user_request(pending, ur);
1649 tcore_hal_send_request(hal, pending);
1652 dbg(" Function exit");
1656 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1658 TcoreHal *hal = NULL;
1659 TcorePending *pending = NULL;
1660 struct s_sim_property file_meta = {0, };
1661 char *cmd_str = NULL;
1662 TReturn ret = TCORE_RETURN_FAILURE;
1665 dbg(" Function entry ");
1667 file_meta.file_id = ef;
1668 dbg("file_meta.file_id: %d", file_meta.file_id);
1669 hal = tcore_object_get_hal(o);
1670 dbg("hal: %x", hal);
1672 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1673 dbg("trt[%d]", trt);
1674 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1675 dbg("cmd_str: %x", cmd_str);
1677 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1678 tcore_pending_link_user_request(pending, ur);
1679 ret = tcore_hal_send_request(hal, pending);
1680 if (TCORE_RETURN_SUCCESS != ret) {
1681 tcore_user_request_free(ur);
1684 dbg(" Function exit");
1685 return TCORE_RETURN_SUCCESS;
1688 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1690 TcoreHal *hal = NULL;
1691 TcoreATRequest *req = NULL;
1692 TcorePending *pending = NULL;
1693 char *cmd_str = NULL;
1698 dbg(" Function entry ");
1699 hal = tcore_object_get_hal(o);
1700 pending = tcore_pending_new(o, 0);
1702 dbg("file_id: %x", ef);
1704 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1705 p2 = (unsigned char) offset & 0x00FF; // offset low
1706 p3 = (unsigned char) length;
1708 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1710 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1712 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1714 tcore_pending_set_request_data(pending, 0, req);
1715 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1716 tcore_pending_link_user_request(pending, ur);
1717 tcore_hal_send_request(hal, pending);
1720 dbg(" Function exit");
1724 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1726 TcoreHal *hal = NULL;
1727 TcoreATRequest *req = NULL;
1728 TcorePending *pending = NULL;
1729 char *cmd_str = NULL;
1734 dbg(" Function entry ");
1736 hal = tcore_object_get_hal(o);
1737 pending = tcore_pending_new(o, 0);
1739 p1 = (unsigned char) index;
1740 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1741 p3 = (unsigned char) length;
1743 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1745 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1747 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1749 tcore_pending_set_request_data(pending, 0, req);
1750 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1751 tcore_pending_link_user_request(pending, ur);
1752 tcore_hal_send_request(hal, pending);
1755 dbg(" Function exit");
1759 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1761 TcoreHal *hal = NULL;
1762 TcoreATRequest *req = NULL;
1763 TcorePending *pending = NULL;
1764 char *cmd_str = NULL;
1766 struct s_sim_property *sp = NULL;
1767 const struct treq_sim_get_lock_info *req_data = NULL;
1769 dbg(" Function entry ");
1771 hal = tcore_object_get_hal(o);
1772 pending = tcore_pending_new(o, 0);
1773 req_data = tcore_user_request_ref_data(ur, NULL);
1774 sp = tcore_sim_ref_userdata(o);
1776 switch (sp->current_sec_op) {
1777 case SEC_PIN1_VERIFY:
1778 case SEC_PIN1_CHANGE:
1779 case SEC_PIN1_ENABLE:
1780 case SEC_PIN1_DISABLE:
1784 case SEC_PIN2_VERIFY:
1785 case SEC_PIN2_CHANGE:
1786 case SEC_PIN2_ENABLE:
1787 case SEC_PIN2_DISABLE:
1788 case SEC_FDN_ENABLE:
1789 case SEC_FDN_DISABLE:
1793 case SEC_PUK1_VERIFY:
1797 case SEC_PUK2_VERIFY:
1801 case SEC_NET_ENABLE:
1802 case SEC_NET_DISABLE:
1807 case SEC_NS_DISABLE:
1812 case SEC_SP_DISABLE:
1817 case SEC_CP_DISABLE:
1821 case SEC_ADM_VERIFY:
1829 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1830 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1831 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1833 tcore_pending_set_request_data(pending, 0, req);
1834 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1835 tcore_pending_link_user_request(pending, ur);
1836 tcore_hal_send_request(hal, pending);
1839 dbg(" Function exit");
1840 return TCORE_RETURN_SUCCESS;
1844 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1846 struct s_sim_property *sp = NULL;
1848 GSList *tokens = NULL;
1849 GSList *lines = NULL;
1851 dbg("Function entry");
1854 sp = tcore_sim_ref_userdata(o);
1855 lines = (GSList *) event_info;
1856 if (1 != g_slist_length(lines)) {
1857 dbg("unsolicited msg but multiple line");
1860 line = (char *) (lines->data);
1861 tokens = tcore_at_tok_new(line);
1862 if (g_slist_length(tokens) != 1) {
1863 msg("invalid message");
1864 tcore_at_tok_free(tokens);
1869 dbg(" Function exit");
1871 tcore_at_tok_free(tokens);
1876 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1878 UserRequest *ur = NULL;
1879 struct s_sim_property *sp = NULL;
1880 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1881 GSList *tokens = NULL;
1882 GSList *lines = NULL;
1883 const char *line = NULL;
1886 dbg(" Function entry ");
1888 sp = tcore_sim_ref_userdata(o);
1890 lines = (GSList *) event_info;
1891 if (1 != g_slist_length(lines)) {
1892 dbg("unsolicited msg but multiple line");
1895 line = (char *) (lines->data);
1897 tokens = tcore_at_tok_new(line);
1898 if (g_slist_length(tokens) != 1) {
1899 msg("invalid message");
1900 tcore_at_tok_free(tokens);
1903 sim_state = atoi(g_slist_nth_data(tokens, 0));
1905 switch (sim_state) {
1906 case 0: // sim state = SIM not present
1907 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1911 case 1: // sim state = PIN verification needed
1912 sim_status = SIM_STATUS_PIN_REQUIRED;
1913 dbg(" PIN required");
1916 case 2: // sim state = PIN verification not needed \96 Ready
1917 case 3: // sim state = PIN verified \96 Ready
1918 sim_status = SIM_STATUS_INITIALIZING;
1919 dbg(" Inside PIN disabled at BOOT UP");
1922 case 4: // sim state = PUK verification needed
1923 sim_status = SIM_STATUS_PUK_REQUIRED;
1924 dbg(" PUK required");
1927 case 5: // sim state = SIM permanently blocked
1928 sim_status = SIM_STATUS_CARD_BLOCKED;
1929 dbg(" Card permanently blocked");
1932 case 6: // sim state = SIM error
1933 sim_status = SIM_STATUS_CARD_ERROR;
1934 dbg("SIM card error ");
1937 case 7: // sim state = ready for attach (+COPS)
1938 sim_status = SIM_STATUS_INIT_COMPLETED;
1939 dbg("Modem init completed");
1942 case 8: // sim state = SIM Technical Problem
1943 sim_status = SIM_STATUS_CARD_ERROR;
1944 dbg("SIM unavailable");
1947 case 9: // sim state = SIM removed
1948 sim_status = SIM_STATUS_CARD_REMOVED;
1952 case 99: // sim state = SIM State Unknown
1953 sim_status = SIM_STATUS_UNKNOWN;
1954 dbg("SIM State Unknown");
1958 dbg("SIM Status : %d", sim_status);
1962 dbg(" not handled SEC lock type ");
1966 switch (sim_status) {
1967 case SIM_STATUS_INIT_COMPLETED:
1968 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
1969 _get_file_info(o, ur, SIM_EF_IMSI);
1972 case SIM_STATUS_INITIALIZING:
1973 case SIM_STATUS_PIN_REQUIRED:
1974 case SIM_STATUS_PUK_REQUIRED:
1975 case SIM_STATUS_CARD_BLOCKED:
1976 case SIM_STATUS_NCK_REQUIRED:
1977 case SIM_STATUS_NSCK_REQUIRED:
1978 case SIM_STATUS_SPCK_REQUIRED:
1979 case SIM_STATUS_CCK_REQUIRED:
1980 case SIM_STATUS_LOCK_REQUIRED:
1981 if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
1982 dbg("first received sim status[%d]", sim_status);
1983 sp->first_recv_status = sim_status;
1986 dbg("second or later received lock status[%d]", sim_status);
1987 if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
1988 dbg("sim is not init complete in telephony side yet");
1989 _sim_status_update(o, sim_status);
1994 case SIM_STATUS_CARD_REMOVED:
1995 case SIM_STATUS_CARD_NOT_PRESENT:
1996 case SIM_STATUS_CARD_ERROR:
1997 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
1998 dbg("[SIM]SIM CARD REMOVED!!");
1999 sim_status = SIM_STATUS_CARD_REMOVED;
2001 _sim_status_update(o, sim_status);
2005 dbg("not handled status[%d]", sim_status);
2010 dbg(" Function exit");
2012 tcore_at_tok_free(tokens);
2016 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2018 const TcoreATResponse *resp = data;
2019 UserRequest *ur = NULL;
2020 CoreObject *co_sim = NULL;
2021 struct s_sim_property *sp = NULL;
2022 GSList *tokens = NULL;
2023 struct tresp_sim_verify_pins res;
2024 GQueue *queue = NULL;
2028 dbg(" Function entry ");
2030 co_sim = tcore_pending_ref_core_object(p);
2031 sp = tcore_sim_ref_userdata(co_sim);
2032 ur = tcore_pending_ref_user_request(p);
2034 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2036 if (resp->success > 0) {
2038 res.result = SIM_PIN_OPERATION_SUCCESS;
2039 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2040 if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
2041 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
2042 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2044 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2046 dbg("RESPONSE NOK");
2047 line = (const char *) resp->final_response;
2048 tokens = tcore_at_tok_new(line);
2049 if (g_slist_length(tokens) < 1) {
2050 dbg("err cause not specified or string corrupted");
2051 res.result = TCORE_RETURN_3GPP_ERROR;
2052 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2054 err = atoi(g_slist_nth_data(tokens, 0));
2055 dbg("on_response_verify_pins: err = %d", err);
2056 queue = tcore_object_ref_user_data(co_sim);
2057 ur = tcore_user_request_ref(ur);
2058 _get_retry_count(co_sim, ur);
2060 tcore_at_tok_free(tokens);
2062 dbg(" Function exit");
2065 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2067 const TcoreATResponse *resp = data;
2068 UserRequest *ur = NULL;
2069 CoreObject *co_sim = NULL;
2070 struct s_sim_property *sp = NULL;
2071 GSList *tokens = NULL;
2072 struct tresp_sim_verify_puks res;
2073 GQueue *queue = NULL;
2077 dbg(" Function entry ");
2079 co_sim = tcore_pending_ref_core_object(p);
2080 sp = tcore_sim_ref_userdata(co_sim);
2081 ur = tcore_pending_ref_user_request(p);
2083 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2085 if (resp->success > 0) {
2087 res.result = SIM_PIN_OPERATION_SUCCESS;
2088 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2089 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2091 dbg("RESPONSE NOK");
2092 line = (const char *) resp->final_response;
2093 tokens = tcore_at_tok_new(line);
2095 if (g_slist_length(tokens) < 1) {
2096 dbg("err cause not specified or string corrupted");
2097 res.result = TCORE_RETURN_3GPP_ERROR;
2098 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2100 err = atoi(g_slist_nth_data(tokens, 0));
2101 queue = tcore_object_ref_user_data(co_sim);
2102 ur = tcore_user_request_ref(ur);
2103 _get_retry_count(co_sim, ur);
2105 tcore_at_tok_free(tokens);
2107 dbg(" Function exit");
2110 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2112 const TcoreATResponse *resp = data;
2113 UserRequest *ur = NULL;
2114 CoreObject *co_sim = NULL;
2115 struct s_sim_property *sp = NULL;
2116 GSList *tokens = NULL;
2117 struct tresp_sim_change_pins res;
2122 dbg(" Function entry ");
2124 co_sim = tcore_pending_ref_core_object(p);
2125 sp = tcore_sim_ref_userdata(co_sim);
2126 ur = tcore_pending_ref_user_request(p);
2128 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2130 if (resp->success > 0) {
2132 res.result = SIM_PIN_OPERATION_SUCCESS;
2133 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2134 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2136 dbg("RESPONSE NOK");
2137 line = (const char *) resp->final_response;
2138 tokens = tcore_at_tok_new(line);
2140 if (g_slist_length(tokens) < 1) {
2141 dbg("err cause not specified or string corrupted");
2142 res.result = TCORE_RETURN_3GPP_ERROR;
2143 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2145 err = atoi(g_slist_nth_data(tokens, 0));
2146 queue = tcore_object_ref_user_data(co_sim);
2147 ur = tcore_user_request_ref(ur);
2148 _get_retry_count(co_sim, ur);
2150 tcore_at_tok_free(tokens);
2152 dbg(" Function exit");
2155 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2157 const TcoreATResponse *resp = data;
2158 UserRequest *ur = NULL;
2159 CoreObject *co_sim = NULL;
2160 struct s_sim_property *sp = NULL;
2161 GSList *tokens = NULL;
2162 struct tresp_sim_get_facility_status res;
2165 dbg(" Function entry ");
2167 co_sim = tcore_pending_ref_core_object(p);
2168 sp = tcore_sim_ref_userdata(co_sim);
2169 ur = tcore_pending_ref_user_request(p);
2171 memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
2173 res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2174 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2176 if (resp->success > 0) {
2179 line = (const char *) resp->lines->data;
2180 tokens = tcore_at_tok_new(line);
2181 if (g_slist_length(tokens) != 1) {
2182 msg("invalid message");
2186 res.b_enable = atoi(g_slist_nth_data(tokens, 0));
2188 dbg("RESPONSE NOK");
2192 tcore_user_request_send_response(ur, _find_resp_command(ur),
2193 sizeof(struct tresp_sim_get_facility_status), &res);
2195 tcore_at_tok_free(tokens);
2196 dbg(" Function exit");
2199 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2201 const TcoreATResponse *resp = data;
2202 UserRequest *ur = NULL;
2203 CoreObject *co_sim = NULL;
2204 struct s_sim_property *sp = NULL;
2205 GSList *tokens = NULL;
2206 struct tresp_sim_enable_facility res;
2210 dbg(" Function entry ");
2212 co_sim = tcore_pending_ref_core_object(p);
2213 sp = tcore_sim_ref_userdata(co_sim);
2214 ur = tcore_pending_ref_user_request(p);
2216 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2218 res.result = SIM_CARD_ERROR;
2219 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2221 if (resp->success > 0) {
2224 line = (const char *) resp->lines->data;
2225 tokens = tcore_at_tok_new(line);
2226 if (g_slist_length(tokens) != 1) {
2227 msg("invalid message");
2228 tcore_user_request_send_response(ur, _find_resp_command(ur),
2229 sizeof(struct tresp_sim_enable_facility), &res);
2230 tcore_at_tok_free(tokens);
2234 res.result = SIM_PIN_OPERATION_SUCCESS;
2236 tcore_user_request_send_response(ur, _find_resp_command(ur),
2237 sizeof(struct tresp_sim_enable_facility), &res);
2239 tcore_at_tok_free(tokens);
2241 dbg("RESPONSE NOK");
2242 queue = tcore_object_ref_user_data(co_sim);
2243 ur = tcore_user_request_ref(ur);
2244 _get_retry_count(co_sim, ur);
2246 dbg(" Function exit");
2249 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2251 const TcoreATResponse *resp = data;
2252 UserRequest *ur = NULL;
2253 CoreObject *co_sim = NULL;
2254 struct s_sim_property *sp = NULL;
2255 GSList *tokens = NULL;
2256 struct tresp_sim_disable_facility res;
2260 dbg(" Function entry ");
2262 co_sim = tcore_pending_ref_core_object(p);
2263 sp = tcore_sim_ref_userdata(co_sim);
2264 ur = tcore_pending_ref_user_request(p);
2266 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2268 res.result = SIM_CARD_ERROR;
2269 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2271 if (resp->success > 0) {
2274 line = (const char *) resp->lines->data;
2275 tokens = tcore_at_tok_new(line);
2276 if (g_slist_length(tokens) != 1) {
2277 msg("invalid message");
2278 tcore_user_request_send_response(ur, _find_resp_command(ur),
2279 sizeof(struct tresp_sim_disable_facility), &res);
2280 tcore_at_tok_free(tokens);
2284 res.result = SIM_PIN_OPERATION_SUCCESS;
2286 tcore_user_request_send_response(ur, _find_resp_command(ur),
2287 sizeof(struct tresp_sim_disable_facility), &res);
2289 tcore_at_tok_free(tokens);
2291 dbg("RESPONSE NOK");
2292 queue = tcore_object_ref_user_data(co_sim);
2293 ur = tcore_user_request_ref(ur);
2294 _get_retry_count(co_sim, ur);
2296 dbg(" Function exit");
2299 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2301 const TcoreATResponse *resp = data;
2302 UserRequest *ur = NULL;
2303 CoreObject *co_sim = NULL;
2304 struct s_sim_property *sp = NULL;
2305 GSList *tokens = NULL;
2307 struct tresp_sim_verify_pins v_pin = {0, };
2308 struct tresp_sim_verify_puks v_puk = {0, };
2309 struct tresp_sim_change_pins change_pin = {0, };
2310 struct tresp_sim_disable_facility dis_facility = {0, };
2311 struct tresp_sim_enable_facility en_facility = {0, };
2313 int attempts_left = 0;
2314 int time_penalty = 0;
2316 dbg(" Function entry ");
2318 co_sim = tcore_pending_ref_core_object(p);
2319 sp = tcore_sim_ref_userdata(co_sim);
2320 ur = tcore_pending_ref_user_request(p);
2322 if (resp->success > 0) {
2325 line = (const char *) resp->lines->data;
2326 tokens = tcore_at_tok_new(line);
2327 if (g_slist_length(tokens) != 3) {
2328 msg("invalid message");
2329 tcore_at_tok_free(tokens);
2333 lock_type = atoi(g_slist_nth_data(tokens, 0));
2334 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2335 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2337 switch (sp->current_sec_op) {
2338 case SEC_PIN1_VERIFY:
2339 case SEC_PIN2_VERIFY:
2340 case SEC_SIM_VERIFY:
2341 case SEC_ADM_VERIFY:
2342 v_pin.result = SIM_INCORRECT_PASSWORD;
2343 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2344 v_pin.retry_count = attempts_left;
2345 tcore_user_request_send_response(ur, _find_resp_command(ur),
2346 sizeof(struct tresp_sim_verify_pins), &v_pin);
2349 case SEC_PUK1_VERIFY:
2350 case SEC_PUK2_VERIFY:
2351 v_puk.result = SIM_INCORRECT_PASSWORD;
2352 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2353 v_puk.retry_count = attempts_left;
2354 tcore_user_request_send_response(ur, _find_resp_command(ur),
2355 sizeof(struct tresp_sim_verify_puks), &v_puk);
2358 case SEC_PIN1_CHANGE:
2359 case SEC_PIN2_CHANGE:
2360 change_pin.result = SIM_INCORRECT_PASSWORD;
2361 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2362 change_pin.retry_count = attempts_left;
2363 tcore_user_request_send_response(ur, _find_resp_command(ur),
2364 sizeof(struct tresp_sim_change_pins), &change_pin);
2367 case SEC_PIN1_DISABLE:
2368 case SEC_PIN2_DISABLE:
2369 case SEC_FDN_DISABLE:
2370 case SEC_SIM_DISABLE:
2371 case SEC_NET_DISABLE:
2372 case SEC_NS_DISABLE:
2373 case SEC_SP_DISABLE:
2374 case SEC_CP_DISABLE:
2375 dis_facility.result = SIM_INCORRECT_PASSWORD;
2376 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2377 dis_facility.retry_count = attempts_left;
2378 tcore_user_request_send_response(ur, _find_resp_command(ur),
2379 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2382 case SEC_PIN1_ENABLE:
2383 case SEC_PIN2_ENABLE:
2384 case SEC_FDN_ENABLE:
2385 case SEC_SIM_ENABLE:
2386 case SEC_NET_ENABLE:
2390 en_facility.result = SIM_INCORRECT_PASSWORD;
2391 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2392 en_facility.retry_count = attempts_left;
2393 tcore_user_request_send_response(ur, _find_resp_command(ur),
2394 sizeof(struct tresp_sim_enable_facility), &en_facility);
2398 dbg("not handled sec op[%d]", sp->current_sec_op);
2401 tcore_at_tok_free(tokens);
2403 dbg(" Function exit");
2406 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2408 const TcoreATResponse *resp = data;
2409 UserRequest *ur = NULL;
2410 CoreObject *co_sim = NULL;
2411 struct tresp_sim_set_data resp_cf = {0, };
2412 struct tresp_sim_set_data resp_language = {0, };
2413 struct s_sim_property *sp = NULL;
2414 GSList *tokens = NULL;
2415 enum tel_sim_access_result result = SIM_CARD_ERROR;
2420 dbg(" Function entry ");
2422 co_sim = tcore_pending_ref_core_object(p);
2423 ur = tcore_pending_ref_user_request(p);
2424 sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
2426 if (resp->success > 0) {
2429 line = (const char *) resp->lines->data;
2430 tokens = tcore_at_tok_new(line);
2431 if (g_slist_length(tokens) != 2) {
2432 msg("invalid message");
2436 sw1 = atoi(g_slist_nth_data(tokens, 0));
2437 sw2 = atoi(g_slist_nth_data(tokens, 1));
2439 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2440 result = SIM_ACCESS_SUCCESS;
2442 result = _decode_status_word(sw1, sw2);
2445 dbg("RESPONSE NOK");
2446 result = SIM_ACCESS_FAILED;
2449 switch (sp->file_id) {
2450 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2451 case SIM_EF_USIM_CFIS:
2452 resp_cf.result = result;
2453 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_cf);
2458 case SIM_EF_USIM_LI:
2459 case SIM_EF_USIM_PL:
2460 resp_language.result = result;
2461 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_language);
2465 dbg("Invalid File ID - %d", sp->file_id)
2468 tcore_at_tok_free(tokens);
2469 dbg(" Function exit");
2472 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2474 const TcoreATResponse *resp = data;
2475 UserRequest *ur = NULL;
2476 CoreObject *co_sim = NULL;
2477 GSList *tokens = NULL;
2478 struct tresp_sim_transmit_apdu res;
2481 dbg(" Function entry ");
2483 co_sim = tcore_pending_ref_core_object(p);
2484 ur = tcore_pending_ref_user_request(p);
2486 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2487 res.result = SIM_ACCESS_FAILED;
2489 if (resp->success > 0) {
2493 char *decoded_data = NULL;
2494 line = (const char *) resp->lines->data;
2495 tokens = tcore_at_tok_new(line);
2496 if (g_slist_length(tokens) != 2) {
2497 msg("invalid message");
2500 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
2502 tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
2503 decoded_data = util_hexStringToBytes(tmp);
2505 memcpy((char *) res.apdu_resp, decoded_data, res.apdu_resp_length);
2508 res.result = SIM_ACCESS_SUCCESS;
2511 dbg("RESPONSE NOK");
2515 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
2517 tcore_at_tok_free(tokens);
2518 dbg(" Function exit");
2521 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
2523 const TcoreATResponse *resp = data;
2524 UserRequest *ur = NULL;
2525 GSList *tokens = NULL;
2526 struct tresp_sim_get_atr res;
2529 dbg(" Function entry ");
2531 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
2532 ur = tcore_pending_ref_user_request(p);
2534 res.result = SIM_ACCESS_FAILED;
2535 if (resp->success > 0) {
2539 char *decoded_data = NULL;
2540 line = (const char *) resp->lines->data;
2541 tokens = tcore_at_tok_new(line);
2542 if (g_slist_length(tokens) < 1) {
2543 msg("invalid message");
2547 tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
2548 decoded_data = util_hexStringToBytes(tmp);
2550 res.atr_length = strlen(decoded_data);
2551 memcpy((char *) res.atr, decoded_data, res.atr_length);
2554 res.result = SIM_ACCESS_SUCCESS;
2557 dbg("RESPONSE NOK");
2562 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_get_atr), &res);
2564 tcore_at_tok_free(tokens);
2565 dbg(" Function exit");
2568 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2570 TcoreHal *hal = NULL;
2571 TcoreATRequest *req = NULL;
2572 TcorePending *pending = NULL;
2573 char *cmd_str = NULL;
2574 const struct treq_sim_verify_pins *req_data = NULL;
2575 struct s_sim_property *sp = NULL;
2576 TReturn ret = TCORE_RETURN_FAILURE;
2578 dbg(" Function entry ");
2581 return TCORE_RETURN_EINVAL;
2583 hal = tcore_object_get_hal(o);
2584 if(FALSE == tcore_hal_get_power_state(hal)){
2585 dbg("cp not ready/n");
2586 return TCORE_RETURN_ENOSYS;
2589 sp = tcore_sim_ref_userdata(o);
2590 pending = tcore_pending_new(o, 0);
2591 req_data = tcore_user_request_ref_data(ur, NULL);
2593 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2594 sp->current_sec_op = SEC_PIN1_VERIFY;
2595 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2596 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2597 sp->current_sec_op = SEC_PIN2_VERIFY;
2598 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
2599 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
2600 sp->current_sec_op = SEC_SIM_VERIFY;
2601 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2602 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
2603 sp->current_sec_op = SEC_ADM_VERIFY;
2604 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2606 return TCORE_RETURN_EINVAL;
2609 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2611 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2613 tcore_pending_set_request_data(pending, 0, req);
2614 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
2615 tcore_pending_link_user_request(pending, ur);
2616 ret = tcore_hal_send_request(hal, pending);
2619 dbg(" Function exit");
2623 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2625 TcoreHal *hal = NULL;
2626 TcoreATRequest *req = NULL;
2627 TcorePending *pending = NULL;
2628 char *cmd_str = NULL;
2629 const struct treq_sim_verify_puks *req_data;
2630 struct s_sim_property *sp = NULL;
2631 TReturn ret = TCORE_RETURN_FAILURE;
2633 dbg(" Function entry ");
2636 return TCORE_RETURN_EINVAL;
2638 hal = tcore_object_get_hal(o);
2639 if(FALSE == tcore_hal_get_power_state(hal)){
2640 dbg("cp not ready/n");
2641 return TCORE_RETURN_ENOSYS;
2644 sp = tcore_sim_ref_userdata(o);
2645 pending = tcore_pending_new(o, 0);
2646 req_data = tcore_user_request_ref_data(ur, NULL);
2648 if (req_data->puk_type == SIM_PTYPE_PUK1) {
2649 sp->current_sec_op = SEC_PUK1_VERIFY;
2650 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2651 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
2652 sp->current_sec_op = SEC_PUK2_VERIFY;
2653 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2655 return TCORE_RETURN_EINVAL;
2657 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2659 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2661 tcore_pending_set_request_data(pending, 0, req);
2662 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
2663 tcore_pending_link_user_request(pending, ur);
2664 ret = tcore_hal_send_request(hal, pending);
2667 dbg(" Function exit");
2671 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2673 TcoreHal *hal = NULL;
2674 TcoreATRequest *req = NULL;
2675 TcorePending *pending = NULL;
2676 char *cmd_str = NULL;
2677 const struct treq_sim_change_pins *req_data;
2678 struct s_sim_property *sp = NULL;
2681 TReturn ret = TCORE_RETURN_FAILURE;
2683 dbg(" Function entry ");
2686 return TCORE_RETURN_EINVAL;
2688 hal = tcore_object_get_hal(o);
2689 if(FALSE == tcore_hal_get_power_state(hal)){
2690 dbg("cp not ready/n");
2691 return TCORE_RETURN_ENOSYS;
2694 sp = tcore_sim_ref_userdata(o);
2695 pending = tcore_pending_new(o, 0);
2696 req_data = tcore_user_request_ref_data(ur, NULL);
2698 if (req_data->type == SIM_PTYPE_PIN1) {
2699 sp->current_sec_op = SEC_PIN1_CHANGE;
2700 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
2701 } else if (req_data->type == SIM_PTYPE_PIN2) {
2702 sp->current_sec_op = SEC_PIN2_CHANGE;
2703 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
2705 return TCORE_RETURN_EINVAL;
2707 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2709 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2711 tcore_pending_set_request_data(pending, 0, req);
2712 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
2713 tcore_pending_link_user_request(pending, ur);
2714 ret = tcore_hal_send_request(hal, pending);
2717 dbg(" Function exit");
2721 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2723 TcoreHal *hal = NULL;
2724 TcoreATRequest *req = NULL;
2725 TcorePending *pending = NULL;
2726 char *cmd_str = NULL;
2727 const struct treq_sim_get_facility_status *req_data;
2729 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
2730 TReturn ret = TCORE_RETURN_FAILURE;
2732 dbg(" Function entry ");
2735 return TCORE_RETURN_EINVAL;
2737 hal = tcore_object_get_hal(o);
2738 if(FALSE == tcore_hal_get_power_state(hal)){
2739 dbg("cp not ready/n");
2740 return TCORE_RETURN_ENOSYS;
2743 pending = tcore_pending_new(o, 0);
2744 req_data = tcore_user_request_ref_data(ur, NULL);
2746 if (req_data->type == SIM_FACILITY_PS) {
2747 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2748 } else if (req_data->type == SIM_FACILITY_SC) {
2749 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2750 } else if (req_data->type == SIM_FACILITY_FD) {
2751 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2752 } else if (req_data->type == SIM_FACILITY_PN) {
2753 fac = "PN"; /*Network Personalization*/
2754 } else if (req_data->type == SIM_FACILITY_PU) {
2755 fac = "PU"; /*network sUbset Personalization*/
2756 } else if (req_data->type == SIM_FACILITY_PP) {
2757 fac = "PP"; /*service Provider Personalization*/
2758 } else if (req_data->type == SIM_FACILITY_PC) {
2759 fac = "PC"; /*Corporate Personalization*/
2761 return TCORE_RETURN_EINVAL;
2763 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
2764 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2766 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2768 tcore_pending_set_request_data(pending, 0, req);
2769 tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
2770 tcore_pending_link_user_request(pending, ur);
2771 ret = tcore_hal_send_request(hal, pending);
2774 dbg(" Function exit");
2778 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2780 TcoreHal *hal = NULL;
2781 TcoreATRequest *req = NULL;
2782 TcorePending *pending = NULL;
2783 char *cmd_str = NULL;
2784 const struct treq_sim_enable_facility *req_data;
2785 struct s_sim_property *sp = NULL;
2787 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
2788 TReturn ret = TCORE_RETURN_FAILURE;
2790 dbg(" Function entry ");
2793 return TCORE_RETURN_EINVAL;
2795 hal = tcore_object_get_hal(o);
2796 if(FALSE == tcore_hal_get_power_state(hal)){
2797 dbg("cp not ready/n");
2798 return TCORE_RETURN_ENOSYS;
2801 sp = tcore_sim_ref_userdata(o);
2802 pending = tcore_pending_new(o, 0);
2803 req_data = tcore_user_request_ref_data(ur, NULL);
2805 if (req_data->type == SIM_FACILITY_PS) {
2806 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2807 sp->current_sec_op = SEC_SIM_ENABLE;
2808 } else if (req_data->type == SIM_FACILITY_SC) {
2809 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2810 sp->current_sec_op = SEC_PIN1_ENABLE;
2811 } else if (req_data->type == SIM_FACILITY_FD) {
2812 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2813 sp->current_sec_op = SEC_FDN_ENABLE;
2814 } else if (req_data->type == SIM_FACILITY_PN) {
2815 fac = "PN"; /*Network Personalization*/
2816 sp->current_sec_op = SEC_NET_ENABLE;
2817 } else if (req_data->type == SIM_FACILITY_PU) {
2818 fac = "PU"; /*network sUbset Personalization*/
2819 sp->current_sec_op = SEC_NS_ENABLE;
2820 } else if (req_data->type == SIM_FACILITY_PP) {
2821 fac = "PP"; /*service Provider Personalization*/
2822 sp->current_sec_op = SEC_SP_ENABLE;
2823 } else if (req_data->type == SIM_FACILITY_PC) {
2824 fac = "PC"; /*Corporate Personalization*/
2825 sp->current_sec_op = SEC_CP_ENABLE;
2827 return TCORE_RETURN_EINVAL;
2829 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2830 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2832 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2834 tcore_pending_set_request_data(pending, 0, req);
2835 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
2836 tcore_pending_link_user_request(pending, ur);
2837 ret = tcore_hal_send_request(hal, pending);
2840 dbg(" Function exit");
2844 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2847 TcoreATRequest *req;
2848 TcorePending *pending = NULL;
2849 char *cmd_str = NULL;
2850 const struct treq_sim_enable_facility *req_data;
2851 struct s_sim_property *sp = NULL;
2853 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
2854 TReturn ret = TCORE_RETURN_FAILURE;
2856 dbg(" Function entry ");
2859 return TCORE_RETURN_EINVAL;
2861 hal = tcore_object_get_hal(o);
2862 if(FALSE == tcore_hal_get_power_state(hal)){
2863 dbg("cp not ready/n");
2864 return TCORE_RETURN_ENOSYS;
2867 sp = tcore_sim_ref_userdata(o);
2868 pending = tcore_pending_new(o, 0);
2869 req_data = tcore_user_request_ref_data(ur, NULL);
2871 if (req_data->type == SIM_FACILITY_PS) {
2872 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2873 sp->current_sec_op = SEC_SIM_DISABLE;
2874 } else if (req_data->type == SIM_FACILITY_SC) {
2875 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2876 sp->current_sec_op = SEC_PIN1_DISABLE;
2877 } else if (req_data->type == SIM_FACILITY_FD) {
2878 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2879 sp->current_sec_op = SEC_FDN_DISABLE;
2880 } else if (req_data->type == SIM_FACILITY_PN) {
2881 fac = "PN"; /*Network Personalization*/
2882 sp->current_sec_op = SEC_NET_DISABLE;
2883 } else if (req_data->type == SIM_FACILITY_PU) {
2884 fac = "PU"; /*network sUbset Personalization*/
2885 sp->current_sec_op = SEC_NS_DISABLE;
2886 } else if (req_data->type == SIM_FACILITY_PP) {
2887 fac = "PP"; /*service Provider Personalization*/
2888 sp->current_sec_op = SEC_SP_DISABLE;
2889 } else if (req_data->type == SIM_FACILITY_PC) {
2890 fac = "PC"; /*Corporate Personalization*/
2891 sp->current_sec_op = SEC_CP_DISABLE;
2893 return TCORE_RETURN_EINVAL;
2895 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2896 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2898 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2900 tcore_pending_set_request_data(pending, 0, req);
2901 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
2902 tcore_pending_link_user_request(pending, ur);
2903 ret = tcore_hal_send_request(hal, pending);
2906 dbg(" Function exit");
2910 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
2912 TcoreHal *hal = NULL;
2913 TcoreATRequest *req = NULL;
2914 TcorePending *pending = NULL;
2915 char *cmd_str = NULL;
2916 char *lock_type = NULL;
2917 const struct treq_sim_get_lock_info *req_data;
2918 TReturn ret = TCORE_RETURN_FAILURE;
2920 dbg(" Function entry ");
2923 return TCORE_RETURN_EINVAL;
2925 hal = tcore_object_get_hal(o);
2926 if(FALSE == tcore_hal_get_power_state(hal)){
2927 dbg("cp not ready/n");
2928 return TCORE_RETURN_ENOSYS;
2930 pending = tcore_pending_new(o, 0);
2931 req_data = tcore_user_request_ref_data(ur, NULL);
2933 switch (req_data->type) {
2934 case SIM_FACILITY_PS:
2938 case SIM_FACILITY_SC:
2942 case SIM_FACILITY_FD:
2946 case SIM_FACILITY_PN:
2950 case SIM_FACILITY_PU:
2954 case SIM_FACILITY_PP:
2958 case SIM_FACILITY_PC:
2965 cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
2966 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2968 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2970 tcore_pending_set_request_data(pending, 0, req);
2971 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
2972 tcore_pending_link_user_request(pending, ur);
2973 ret = tcore_hal_send_request(hal, pending);
2976 dbg(" Function exit");
2980 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
2982 TReturn api_ret = TCORE_RETURN_SUCCESS;
2983 enum tcore_request_command command;
2985 dbg(" Function entry ");
2988 return TCORE_RETURN_EINVAL;
2990 command = tcore_user_request_get_command(ur);
2991 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2992 dbg("cp not ready/n");
2993 return TCORE_RETURN_ENOSYS;
2997 case TREQ_SIM_GET_ECC:
2998 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
3001 case TREQ_SIM_GET_LANGUAGE:
3002 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
3003 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
3004 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
3005 api_ret = _get_file_info(o, ur, SIM_EF_LP);
3007 api_ret = TCORE_RETURN_ENOSYS;
3010 case TREQ_SIM_GET_ICCID:
3011 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
3014 case TREQ_SIM_GET_MAILBOX:
3015 if (tcore_sim_get_cphs_status(o))
3016 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3018 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
3021 case TREQ_SIM_GET_CALLFORWARDING:
3022 if (tcore_sim_get_cphs_status(o))
3023 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3025 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3028 case TREQ_SIM_GET_MESSAGEWAITING:
3029 if (tcore_sim_get_cphs_status(o))
3030 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3032 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3035 case TREQ_SIM_GET_CPHS_INFO:
3036 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3039 case TREQ_SIM_GET_MSISDN:
3040 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3043 case TREQ_SIM_GET_SPN:
3044 dbg("enter case SPN");
3045 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3048 case TREQ_SIM_GET_SPDI:
3049 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3052 case TREQ_SIM_GET_OPL:
3053 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3056 case TREQ_SIM_GET_PNN:
3057 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3060 case TREQ_SIM_GET_CPHS_NETNAME:
3061 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3064 case TREQ_SIM_GET_OPLMNWACT:
3065 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3069 dbg("error - not handled read treq command[%d]", command);
3070 api_ret = TCORE_RETURN_EINVAL;
3073 dbg(" Function exit");
3077 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
3080 TcoreATRequest *req;
3081 TcorePending *pending = NULL;
3082 char *cmd_str = NULL;
3083 TReturn ret = TCORE_RETURN_SUCCESS;
3084 char *encoded_data = NULL;
3085 int encoded_len = 0;
3086 enum tcore_request_command command;
3087 enum tel_sim_file_id ef = SIM_EF_INVALID;
3088 const struct treq_sim_set_callforwarding *cf;
3089 const struct treq_sim_set_language *cl;
3090 struct s_sim_property file_meta = {0, };
3097 struct tel_sim_language sim_language;
3101 command = tcore_user_request_get_command(ur);
3103 dbg(" Function entry ");
3106 return TCORE_RETURN_EINVAL;
3109 hal = tcore_object_get_hal(o);
3110 if(FALSE == tcore_hal_get_power_state(hal)){
3111 dbg("cp not ready/n");
3112 return TCORE_RETURN_ENOSYS;
3115 pending = tcore_pending_new(o, 0);
3118 case TREQ_SIM_SET_LANGUAGE:
3119 cl = tcore_user_request_ref_data(ur, NULL);
3120 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
3123 sim_language.language_count = 1;
3124 sim_language.language[0] = cl->language;
3125 dbg("language %d", cl->language);
3127 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
3130 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
3132 encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
3133 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
3134 result = util_byte_to_hex(tmp, encoded_data, out_length);
3139 dbg("encoded_data - %s ---", encoded_data);
3140 dbg("out_length - %d ---", out_length);
3141 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
3144 tmp = tcore_sim_encode_li(&out_length, &sim_language);
3146 encoded_data = (char *) malloc(2 * (out_length) + 1);
3147 memset(encoded_data, 0x00, (2 * out_length) + 1);
3148 result = util_byte_to_hex(tmp, encoded_data, out_length);
3153 dbg("encoded_data - %s ---", encoded_data);
3154 dbg("out_length - %d ---", out_length);
3156 ret = TCORE_RETURN_ENOSYS;
3160 case TREQ_SIM_SET_CALLFORWARDING:
3161 cf = tcore_user_request_ref_data(ur, NULL);
3162 if (tcore_sim_get_cphs_status(o)) {
3163 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
3164 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
3168 encoded_data = (char *) malloc(2 * (p3) + 1);
3169 memset(encoded_data, 0x00, (2 *p3) + 1);
3170 result = util_byte_to_hex(tmp, encoded_data, p3);
3171 cmd = 214; /*command - 214 : UPDATE BINARY*/
3173 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
3174 ef = SIM_EF_USIM_CFIS;
3178 encoded_data = (char *) malloc(2 * (encoded_len) + 1);
3179 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
3180 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3181 cmd = 220; /*command - 220 : UPDATE RECORD*/
3186 dbg("error - not handled update treq command[%d]", command);
3187 ret = TCORE_RETURN_EINVAL;
3190 file_meta.file_id = ef;
3191 dbg("file_meta.file_id: %d", file_meta.file_id);
3193 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
3194 dbg("trt[%d]", trt);
3196 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3197 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3199 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3201 tcore_pending_set_request_data(pending, 0, req);
3202 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
3203 tcore_pending_link_user_request(pending, ur);
3204 ret = tcore_hal_send_request(hal, pending);
3206 if (NULL != encoded_data) {
3207 g_free(encoded_data);
3215 dbg(" Function exit");
3219 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3221 TcoreHal *hal = NULL;
3222 TcoreATRequest *req = NULL;
3223 TcorePending *pending = NULL;
3224 char *cmd_str = NULL;
3228 const struct treq_sim_transmit_apdu *req_data;
3229 TReturn ret = TCORE_RETURN_FAILURE;
3231 dbg(" Function entry ");
3234 return TCORE_RETURN_EINVAL;
3236 hal = tcore_object_get_hal(o);
3237 if(FALSE == tcore_hal_get_power_state(hal)){
3238 dbg("cp not ready/n");
3239 return TCORE_RETURN_ENOSYS;
3242 pending = tcore_pending_new(o, 0);
3243 req_data = tcore_user_request_ref_data(ur, NULL);
3245 apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
3246 memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
3247 result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
3248 apdu_len = strlen(apdu);
3249 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", apdu_len, apdu);
3250 req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
3251 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3253 tcore_pending_set_request_data(pending, 0, req);
3254 tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
3255 tcore_pending_link_user_request(pending, ur);
3256 ret = tcore_hal_send_request(hal, pending);
3260 dbg(" Function exit");
3264 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
3266 TcoreHal *hal = NULL;
3267 TcoreATRequest *req = NULL;
3268 TcorePending *pending = NULL;
3269 char *cmd_str = NULL;
3270 TReturn ret = TCORE_RETURN_FAILURE;
3272 dbg(" Function entry ");
3275 return TCORE_RETURN_EINVAL;
3277 hal = tcore_object_get_hal(o);
3278 if(FALSE == tcore_hal_get_power_state(hal)) {
3279 dbg("cp not ready/n");
3280 return TCORE_RETURN_ENOSYS;
3282 pending = tcore_pending_new(o, 0);
3284 cmd_str = g_strdup_printf("AT+XGATR");
3285 req = tcore_at_request_new(cmd_str, "+XGATR:", TCORE_AT_SINGLELINE);
3286 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3288 tcore_pending_set_request_data(pending, 0, req);
3289 tcore_pending_set_response_callback(pending, on_response_get_atr, hal);
3290 tcore_pending_link_user_request(pending, ur);
3291 ret = tcore_hal_send_request(hal, pending);
3294 dbg(" Function exit");
3298 static struct tcore_sim_operations sim_ops = {
3299 .verify_pins = s_verify_pins,
3300 .verify_puks = s_verify_puks,
3301 .change_pins = s_change_pins,
3302 .get_facility_status = s_get_facility_status,
3303 .enable_facility = s_enable_facility,
3304 .disable_facility = s_disable_facility,
3305 .get_lock_info = s_get_lock_info,
3306 .read_file = s_read_file,
3307 .update_file = s_update_file,
3308 .transmit_apdu = s_transmit_apdu,
3309 .get_atr = s_get_atr,
3310 .req_authentication = NULL,
3313 gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
3316 struct s_sim_property *file_meta = NULL;
3321 o = tcore_sim_new(p, "sim", &sim_ops, h);
3326 file_meta = calloc(sizeof(struct s_sim_property), 1);
3330 work_queue = g_queue_new();
3331 tcore_object_link_user_data(o, work_queue);
3333 file_meta->first_recv_status = SIM_STATUS_UNKNOWN;
3334 tcore_sim_link_userdata(o, file_meta);
3336 tcore_object_add_callback(o, "+XLOCK", on_event_facility_lock_status, NULL);
3337 tcore_object_add_callback(o, "+XSIM", on_event_pin_status, NULL);
3343 void s_sim_exit(TcorePlugin *p)
3347 o = tcore_plugin_ref_core_object(p, "sim");