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 static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
116 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
118 static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data)
120 dbg("on_confirmation_sim_message_send - msg out from queue.\n");
122 if (result == FALSE) {
130 static enum tcore_response_command _find_resp_command(UserRequest *ur)
132 enum tcore_request_command command;
134 command = tcore_user_request_get_command(ur);
136 case TREQ_SIM_VERIFY_PINS:
137 return TRESP_SIM_VERIFY_PINS;
140 case TREQ_SIM_VERIFY_PUKS:
141 return TRESP_SIM_VERIFY_PUKS;
144 case TREQ_SIM_CHANGE_PINS:
145 return TRESP_SIM_CHANGE_PINS;
148 case TREQ_SIM_GET_FACILITY_STATUS:
149 return TRESP_SIM_GET_FACILITY_STATUS;
152 case TREQ_SIM_DISABLE_FACILITY:
153 return TRESP_SIM_DISABLE_FACILITY;
156 case TREQ_SIM_ENABLE_FACILITY:
157 return TRESP_SIM_ENABLE_FACILITY;
160 case TREQ_SIM_GET_LOCK_INFO:
161 return TRESP_SIM_GET_LOCK_INFO;
164 case TREQ_SIM_TRANSMIT_APDU:
165 return TRESP_SIM_TRANSMIT_APDU;
168 case TREQ_SIM_GET_ATR:
169 return TRESP_SIM_GET_ATR;
172 case TREQ_SIM_GET_ECC:
173 return TRESP_SIM_GET_ECC;
176 case TREQ_SIM_GET_LANGUAGE:
177 return TRESP_SIM_GET_LANGUAGE;
180 case TREQ_SIM_SET_LANGUAGE:
181 return TRESP_SIM_SET_LANGUAGE;
184 case TREQ_SIM_GET_ICCID:
185 return TRESP_SIM_GET_ICCID;
188 case TREQ_SIM_GET_MAILBOX:
189 return TRESP_SIM_GET_MAILBOX;
192 case TREQ_SIM_GET_CALLFORWARDING:
193 return TRESP_SIM_GET_CALLFORWARDING;
196 case TREQ_SIM_SET_CALLFORWARDING:
197 return TRESP_SIM_SET_CALLFORWARDING;
200 case TREQ_SIM_GET_MESSAGEWAITING:
201 return TRESP_SIM_GET_MESSAGEWAITING;
204 case TREQ_SIM_GET_CPHS_INFO:
205 return TRESP_SIM_GET_CPHS_INFO;
208 case TREQ_SIM_GET_MSISDN:
209 return TRESP_SIM_GET_MSISDN;
212 case TREQ_SIM_GET_SPN:
213 return TRESP_SIM_GET_SPN;
216 case TREQ_SIM_GET_SPDI:
217 return TRESP_SIM_GET_SPDI;
220 case TREQ_SIM_GET_OPL:
221 return TRESP_SIM_GET_OPL;
224 case TREQ_SIM_GET_PNN:
225 return TRESP_SIM_GET_PNN;
228 case TREQ_SIM_GET_CPHS_NETNAME:
229 return TRESP_SIM_GET_CPHS_NETNAME;
232 case TREQ_SIM_GET_OPLMNWACT:
233 return TRESP_SIM_GET_OPLMNWACT;
236 case TREQ_SIM_REQ_AUTHENTICATION:
237 return TRESP_SIM_REQ_AUTHENTICATION;
243 return TRESP_UNKNOWN;
246 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
250 dbg("current sec_op[%d]", op);
253 case SEC_PIN1_VERIFY:
254 case SEC_PIN1_CHANGE:
255 ret_type = SIM_PTYPE_PIN1;
258 case SEC_PIN2_VERIFY:
259 case SEC_PIN2_CHANGE:
260 ret_type = SIM_PTYPE_PIN2;
263 case SEC_PUK1_VERIFY:
264 ret_type = SIM_PTYPE_PUK1;
267 case SEC_PUK2_VERIFY:
268 ret_type = SIM_PTYPE_PUK2;
272 ret_type = SIM_PTYPE_SIM;
276 ret_type = SIM_PTYPE_ADM;
279 case SEC_PIN1_ENABLE:
280 case SEC_PIN1_DISABLE:
281 case SEC_PIN1_STATUS:
282 ret_type = SIM_FACILITY_SC;
286 case SEC_SIM_DISABLE:
288 ret_type = SIM_FACILITY_PS;
292 case SEC_NET_DISABLE:
294 ret_type = SIM_FACILITY_PN;
300 ret_type = SIM_FACILITY_PU;
306 ret_type = SIM_FACILITY_PP;
312 ret_type = SIM_FACILITY_PC;
316 case SEC_FDN_DISABLE:
318 ret_type = SIM_FACILITY_FD;
322 dbg("not handled current sec op[%d]", op)
328 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
330 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
332 if (status_word1 == 0x93 && status_word2 == 0x00) {
333 rst = SIM_ACCESS_FAILED;
334 /*Failed SIM request command*/
335 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
336 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
337 rst = SIM_ACCESS_FAILED;
338 /*Failed SIM request command*/
339 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
340 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
341 rst = SIM_ACCESS_FAILED;
342 /*Failed SIM request command*/
343 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
344 status_word1, status_word2);
345 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
346 rst = SIM_ACCESS_FILE_NOT_FOUND;
347 /*Failed SIM request command*/
348 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
349 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
350 rst = SIM_ACCESS_FAILED; /* MOdem not support */
351 /*Failed SIM request command*/
352 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
353 status_word1, status_word2);
354 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
355 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
356 /*Failed SIM request command*/
357 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
358 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
359 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
360 /*Failed SIM request command*/
361 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
362 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
363 status_word1, status_word2);
364 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
365 status_word1, status_word2);
366 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
367 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
368 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
369 /*Failed SIM request command*/
370 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
371 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
372 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
373 /*Failed SIM request command*/
374 dbg(" error - Contradiction with invalidation status [%x][%x]",
375 status_word1, status_word2);
376 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
377 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
378 /*Failed SIM request command*/
379 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
380 status_word1, status_word2);
381 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
382 status_word1, status_word2);
383 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
384 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
385 rst = SIM_ACCESS_FAILED;
386 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
387 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
388 rst = SIM_ACCESS_FAILED;
389 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
390 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
391 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
392 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
393 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
394 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
395 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
396 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
397 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
398 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
399 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
400 rst = SIM_ACCESS_FAILED;
401 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
402 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
403 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
404 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
405 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
406 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
407 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
409 rst = SIM_ACCESS_CARD_ERROR;
410 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
415 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
418 Storage *strg = NULL;
419 char *old_imsi = NULL;
420 char new_imsi[15 + 1] = {0, };
422 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
424 dbg("there is no valid server at this point");
427 strg = (Storage *) tcore_server_find_storage(s, "vconf");
429 dbg("there is no valid storage plugin");
432 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
433 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
434 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
436 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
437 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
439 if (old_imsi != NULL) {
440 if (strncmp(old_imsi, new_imsi, 15) != 0) {
442 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
443 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
445 tcore_sim_set_identification(o, TRUE);
448 tcore_sim_set_identification(o, FALSE);
451 dbg("OLD SIM VALUE IS NULL. NEW SIM");
452 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
453 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
455 tcore_sim_set_identification(o, TRUE);
460 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
462 struct tresp_sim_read resp = {0, };
463 struct s_sim_property *file_meta = NULL;
465 dbg("EF[0x%x] access Result[%d]", ef, rt);
468 memset(&resp.data, 0x00, sizeof(resp.data));
469 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
471 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
472 && (rt != SIM_ACCESS_SUCCESS)) {
473 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
479 if (rt == SIM_ACCESS_SUCCESS) {
480 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
481 /* if (po->language_file == 0x00)
482 po->language_file = SIM_EF_ELP;*/
483 _get_file_data(o, ur, ef, 0, file_meta->data_size);
485 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
486 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
487 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
488 _get_file_info(o, ur, SIM_EF_LP);
489 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
491 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
492 /* EFELPand EFLI not present at this point. */
493 /* po->language.lang_cnt = 0;*/
494 tcore_user_request_send_response(ur, _find_resp_command(ur),
495 sizeof(struct tresp_sim_read), &resp);
501 case SIM_EF_LP: // same with SIM_EF_USIM_LI
502 if (rt == SIM_ACCESS_SUCCESS) {
503 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
504 _get_file_data(o, ur, ef, 0, file_meta->data_size);
506 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
507 tcore_sim_get_type(o));
508 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
509 tcore_user_request_send_response(ur, _find_resp_command(ur),
510 sizeof(struct tresp_sim_read), &resp);
513 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
514 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
515 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
516 _get_file_info(o, ur, SIM_EF_ELP);
522 if (rt == SIM_ACCESS_SUCCESS) {
523 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
524 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
526 /* EFELIand EFPL not present, so set language count as zero and select ECC */
528 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
529 tcore_user_request_send_response(ur, _find_resp_command(ur),
530 sizeof(struct tresp_sim_read), &resp);
536 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
537 _get_file_data(o, ur, ef, 0, file_meta->data_size);
538 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
539 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
540 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
543 file_meta->current_index++;
544 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
553 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
554 case SIM_EF_CPHS_VOICE_MSG_WAITING:
555 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
556 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
557 case SIM_EF_CPHS_DYNAMICFLAGS:
558 case SIM_EF_CPHS_DYNAMIC2FLAG:
559 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
560 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
561 _get_file_data(o, ur, ef, 0, file_meta->data_size);
564 case SIM_EF_CPHS_CPHS_INFO:
565 if (rt == SIM_ACCESS_SUCCESS) {
566 tcore_sim_set_cphs_status(o, TRUE);
567 if (!tcore_user_request_ref_communicator(ur)) {
568 dbg("internal CPHS INFO request before sim status update");
569 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
571 dbg("external CPHS INFO request");
572 _get_file_data(o, ur, ef, 0, file_meta->data_size);
575 tcore_sim_set_cphs_status(o, FALSE);
576 if (!tcore_user_request_ref_communicator(ur)) {
577 dbg("internal CPHS INFO request before sim status update");
578 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
580 dbg("external CPHS INFO request");
581 tcore_user_request_send_response(ur, _find_resp_command(ur),
582 sizeof(struct tresp_sim_read), &resp);
588 case SIM_EF_USIM_CFIS:
589 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
590 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
592 file_meta->current_index++;
593 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
598 case SIM_EF_USIM_MWIS:
599 case SIM_EF_USIM_MBI:
601 case SIM_EF_CPHS_MAILBOX_NUMBERS:
602 case SIM_EF_CPHS_INFORMATION_NUMBERS:
603 file_meta->current_index++;
604 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
608 dbg("error - File id for get file info [0x%x]", ef);
614 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
616 struct s_sim_property *file_meta = NULL;
620 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
621 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
622 switch (file_meta->file_id) {
627 if (decode_ret == TRUE) {
628 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
629 /* po->language_file = SIM_EF_LP;*/
630 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
631 /* po->language_file = SIM_EF_ELP;*/
633 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
636 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
637 - EFELP is not available;
638 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
639 - the ME does not support any of the languages in EFELP.
642 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
643 - if the EFLI has the value 'FFFF' in its highest priority position
644 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
646 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
647 if (file_meta->file_id == SIM_EF_LP) {
648 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
650 _get_file_info(o, ur, SIM_EF_LP);
652 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
653 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
654 _get_file_info(o, ur, SIM_EF_ELP);
656 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
663 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
664 if (file_meta->current_index == file_meta->rec_count) {
665 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
667 file_meta->current_index++;
668 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
670 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
671 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
673 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
678 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
679 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
683 if (file_meta->current_index == file_meta->rec_count) {
684 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
686 file_meta->current_index++;
687 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
692 if (file_meta->current_index == file_meta->rec_count) {
693 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
695 file_meta->current_index++;
696 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
701 if (file_meta->current_index == file_meta->rec_count) {
702 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
704 file_meta->current_index++;
705 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
709 case SIM_EF_USIM_CFIS:
710 case SIM_EF_USIM_MWIS:
711 case SIM_EF_USIM_MBI:
713 case SIM_EF_CPHS_MAILBOX_NUMBERS:
714 case SIM_EF_CPHS_INFORMATION_NUMBERS:
715 if (file_meta->current_index == file_meta->rec_count) {
716 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
718 file_meta->current_index++;
719 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
723 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
724 file_meta->files.result = rt;
725 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
726 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));
728 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
731 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
732 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
733 file_meta->files.result = SIM_ACCESS_SUCCESS;
735 if (strlen((char *) file_meta->files.data.cphs_net.full_name)) {
736 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));
738 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
745 case SIM_EF_OPLMN_ACT:
746 case SIM_EF_CPHS_CPHS_INFO:
747 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
748 case SIM_EF_CPHS_VOICE_MSG_WAITING:
749 case SIM_EF_CPHS_DYNAMICFLAGS:
750 case SIM_EF_CPHS_DYNAMIC2FLAG:
751 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
752 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
753 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
757 dbg("File id not handled [0x%x]", file_meta->file_id);
762 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
764 struct tnoti_sim_status noti_data = {0, };
766 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
767 tcore_sim_set_status(o, sim_status);
768 noti_data.sim_status = sim_status;
769 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
770 sizeof(struct tnoti_sim_status), ¬i_data);
773 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
775 const TcoreATResponse *resp = data;
776 UserRequest *ur = NULL;
777 CoreObject *co_sim = NULL;
778 struct s_sim_property *sp = NULL;
779 GSList *tokens = NULL;
780 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
784 dbg(" Function entry ");
786 co_sim = tcore_pending_ref_core_object(p);
787 sp = tcore_sim_ref_userdata(co_sim);
788 ur = tcore_pending_ref_user_request(p);
790 if (resp->success > 0) {
793 line = (const char *) resp->lines->data;
794 tokens = tcore_at_tok_new(line);
795 if (g_slist_length(tokens) != 1) {
796 msg("invalid message");
797 tcore_at_tok_free(tokens);
801 state = atoi(g_slist_nth_data(tokens, 0));
802 dbg("SIM Type is %d", state);
805 sim_type = SIM_TYPE_GSM;
806 } else if (state == 1) {
807 sim_type = SIM_TYPE_USIM;
809 sim_type = SIM_TYPE_UNKNOWN;
813 sim_type = SIM_TYPE_UNKNOWN;
816 tcore_sim_set_type(co_sim, sim_type);
817 _sim_status_update(co_sim, sp->first_recv_status);
818 tcore_at_tok_free(tokens);
819 dbg(" Function exit");
822 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
824 const TcoreATResponse *resp = data;
825 UserRequest *ur = NULL;
826 CoreObject *co_sim = NULL;
827 struct s_sim_property *file_meta = NULL;
828 GSList *tokens = NULL;
829 enum tel_sim_access_result rt;
830 const char *line = NULL;
834 dbg(" Function entry ");
836 co_sim = tcore_pending_ref_core_object(p);
837 ur = tcore_pending_ref_user_request(p);
838 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
840 if (resp->success > 0) {
843 line = (const char *) resp->lines->data;
844 tokens = tcore_at_tok_new(line);
845 if (g_slist_length(tokens) < 2) {
846 err("invalid message");
847 tcore_at_tok_free(tokens);
851 sw1 = atoi(g_slist_nth_data(tokens, 0));
852 sw2 = atoi(g_slist_nth_data(tokens, 1));
854 /*1. SIM access success case*/
855 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
856 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
857 unsigned short record_len = 0;
858 char num_of_records = 0;
859 unsigned char file_id_len = 0;
860 unsigned short file_id = 0;
861 unsigned short file_size = 0;
862 unsigned short file_type = 0;
863 unsigned short arr_file_id = 0;
864 int arr_file_id_rec_num = 0;
866 /* handling only last 3 bits */
867 unsigned char file_type_tag = 0x07;
868 unsigned char *ptr_data;
872 char *recordData = NULL;
873 hexData = g_slist_nth_data(tokens, 2);
874 dbg("hexData: %s", hexData);
875 dbg("hexData: %s", hexData + 1);
877 tmp = util_removeQuotes(hexData);
878 recordData = util_hexStringToBytes(tmp);
879 util_hex_dump(" ", strlen(hexData) / 2, recordData);
882 ptr_data = (unsigned char *) recordData;
883 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
885 ETSI TS 102 221 v7.9.0
887 '62' FCP template tag
889 '82' M File Descriptor
890 '83' M File Identifier
891 'A5' O Proprietary information
892 '8A' M Life Cycle Status Integer
893 '8B', '8C' or 'AB' C1 Security attributes
895 '81' O Total file size
896 '88' O Short File Identifier (SFI)
899 /* rsim.res_len has complete data length received */
901 /* FCP template tag - File Control Parameters tag*/
902 if (*ptr_data == 0x62) {
903 /* parse complete FCP tag*/
904 /* increment to next byte */
906 tag_len = *ptr_data++;
907 dbg("tag_len: %02x", tag_len);
908 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
909 if (*ptr_data == 0x82) {
910 /* increment to next byte */
914 /* unsigned char file_desc_len = *ptr_data++;*/
915 /* dbg("file descriptor length: [%d]", file_desc_len);*/
916 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
917 /* consider only last 3 bits*/
918 dbg("file_type_tag: %02x", file_type_tag);
919 file_type_tag = file_type_tag & (*ptr_data);
920 dbg("file_type_tag: %02x", file_type_tag);
922 switch (file_type_tag) {
923 /* increment to next byte */
926 dbg("Getting FileType: [Transparent file type]");
927 file_type = SIM_FTYPE_TRANSPARENT;
929 /* increment to next byte */
931 /* increment to next byte */
936 dbg("Getting FileType: [Linear fixed file type]");
937 /* increment to next byte */
939 /* data coding byte - value 21 */
942 memcpy(&record_len, ptr_data, 2);
944 SWAPBYTES16(record_len);
945 ptr_data = ptr_data + 2;
946 num_of_records = *ptr_data++;
947 /* Data lossy conversation from enum (int) to unsigned char */
948 file_type = SIM_FTYPE_LINEAR_FIXED;
952 dbg(" Cyclic fixed file type");
953 /* increment to next byte */
955 /* data coding byte - value 21 */
958 memcpy(&record_len, ptr_data, 2);
960 SWAPBYTES16(record_len);
961 ptr_data = ptr_data + 2;
962 num_of_records = *ptr_data++;
963 file_type = SIM_FTYPE_CYCLIC;
967 dbg("not handled file type [0x%x]", *ptr_data);
971 dbg("INVALID FCP received - DEbug!");
972 tcore_at_tok_free(tokens);
977 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
978 if (*ptr_data == 0x83) {
979 /* increment to next byte */
981 file_id_len = *ptr_data++;
982 dbg("file_id_len: %02x", file_id_len);
984 memcpy(&file_id, ptr_data, file_id_len);
985 dbg("file_id: %x", file_id);
988 SWAPBYTES16(file_id);
989 dbg("file_id: %x", file_id);
991 ptr_data = ptr_data + 2;
992 dbg("Getting FileID=[0x%x]", file_id);
994 dbg("INVALID FCP received - DEbug!");
995 tcore_at_tok_free(tokens);
1000 /* proprietary information */
1001 if (*ptr_data == 0xA5) {
1002 unsigned short prop_len;
1003 /* increment to next byte */
1007 prop_len = *ptr_data;
1008 dbg("prop_len: %02x", prop_len);
1011 ptr_data = ptr_data + prop_len + 1;
1013 dbg("INVALID FCP received - DEbug!");
1016 /* life cycle status integer [8A][length:0x01][status]*/
1019 00000000 : No information given
1020 00000001 : creation state
1021 00000011 : initialization state
1022 000001-1 : operation state -activated
1023 000001-0 : operation state -deactivated
1024 000011-- : Termination state
1025 b8~b5 !=0, b4~b1=X : Proprietary
1026 Any other value : RFU
1028 if (*ptr_data == 0x8A) {
1029 /* increment to next byte */
1031 /* length - value 1 */
1034 switch (*ptr_data) {
1037 dbg("<RX> operation state -deactivated");
1043 dbg("<RX> operation state -activated");
1048 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1054 /* related to security attributes : currently not handled*/
1055 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1056 /* increment to next byte */
1058 /* if tag length is 3 */
1059 if (*ptr_data == 0x03) {
1060 /* increment to next byte */
1063 memcpy(&arr_file_id, ptr_data, 2);
1065 SWAPBYTES16(arr_file_id);
1066 ptr_data = ptr_data + 2;
1067 arr_file_id_rec_num = *ptr_data++;
1069 /* if tag length is not 3 */
1070 /* ignoring bytes */
1071 // ptr_data = ptr_data + 4;
1072 dbg("Useless security attributes, so jump to next tag");
1073 ptr_data = ptr_data + (*ptr_data + 1);
1076 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1077 tcore_at_tok_free(tokens);
1082 dbg("Current ptr_data value is [%x]", *ptr_data);
1084 /* file size excluding structural info*/
1085 if (*ptr_data == 0x80) {
1086 /* for EF file size is body of file and for Linear or cyclic it is
1087 * number of recXsizeof(one record)
1089 /* increment to next byte */
1091 /* length is 1 byte - value is 2 bytes or more */
1093 memcpy(&file_size, ptr_data, 2);
1095 SWAPBYTES16(file_size);
1096 ptr_data = ptr_data + 2;
1098 dbg("INVALID FCP received - DEbug!");
1099 tcore_at_tok_free(tokens);
1104 /* total file size including structural info*/
1105 if (*ptr_data == 0x81) {
1107 /* increment to next byte */
1112 ptr_data = ptr_data + 3;
1114 dbg("INVALID FCP received - DEbug!");
1115 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1118 /*short file identifier ignored*/
1119 if (*ptr_data == 0x88) {
1120 dbg("0x88: Do Nothing");
1124 dbg("INVALID FCP received - DEbug!");
1125 tcore_at_tok_free(tokens);
1129 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1130 unsigned char gsm_specific_file_data_len = 0;
1131 /* ignore RFU byte1 and byte2 */
1135 // file_size = p_info->response_len;
1136 memcpy(&file_size, ptr_data, 2);
1138 SWAPBYTES16(file_size);
1139 /* parsed file size */
1140 ptr_data = ptr_data + 2;
1142 memcpy(&file_id, ptr_data, 2);
1143 SWAPBYTES16(file_id);
1144 dbg(" FILE id --> [%x]", file_id);
1145 ptr_data = ptr_data + 2;
1146 /* save file type - transparent, linear fixed or cyclic */
1147 file_type_tag = (*(ptr_data + 7));
1149 switch (*ptr_data) {
1152 dbg(" RFU file type- not handled - Debug!");
1157 dbg(" MF file type - not handled - Debug!");
1162 dbg(" DF file type - not handled - Debug!");
1167 dbg(" EF file type [%d] ", file_type_tag);
1168 /* increment to next byte */
1171 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1172 /* increament to next byte as this byte is RFU */
1175 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1177 /* increment to next byte */
1179 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1180 /* the INCREASE command is allowed on the selected cyclic file. */
1181 file_type = SIM_FTYPE_CYCLIC;
1183 /* bytes 9 to 11 give SIM file access conditions */
1185 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1187 /* byte 11 is invalidate and rehabilate nibbles */
1189 /* byte 12 - file status */
1191 /* byte 13 - GSM specific data */
1192 gsm_specific_file_data_len = *ptr_data;
1194 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1196 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1197 record_len = *ptr_data;
1198 dbg("record length[%d], file size[%d]", record_len, file_size);
1200 if (record_len != 0)
1201 num_of_records = (file_size / record_len);
1203 dbg("Number of records [%d]", num_of_records);
1207 dbg(" not handled file type");
1211 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1214 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1215 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1217 file_meta->file_type = file_type;
1218 file_meta->data_size = file_size;
1219 file_meta->rec_length = record_len;
1220 file_meta->rec_count = num_of_records;
1221 file_meta->current_index = 0; // reset for new record type EF
1222 rt = SIM_ACCESS_SUCCESS;
1225 /*2. SIM access fail case*/
1226 dbg("error to get ef[0x%x]", file_meta->file_id);
1227 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1228 rt = _decode_status_word(sw1, sw2);
1230 ur = tcore_user_request_ref(ur);
1232 dbg("Calling _next_from_get_file_info");
1233 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1234 tcore_at_tok_free(tokens);
1236 dbg("RESPONSE NOK");
1237 dbg("error to get ef[0x%x]", file_meta->file_id);
1238 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1239 rt = SIM_ACCESS_FAILED;
1241 ur = tcore_user_request_ref(ur);
1242 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1244 dbg(" Function exit");
1247 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1249 const TcoreATResponse *resp = data;
1250 UserRequest *ur = NULL;
1251 CoreObject *co_sim = NULL;
1252 struct s_sim_property *file_meta = NULL;
1253 GSList *tokens = NULL;
1254 enum tel_sim_access_result rt;
1255 struct tel_sim_imsi *imsi = NULL;
1256 struct tel_sim_service_table *svct = NULL;
1257 struct tel_sim_ecc *ecc = NULL;
1258 struct tel_sim_msisdn *msisdn = NULL;
1259 struct tel_sim_opl *opl = NULL;
1260 struct tel_sim_pnn *pnn = NULL;
1261 struct tel_sim_cfis *cf = NULL;
1262 struct tel_sim_mbi *mbi = NULL;
1263 struct tel_sim_mw *mw = NULL;
1264 gboolean dr = FALSE;
1265 const char *line = NULL;
1272 dbg(" Function entry ");
1274 co_sim = tcore_pending_ref_core_object(p);
1275 ur = tcore_pending_ref_user_request(p);
1276 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
1278 if (resp->success > 0) {
1281 line = (const char *) resp->lines->data;
1282 tokens = tcore_at_tok_new(line);
1283 if (g_slist_length(tokens) != 3) {
1284 msg("invalid message");
1285 tcore_at_tok_free(tokens);
1289 sw1 = atoi(g_slist_nth_data(tokens, 0));
1290 sw2 = atoi(g_slist_nth_data(tokens, 1));
1291 res = g_slist_nth_data(tokens, 2);
1293 tmp = util_removeQuotes(res);
1294 res = util_hexStringToBytes(tmp);
1295 res_len = strlen((const char *) res);
1296 dbg("res: %s res_len: %d", res, res_len);
1298 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1299 rt = SIM_ACCESS_SUCCESS;
1300 file_meta->files.result = rt;
1301 dbg("file_meta->file_id : %x", file_meta->file_id);
1303 switch (file_meta->file_id) {
1306 dbg("res: %s", res);
1307 imsi = calloc(sizeof(struct tel_sim_imsi),1);
1308 dr = tcore_sim_decode_imsi(imsi, (unsigned char *) res, res_len);
1310 dbg("imsi decoding failed");
1312 _sim_check_identity(co_sim, imsi);
1313 tcore_sim_set_imsi(co_sim, imsi);
1321 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
1324 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
1325 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1326 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
1327 case SIM_EF_LP: /* 1 byte encoding*/
1328 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1329 /*2G LP(0x6F05) has 1 byte for each language*/
1330 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
1332 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1333 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
1338 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
1342 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
1345 case SIM_EF_SST: //EF UST has same address
1346 svct = calloc(sizeof(struct tel_sim_service_table),1);
1347 if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1348 dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *) res, res_len);
1349 }else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1350 dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *) res, res_len);
1352 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1355 dbg("SST/UST decoding failed");
1357 tcore_sim_set_service_table(co_sim, svct);
1364 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1365 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
1366 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1367 ecc = calloc(sizeof(struct tel_sim_ecc),1);
1368 dbg("decode w/ index [%d]", file_meta->current_index);
1369 dr = tcore_sim_decode_uecc(ecc, (unsigned char *) res, res_len);
1371 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1372 file_meta->files.data.ecc.ecc_count++;
1377 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
1382 dbg("decode w/ index [%d]", file_meta->current_index);
1383 msisdn = calloc(sizeof(struct tel_sim_msisdn),1);
1384 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *) res, res_len);
1386 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], msisdn, sizeof(struct tel_sim_msisdn));
1387 file_meta->files.data.msisdn_list.count++;
1394 dbg("decode w/ index [%d]", file_meta->current_index);
1395 opl = calloc(sizeof(struct tel_sim_opl),1);
1396 dr = tcore_sim_decode_opl(opl, (unsigned char *) res, res_len);
1398 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], opl, sizeof(struct tel_sim_opl));
1399 file_meta->files.data.opl.opl_count++;
1404 dbg("decode w/ index [%d]", file_meta->current_index);
1405 pnn = calloc(sizeof(struct tel_sim_pnn),1);
1406 dr = tcore_sim_decode_pnn(pnn, (unsigned char *) res, res_len);
1408 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], pnn, sizeof(struct tel_sim_pnn));
1409 file_meta->files.data.pnn.pnn_count++;
1415 case SIM_EF_OPLMN_ACT:
1416 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
1419 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1420 /* dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1423 case SIM_EF_USIM_MBI: //linear type
1424 mbi = calloc(sizeof(struct tel_sim_mbi),1);
1425 dr = tcore_sim_decode_mbi(mbi, (unsigned char *) res, res_len);
1427 memcpy( &file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count], mbi, sizeof(struct tel_sim_mbi) );
1428 file_meta->mbi_list.profile_count++;
1429 dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
1430 dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
1431 dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
1432 dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
1433 dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
1434 dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
1440 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1441 case SIM_EF_MBDN: //linear type
1442 dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info, (unsigned char *) res, res_len);
1443 file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
1446 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1447 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw, (unsigned char *) res, res_len);
1450 case SIM_EF_USIM_MWIS: //linear type
1451 mw = calloc(sizeof(struct tel_sim_mw),1);
1452 dr = tcore_sim_decode_mwis(mw, (unsigned char *) res, res_len);
1454 memcpy( &file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw) );
1455 file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
1456 file_meta->files.data.mw.mw_list.profile_count++;
1462 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
1463 dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf, (unsigned char *) res, res_len);
1466 case SIM_EF_USIM_CFIS: //linear type
1467 cf = calloc(sizeof(struct tel_sim_cfis),1);
1468 dr = tcore_sim_decode_cfis(cf, (unsigned char *) res, res_len);
1470 memcpy( &file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count], cf, sizeof(struct tel_sim_cfis) );
1471 file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
1472 file_meta->files.data.cf.cf_list.profile_count++;
1478 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1479 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1482 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1483 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
1484 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);
1487 case SIM_EF_CPHS_DYNAMICFLAGS:
1488 /* dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, p_data->response, p_data->response_len);*/
1491 case SIM_EF_CPHS_DYNAMIC2FLAG:
1492 /* dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response, p_data->response_len);*/
1495 case SIM_EF_CPHS_CPHS_INFO:
1496 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
1499 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1500 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
1503 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1504 /* dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1508 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1513 rt = _decode_status_word(sw1, sw2);
1514 file_meta->files.result = rt;
1518 tcore_at_tok_free(tokens);
1520 dbg("RESPONSE NOK");
1521 dbg("error to get ef[0x%x]", file_meta->file_id);
1522 rt = SIM_ACCESS_FAILED;
1524 ur = tcore_user_request_ref(ur);
1526 dbg("Calling _next_from_get_file_data");
1527 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1528 dbg(" Function exit");
1531 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1533 const TcoreATResponse *resp = data;
1534 UserRequest *ur = NULL;
1535 CoreObject *co_sim = NULL;
1536 struct s_sim_property *sp = NULL;
1537 GSList *tokens = NULL;
1538 const char *line = NULL;
1539 struct tresp_sim_verify_pins v_pin = {0, };
1540 struct tresp_sim_verify_puks v_puk = {0, };
1541 struct tresp_sim_change_pins change_pin = {0, };
1542 struct tresp_sim_disable_facility dis_facility = {0, };
1543 struct tresp_sim_enable_facility en_facility = {0, };
1545 int attempts_left = 0;
1546 int time_penalty = 0;
1548 dbg(" Function entry ");
1550 co_sim = tcore_pending_ref_core_object(p);
1551 sp = tcore_sim_ref_userdata(co_sim);
1552 ur = tcore_pending_ref_user_request(p);
1554 if (resp->success > 0) {
1557 line = (const char *) resp->lines->data;
1558 tokens = tcore_at_tok_new(line);
1559 if (g_slist_length(tokens) < 3) {
1560 msg("invalid message");
1561 tcore_at_tok_free(tokens);
1565 lock_type = atoi(g_slist_nth_data(tokens, 0));
1566 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1567 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1569 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1570 lock_type, attempts_left, time_penalty);
1572 switch (sp->current_sec_op) {
1573 case SEC_PIN1_VERIFY:
1574 case SEC_PIN2_VERIFY:
1575 case SEC_SIM_VERIFY:
1576 case SEC_ADM_VERIFY:
1577 v_pin.result = SIM_INCORRECT_PASSWORD;
1578 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1579 v_pin.retry_count = attempts_left;
1580 tcore_user_request_send_response(ur, _find_resp_command(ur),
1581 sizeof(struct tresp_sim_verify_pins), &v_pin);
1584 case SEC_PUK1_VERIFY:
1585 case SEC_PUK2_VERIFY:
1586 v_puk.result = SIM_INCORRECT_PASSWORD;
1587 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1588 v_puk.retry_count = attempts_left;
1589 tcore_user_request_send_response(ur, _find_resp_command(ur),
1590 sizeof(struct tresp_sim_verify_puks), &v_puk);
1593 case SEC_PIN1_CHANGE:
1594 case SEC_PIN2_CHANGE:
1595 change_pin.result = SIM_INCORRECT_PASSWORD;
1596 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1597 change_pin.retry_count = attempts_left;
1598 tcore_user_request_send_response(ur, _find_resp_command(ur),
1599 sizeof(struct tresp_sim_change_pins), &change_pin);
1602 case SEC_PIN1_DISABLE:
1603 case SEC_PIN2_DISABLE:
1604 case SEC_FDN_DISABLE:
1605 case SEC_SIM_DISABLE:
1606 case SEC_NET_DISABLE:
1607 case SEC_NS_DISABLE:
1608 case SEC_SP_DISABLE:
1609 case SEC_CP_DISABLE:
1610 dis_facility.result = SIM_INCORRECT_PASSWORD;
1611 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1612 dis_facility.retry_count = attempts_left;
1613 tcore_user_request_send_response(ur, _find_resp_command(ur),
1614 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1617 case SEC_PIN1_ENABLE:
1618 case SEC_PIN2_ENABLE:
1619 case SEC_FDN_ENABLE:
1620 case SEC_SIM_ENABLE:
1621 case SEC_NET_ENABLE:
1625 en_facility.result = SIM_INCORRECT_PASSWORD;
1626 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1627 en_facility.retry_count = attempts_left;
1628 tcore_user_request_send_response(ur, _find_resp_command(ur),
1629 sizeof(struct tresp_sim_enable_facility), &en_facility);
1633 dbg("not handled sec op[%d]", sp->current_sec_op);
1636 tcore_at_tok_free(tokens);
1638 dbg(" Function exit");
1641 static gboolean _get_sim_type(CoreObject *o)
1643 TcoreHal *hal = NULL;
1644 TcoreATRequest *req = NULL;
1645 TcorePending *pending = NULL;
1646 UserRequest *ur = NULL;
1647 char *cmd_str = NULL;
1649 dbg(" Function entry ");
1651 hal = tcore_object_get_hal(o);
1652 pending = tcore_pending_new(o, 0);
1654 cmd_str = g_strdup_printf("AT+XUICC?");
1655 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1657 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1659 tcore_pending_set_request_data(pending, 0, req);
1660 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1661 tcore_pending_link_user_request(pending, ur);
1662 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1663 tcore_hal_send_request(hal, pending);
1666 dbg(" Function exit");
1670 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1672 TcoreHal *hal = NULL;
1673 TcorePending *pending = NULL;
1674 struct s_sim_property file_meta = {0, };
1675 char *cmd_str = NULL;
1676 TReturn ret = TCORE_RETURN_FAILURE;
1679 dbg(" Function entry ");
1681 file_meta.file_id = ef;
1682 dbg("file_meta.file_id: %d", file_meta.file_id);
1683 hal = tcore_object_get_hal(o);
1684 dbg("hal: %x", hal);
1686 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1687 dbg("trt[%d]", trt);
1688 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1689 dbg("cmd_str: %x", cmd_str);
1691 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1692 tcore_pending_link_user_request(pending, ur);
1693 ret = tcore_hal_send_request(hal, pending);
1694 if (TCORE_RETURN_SUCCESS != ret) {
1695 tcore_user_request_free(ur);
1698 dbg(" Function exit");
1699 return TCORE_RETURN_SUCCESS;
1702 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1704 TcoreHal *hal = NULL;
1705 TcoreATRequest *req = NULL;
1706 TcorePending *pending = NULL;
1707 char *cmd_str = NULL;
1712 dbg(" Function entry ");
1713 hal = tcore_object_get_hal(o);
1714 pending = tcore_pending_new(o, 0);
1716 dbg("file_id: %x", ef);
1718 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1719 p2 = (unsigned char) offset & 0x00FF; // offset low
1720 p3 = (unsigned char) length;
1722 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1724 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1726 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1728 tcore_pending_set_request_data(pending, 0, req);
1729 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1730 tcore_pending_link_user_request(pending, ur);
1731 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1733 tcore_hal_send_request(hal, pending);
1736 dbg(" Function exit");
1740 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1742 TcoreHal *hal = NULL;
1743 TcoreATRequest *req = NULL;
1744 TcorePending *pending = NULL;
1745 char *cmd_str = NULL;
1750 dbg(" Function entry ");
1752 hal = tcore_object_get_hal(o);
1753 pending = tcore_pending_new(o, 0);
1755 p1 = (unsigned char) index;
1756 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1757 p3 = (unsigned char) length;
1759 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1761 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1763 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1765 tcore_pending_set_request_data(pending, 0, req);
1766 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1767 tcore_pending_link_user_request(pending, ur);
1768 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1770 tcore_hal_send_request(hal, pending);
1773 dbg(" Function exit");
1777 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1779 TcoreHal *hal = NULL;
1780 TcoreATRequest *req = NULL;
1781 TcorePending *pending = NULL;
1782 char *cmd_str = NULL;
1784 struct s_sim_property *sp = NULL;
1785 const struct treq_sim_get_lock_info *req_data = NULL;
1787 dbg(" Function entry ");
1789 hal = tcore_object_get_hal(o);
1790 pending = tcore_pending_new(o, 0);
1791 req_data = tcore_user_request_ref_data(ur, NULL);
1792 sp = tcore_sim_ref_userdata(o);
1794 switch (sp->current_sec_op) {
1795 case SEC_PIN1_VERIFY:
1796 case SEC_PIN1_CHANGE:
1797 case SEC_PIN1_ENABLE:
1798 case SEC_PIN1_DISABLE:
1802 case SEC_PIN2_VERIFY:
1803 case SEC_PIN2_CHANGE:
1804 case SEC_PIN2_ENABLE:
1805 case SEC_PIN2_DISABLE:
1806 case SEC_FDN_ENABLE:
1807 case SEC_FDN_DISABLE:
1811 case SEC_PUK1_VERIFY:
1815 case SEC_PUK2_VERIFY:
1819 case SEC_NET_ENABLE:
1820 case SEC_NET_DISABLE:
1825 case SEC_NS_DISABLE:
1830 case SEC_SP_DISABLE:
1835 case SEC_CP_DISABLE:
1839 case SEC_ADM_VERIFY:
1847 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1848 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1849 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1851 tcore_pending_set_request_data(pending, 0, req);
1852 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1853 tcore_pending_link_user_request(pending, ur);
1854 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1855 tcore_hal_send_request(hal, pending);
1858 dbg(" Function exit");
1859 return TCORE_RETURN_SUCCESS;
1863 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1865 struct s_sim_property *sp = NULL;
1867 GSList *tokens = NULL;
1868 GSList *lines = NULL;
1870 dbg("Function entry");
1873 sp = tcore_sim_ref_userdata(o);
1874 lines = (GSList *) event_info;
1875 if (1 != g_slist_length(lines)) {
1876 dbg("unsolicited msg but multiple line");
1879 line = (char *) (lines->data);
1880 tokens = tcore_at_tok_new(line);
1881 if (g_slist_length(tokens) != 1) {
1882 msg("invalid message");
1883 tcore_at_tok_free(tokens);
1888 dbg(" Function exit");
1890 tcore_at_tok_free(tokens);
1895 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1897 UserRequest *ur = NULL;
1898 struct s_sim_property *sp = NULL;
1899 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1900 GSList *tokens = NULL;
1901 GSList *lines = NULL;
1902 const char *line = NULL;
1905 dbg(" Function entry ");
1907 sp = tcore_sim_ref_userdata(o);
1909 lines = (GSList *) event_info;
1910 if (1 != g_slist_length(lines)) {
1911 dbg("unsolicited msg but multiple line");
1914 line = (char *) (lines->data);
1916 tokens = tcore_at_tok_new(line);
1917 if (g_slist_length(tokens) != 1) {
1918 msg("invalid message");
1919 tcore_at_tok_free(tokens);
1922 sim_state = atoi(g_slist_nth_data(tokens, 0));
1924 switch (sim_state) {
1925 case 0: // sim state = SIM not present
1926 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1930 case 1: // sim state = PIN verification needed
1931 sim_status = SIM_STATUS_PIN_REQUIRED;
1932 dbg(" PIN required");
1935 case 2: // sim state = PIN verification not needed \96 Ready
1936 case 3: // sim state = PIN verified \96 Ready
1937 sim_status = SIM_STATUS_INITIALIZING;
1938 dbg(" Inside PIN disabled at BOOT UP");
1941 case 4: // sim state = PUK verification needed
1942 sim_status = SIM_STATUS_PUK_REQUIRED;
1943 dbg(" PUK required");
1946 case 5: // sim state = SIM permanently blocked
1947 sim_status = SIM_STATUS_CARD_BLOCKED;
1948 dbg(" Card permanently blocked");
1951 case 6: // sim state = SIM error
1952 sim_status = SIM_STATUS_CARD_ERROR;
1953 dbg("SIM card error ");
1956 case 7: // sim state = ready for attach (+COPS)
1957 sim_status = SIM_STATUS_INIT_COMPLETED;
1958 dbg("Modem init completed");
1961 case 8: // sim state = SIM Technical Problem
1962 sim_status = SIM_STATUS_CARD_ERROR;
1963 dbg("SIM unavailable");
1966 case 9: // sim state = SIM removed
1967 sim_status = SIM_STATUS_CARD_REMOVED;
1971 case 99: // sim state = SIM State Unknown
1972 sim_status = SIM_STATUS_UNKNOWN;
1973 dbg("SIM State Unknown");
1977 dbg("SIM Status : %d", sim_status);
1981 dbg(" not handled SEC lock type ");
1985 switch (sim_status) {
1986 case SIM_STATUS_INIT_COMPLETED:
1987 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
1988 _get_file_info(o, ur, SIM_EF_IMSI);
1991 case SIM_STATUS_INITIALIZING:
1992 case SIM_STATUS_PIN_REQUIRED:
1993 case SIM_STATUS_PUK_REQUIRED:
1994 case SIM_STATUS_CARD_BLOCKED:
1995 case SIM_STATUS_NCK_REQUIRED:
1996 case SIM_STATUS_NSCK_REQUIRED:
1997 case SIM_STATUS_SPCK_REQUIRED:
1998 case SIM_STATUS_CCK_REQUIRED:
1999 case SIM_STATUS_LOCK_REQUIRED:
2000 if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
2001 dbg("first received sim status[%d]", sim_status);
2002 sp->first_recv_status = sim_status;
2005 dbg("second or later received lock status[%d]", sim_status);
2006 if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
2007 dbg("sim is not init complete in telephony side yet");
2008 _sim_status_update(o, sim_status);
2013 case SIM_STATUS_CARD_REMOVED:
2014 case SIM_STATUS_CARD_NOT_PRESENT:
2015 case SIM_STATUS_CARD_ERROR:
2016 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
2017 dbg("[SIM]SIM CARD REMOVED!!");
2018 sim_status = SIM_STATUS_CARD_REMOVED;
2020 _sim_status_update(o, sim_status);
2024 dbg("not handled status[%d]", sim_status);
2029 dbg(" Function exit");
2031 tcore_at_tok_free(tokens);
2037 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2039 const TcoreATResponse *resp = data;
2040 UserRequest *ur = NULL;
2041 CoreObject *co_sim = NULL;
2042 struct s_sim_property *sp = NULL;
2043 GSList *tokens = NULL;
2044 struct tresp_sim_verify_pins res;
2045 GQueue *queue = NULL;
2049 dbg(" Function entry ");
2051 co_sim = tcore_pending_ref_core_object(p);
2052 sp = tcore_sim_ref_userdata(co_sim);
2053 ur = tcore_pending_ref_user_request(p);
2055 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2057 if (resp->success > 0) {
2059 res.result = SIM_PIN_OPERATION_SUCCESS;
2060 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2061 if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
2062 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
2063 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2065 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &res);
2067 dbg("RESPONSE NOK");
2068 line = (const char *) resp->final_response;
2069 tokens = tcore_at_tok_new(line);
2070 if (g_slist_length(tokens) < 1) {
2071 dbg("err cause not specified or string corrupted");
2072 res.result = TCORE_RETURN_3GPP_ERROR;
2074 err = atoi(g_slist_nth_data(tokens, 0));
2075 dbg("on_response_verify_pins: err = %d", err);
2076 queue = tcore_object_ref_user_data(co_sim);
2077 ur = tcore_user_request_ref(ur);
2078 _get_retry_count(co_sim, ur);
2080 tcore_at_tok_free(tokens);
2082 dbg(" Function exit");
2085 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2087 const TcoreATResponse *resp = data;
2088 UserRequest *ur = NULL;
2089 CoreObject *co_sim = NULL;
2090 struct s_sim_property *sp = NULL;
2091 GSList *tokens = NULL;
2092 struct tresp_sim_verify_puks res;
2093 GQueue *queue = NULL;
2097 dbg(" Function entry ");
2099 co_sim = tcore_pending_ref_core_object(p);
2100 sp = tcore_sim_ref_userdata(co_sim);
2101 ur = tcore_pending_ref_user_request(p);
2103 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2105 if (resp->success > 0) {
2107 res.result = SIM_PIN_OPERATION_SUCCESS;
2108 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2109 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PUKS, sizeof(struct tresp_sim_verify_pins), &res);
2111 dbg("RESPONSE NOK");
2112 line = (const char *) resp->final_response;
2113 tokens = tcore_at_tok_new(line);
2115 if (g_slist_length(tokens) < 1) {
2116 dbg("err cause not specified or string corrupted");
2117 res.result = TCORE_RETURN_3GPP_ERROR;
2119 err = atoi(g_slist_nth_data(tokens, 0));
2120 queue = tcore_object_ref_user_data(co_sim);
2121 ur = tcore_user_request_ref(ur);
2122 _get_retry_count(co_sim, ur);
2124 tcore_at_tok_free(tokens);
2126 dbg(" Function exit");
2129 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2131 const TcoreATResponse *resp = data;
2132 UserRequest *ur = NULL;
2133 CoreObject *co_sim = NULL;
2134 struct s_sim_property *sp = NULL;
2135 GSList *tokens = NULL;
2136 struct tresp_sim_change_pins res;
2141 dbg(" Function entry ");
2143 co_sim = tcore_pending_ref_core_object(p);
2144 sp = tcore_sim_ref_userdata(co_sim);
2145 ur = tcore_pending_ref_user_request(p);
2147 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2149 if (resp->success > 0) {
2151 res.result = SIM_PIN_OPERATION_SUCCESS;
2152 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2153 tcore_user_request_send_response(ur, TRESP_SIM_CHANGE_PINS, sizeof(struct tresp_sim_change_pins), &res);
2155 dbg("RESPONSE NOK");
2156 line = (const char *) resp->final_response;
2157 tokens = tcore_at_tok_new(line);
2159 if (g_slist_length(tokens) < 1) {
2160 dbg("err cause not specified or string corrupted");
2161 res.result = TCORE_RETURN_3GPP_ERROR;
2163 err = atoi(g_slist_nth_data(tokens, 0));
2164 queue = tcore_object_ref_user_data(co_sim);
2165 ur = tcore_user_request_ref(ur);
2166 _get_retry_count(co_sim, ur);
2168 tcore_at_tok_free(tokens);
2170 dbg(" Function exit");
2173 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2175 const TcoreATResponse *resp = data;
2176 UserRequest *ur = NULL;
2177 CoreObject *co_sim = NULL;
2178 struct s_sim_property *sp = NULL;
2179 GSList *tokens = NULL;
2180 struct tresp_sim_get_facility_status res;
2183 dbg(" Function entry ");
2185 co_sim = tcore_pending_ref_core_object(p);
2186 sp = tcore_sim_ref_userdata(co_sim);
2187 ur = tcore_pending_ref_user_request(p);
2189 memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
2191 res.result = SIM_PIN_OPERATION_SUCCESS;
2192 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2194 if (resp->success > 0) {
2197 line = (const char *) resp->lines->data;
2198 tokens = tcore_at_tok_new(line);
2199 if (g_slist_length(tokens) != 1) {
2200 msg("invalid message");
2201 tcore_at_tok_free(tokens);
2205 res.b_enable = atoi(g_slist_nth_data(tokens, 0));
2207 dbg("RESPONSE NOK");
2208 res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2212 tcore_user_request_send_response(ur, TRESP_SIM_GET_FACILITY_STATUS,
2213 sizeof(struct tresp_sim_get_facility_status), &res);
2215 tcore_at_tok_free(tokens);
2216 dbg(" Function exit");
2219 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2221 const TcoreATResponse *resp = data;
2222 UserRequest *ur = NULL;
2223 CoreObject *co_sim = NULL;
2224 struct s_sim_property *sp = NULL;
2225 GSList *tokens = NULL;
2226 struct tresp_sim_enable_facility res;
2230 dbg(" Function entry ");
2232 co_sim = tcore_pending_ref_core_object(p);
2233 sp = tcore_sim_ref_userdata(co_sim);
2234 ur = tcore_pending_ref_user_request(p);
2236 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2238 res.result = SIM_PIN_OPERATION_SUCCESS;
2239 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2241 if (resp->success > 0) {
2244 line = (const char *) resp->lines->data;
2245 tokens = tcore_at_tok_new(line);
2246 if (g_slist_length(tokens) != 1) {
2247 msg("invalid message");
2248 tcore_at_tok_free(tokens);
2252 res.result = SIM_PIN_OPERATION_SUCCESS;
2254 tcore_user_request_send_response(ur, TRESP_SIM_ENABLE_FACILITY,
2255 sizeof(struct tresp_sim_enable_facility), &res);
2257 tcore_at_tok_free(tokens);
2259 dbg("RESPONSE NOK");
2260 queue = tcore_object_ref_user_data(co_sim);
2261 ur = tcore_user_request_ref(ur);
2262 _get_retry_count(co_sim, ur);
2264 dbg(" Function exit");
2267 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2269 const TcoreATResponse *resp = data;
2270 UserRequest *ur = NULL;
2271 CoreObject *co_sim = NULL;
2272 struct s_sim_property *sp = NULL;
2273 GSList *tokens = NULL;
2274 struct tresp_sim_disable_facility res;
2278 dbg(" Function entry ");
2280 co_sim = tcore_pending_ref_core_object(p);
2281 sp = tcore_sim_ref_userdata(co_sim);
2282 ur = tcore_pending_ref_user_request(p);
2284 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2286 res.result = SIM_PIN_OPERATION_SUCCESS;
2287 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2289 if (resp->success > 0) {
2292 line = (const char *) resp->lines->data;
2293 tokens = tcore_at_tok_new(line);
2294 if (g_slist_length(tokens) != 1) {
2295 msg("invalid message");
2296 tcore_at_tok_free(tokens);
2300 res.result = SIM_PIN_OPERATION_SUCCESS;
2302 tcore_user_request_send_response(ur, TRESP_SIM_DISABLE_FACILITY,
2303 sizeof(struct tresp_sim_disable_facility), &res);
2305 tcore_at_tok_free(tokens);
2307 dbg("RESPONSE NOK");
2308 queue = tcore_object_ref_user_data(co_sim);
2309 ur = tcore_user_request_ref(ur);
2310 _get_retry_count(co_sim, ur);
2312 dbg(" Function exit");
2315 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2317 const TcoreATResponse *resp = data;
2318 UserRequest *ur = NULL;
2319 CoreObject *co_sim = NULL;
2320 struct s_sim_property *sp = NULL;
2321 GSList *tokens = NULL;
2323 struct tresp_sim_verify_pins v_pin = {0, };
2324 struct tresp_sim_verify_puks v_puk = {0, };
2325 struct tresp_sim_change_pins change_pin = {0, };
2326 struct tresp_sim_disable_facility dis_facility = {0, };
2327 struct tresp_sim_enable_facility en_facility = {0, };
2329 int attempts_left = 0;
2330 int time_penalty = 0;
2332 dbg(" Function entry ");
2334 co_sim = tcore_pending_ref_core_object(p);
2335 sp = tcore_sim_ref_userdata(co_sim);
2336 ur = tcore_pending_ref_user_request(p);
2338 if (resp->success > 0) {
2341 line = (const char *) resp->lines->data;
2342 tokens = tcore_at_tok_new(line);
2343 if (g_slist_length(tokens) != 3) {
2344 msg("invalid message");
2345 tcore_at_tok_free(tokens);
2349 lock_type = atoi(g_slist_nth_data(tokens, 0));
2350 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2351 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2353 switch (sp->current_sec_op) {
2354 case SEC_PIN1_VERIFY:
2355 case SEC_PIN2_VERIFY:
2356 case SEC_SIM_VERIFY:
2357 case SEC_ADM_VERIFY:
2358 v_pin.result = SIM_INCORRECT_PASSWORD;
2359 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2360 v_pin.retry_count = attempts_left;
2361 tcore_user_request_send_response(ur, _find_resp_command(ur),
2362 sizeof(struct tresp_sim_verify_pins), &v_pin);
2365 case SEC_PUK1_VERIFY:
2366 case SEC_PUK2_VERIFY:
2367 v_puk.result = SIM_INCORRECT_PASSWORD;
2368 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2369 v_puk.retry_count = attempts_left;
2370 tcore_user_request_send_response(ur, _find_resp_command(ur),
2371 sizeof(struct tresp_sim_verify_puks), &v_puk);
2374 case SEC_PIN1_CHANGE:
2375 case SEC_PIN2_CHANGE:
2376 change_pin.result = SIM_INCORRECT_PASSWORD;
2377 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2378 change_pin.retry_count = attempts_left;
2379 tcore_user_request_send_response(ur, _find_resp_command(ur),
2380 sizeof(struct tresp_sim_change_pins), &change_pin);
2383 case SEC_PIN1_DISABLE:
2384 case SEC_PIN2_DISABLE:
2385 case SEC_FDN_DISABLE:
2386 case SEC_SIM_DISABLE:
2387 case SEC_NET_DISABLE:
2388 case SEC_NS_DISABLE:
2389 case SEC_SP_DISABLE:
2390 case SEC_CP_DISABLE:
2391 dis_facility.result = SIM_INCORRECT_PASSWORD;
2392 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2393 dis_facility.retry_count = attempts_left;
2394 tcore_user_request_send_response(ur, _find_resp_command(ur),
2395 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2398 case SEC_PIN1_ENABLE:
2399 case SEC_PIN2_ENABLE:
2400 case SEC_FDN_ENABLE:
2401 case SEC_SIM_ENABLE:
2402 case SEC_NET_ENABLE:
2406 en_facility.result = SIM_INCORRECT_PASSWORD;
2407 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2408 en_facility.retry_count = attempts_left;
2409 tcore_user_request_send_response(ur, _find_resp_command(ur),
2410 sizeof(struct tresp_sim_enable_facility), &en_facility);
2414 dbg("not handled sec op[%d]", sp->current_sec_op);
2417 tcore_at_tok_free(tokens);
2419 dbg(" Function exit");
2422 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2424 const TcoreATResponse *resp = data;
2425 UserRequest *ur = NULL;
2426 CoreObject *co_sim = NULL;
2427 struct tresp_sim_set_data resp_cf = {0, };
2428 struct tresp_sim_set_data resp_language = {0, };
2429 struct s_sim_property *sp = NULL;
2430 GSList *tokens = NULL;
2431 enum tel_sim_access_result result;
2436 dbg(" Function entry ");
2438 co_sim = tcore_pending_ref_core_object(p);
2439 ur = tcore_pending_ref_user_request(p);
2440 sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
2442 if (resp->success > 0) {
2445 line = (const char *) resp->lines->data;
2446 tokens = tcore_at_tok_new(line);
2447 if (g_slist_length(tokens) != 2) {
2448 msg("invalid message");
2449 tcore_at_tok_free(tokens);
2453 sw1 = atoi(g_slist_nth_data(tokens, 0));
2454 sw2 = atoi(g_slist_nth_data(tokens, 1));
2456 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2457 result = SIM_ACCESS_SUCCESS;
2459 result = _decode_status_word(sw1, sw2);
2462 dbg("RESPONSE NOK");
2463 result = SIM_ACCESS_FAILED;
2466 switch (sp->file_id) {
2467 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2468 case SIM_EF_USIM_CFIS:
2469 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_cf);
2474 case SIM_EF_USIM_LI:
2475 case SIM_EF_USIM_PL:
2476 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_language);
2480 dbg("Invalid File ID - %d", sp->file_id)
2483 tcore_at_tok_free(tokens);
2484 dbg(" Function exit");
2487 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2489 const TcoreATResponse *resp = data;
2490 UserRequest *ur = NULL;
2491 CoreObject *co_sim = NULL;
2492 struct s_sim_property *sp = NULL;
2493 GSList *tokens = NULL;
2494 struct tresp_sim_transmit_apdu res;
2497 dbg(" Function entry ");
2499 co_sim = tcore_pending_ref_core_object(p);
2500 sp = tcore_sim_ref_userdata(co_sim);
2501 ur = tcore_pending_ref_user_request(p);
2503 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2505 if (resp->success > 0) {
2507 res.result = SIM_ACCESS_SUCCESS;
2510 char *decoded_data = NULL;
2511 line = (const char *) resp->lines->data;
2512 tokens = tcore_at_tok_new(line);
2513 if (g_slist_length(tokens) != 2) {
2514 msg("invalid message");
2515 tcore_at_tok_free(tokens);
2518 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
2520 tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
2521 decoded_data = util_hexStringToBytes(tmp);
2523 memcpy((char *) res.apdu_resp, decoded_data, res.apdu_resp_length);
2528 dbg("RESPONSE NOK");
2529 res.result = SIM_ACCESS_FAILED;
2531 ur = tcore_pending_ref_user_request(p);
2533 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
2535 tcore_at_tok_free(tokens);
2536 dbg(" Function exit");
2539 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2541 TcoreHal *hal = NULL;
2542 TcoreATRequest *req = NULL;
2543 TcorePending *pending = NULL;
2544 char *cmd_str = NULL;
2545 const struct treq_sim_verify_pins *req_data = NULL;
2546 struct s_sim_property *sp = NULL;
2548 dbg(" Function entry ");
2550 hal = tcore_object_get_hal(o);
2551 if(FALSE == tcore_hal_get_power_state(hal)){
2552 dbg("cp not ready/n");
2553 return TCORE_RETURN_ENOSYS;
2556 sp = tcore_sim_ref_userdata(o);
2557 pending = tcore_pending_new(o, 0);
2558 req_data = tcore_user_request_ref_data(ur, NULL);
2561 return TCORE_RETURN_EINVAL;
2563 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2564 sp->current_sec_op = SEC_PIN1_VERIFY;
2565 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2566 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2567 sp->current_sec_op = SEC_PIN2_VERIFY;
2568 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
2569 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
2570 sp->current_sec_op = SEC_SIM_VERIFY;
2571 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2572 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
2573 sp->current_sec_op = SEC_ADM_VERIFY;
2574 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2576 return TCORE_RETURN_EINVAL;
2579 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2581 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2583 tcore_pending_set_request_data(pending, 0, req);
2584 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
2585 tcore_pending_link_user_request(pending, ur);
2586 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2587 tcore_hal_send_request(hal, pending);
2590 dbg(" Function exit");
2591 return TCORE_RETURN_SUCCESS;
2594 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2596 TcoreHal *hal = NULL;
2597 TcoreATRequest *req = NULL;
2598 TcorePending *pending = NULL;
2599 char *cmd_str = NULL;
2600 const struct treq_sim_verify_puks *req_data;
2601 struct s_sim_property *sp = NULL;
2603 dbg(" Function entry ");
2605 hal = tcore_object_get_hal(o);
2606 if(FALSE == tcore_hal_get_power_state(hal)){
2607 dbg("cp not ready/n");
2608 return TCORE_RETURN_ENOSYS;
2611 sp = tcore_sim_ref_userdata(o);
2612 pending = tcore_pending_new(o, 0);
2613 req_data = tcore_user_request_ref_data(ur, NULL);
2616 return TCORE_RETURN_EINVAL;
2618 if (req_data->puk_type == SIM_PTYPE_PUK1) {
2619 sp->current_sec_op = SEC_PUK1_VERIFY;
2620 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2621 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
2622 sp->current_sec_op = SEC_PUK2_VERIFY;
2623 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2625 return TCORE_RETURN_EINVAL;
2627 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2629 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2631 tcore_pending_set_request_data(pending, 0, req);
2632 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
2633 tcore_pending_link_user_request(pending, ur);
2634 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2635 tcore_hal_send_request(hal, pending);
2638 dbg(" Function exit");
2639 return TCORE_RETURN_SUCCESS;
2642 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2644 TcoreHal *hal = NULL;
2645 TcoreATRequest *req = NULL;
2646 TcorePending *pending = NULL;
2647 char *cmd_str = NULL;
2648 const struct treq_sim_change_pins *req_data;
2649 struct s_sim_property *sp = NULL;
2653 dbg(" Function entry ");
2655 hal = tcore_object_get_hal(o);
2656 if(FALSE == tcore_hal_get_power_state(hal)){
2657 dbg("cp not ready/n");
2658 return TCORE_RETURN_ENOSYS;
2661 sp = tcore_sim_ref_userdata(o);
2662 pending = tcore_pending_new(o, 0);
2663 req_data = tcore_user_request_ref_data(ur, NULL);
2666 return TCORE_RETURN_EINVAL;
2668 if (req_data->type == SIM_PTYPE_PIN1) {
2669 sp->current_sec_op = SEC_PIN1_CHANGE;
2670 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
2671 } else if (req_data->type == SIM_PTYPE_PIN2) {
2672 sp->current_sec_op = SEC_PIN2_CHANGE;
2673 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
2675 return TCORE_RETURN_EINVAL;
2677 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2679 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2681 tcore_pending_set_request_data(pending, 0, req);
2682 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
2683 tcore_pending_link_user_request(pending, ur);
2684 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2685 tcore_hal_send_request(hal, pending);
2688 dbg(" Function exit");
2689 return TCORE_RETURN_SUCCESS;
2692 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2694 TcoreHal *hal = NULL;
2695 TcoreATRequest *req = NULL;
2696 TcorePending *pending = NULL;
2697 char *cmd_str = NULL;
2698 const struct treq_sim_get_facility_status *req_data;
2699 struct s_sim_property *sp = NULL;
2701 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
2703 dbg(" Function entry ");
2705 hal = tcore_object_get_hal(o);
2706 if(FALSE == tcore_hal_get_power_state(hal)){
2707 dbg("cp not ready/n");
2708 return TCORE_RETURN_ENOSYS;
2711 sp = tcore_sim_ref_userdata(o);
2712 pending = tcore_pending_new(o, 0);
2713 req_data = tcore_user_request_ref_data(ur, NULL);
2716 return TCORE_RETURN_EINVAL;
2718 if (req_data->type == SIM_FACILITY_PS) {
2719 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2720 } else if (req_data->type == SIM_FACILITY_SC) {
2721 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2722 } else if (req_data->type == SIM_FACILITY_FD) {
2723 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2724 } else if (req_data->type == SIM_FACILITY_PN) {
2725 fac = "PN"; /*Network Personalization*/
2726 } else if (req_data->type == SIM_FACILITY_PU) {
2727 fac = "PU"; /*network sUbset Personalization*/
2728 } else if (req_data->type == SIM_FACILITY_PP) {
2729 fac = "PP"; /*service Provider Personalization*/
2730 } else if (req_data->type == SIM_FACILITY_PC) {
2731 fac = "PC"; /*Corporate Personalization*/
2733 return TCORE_RETURN_EINVAL;
2735 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
2736 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2738 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2740 tcore_pending_set_request_data(pending, 0, req);
2741 tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
2742 tcore_pending_link_user_request(pending, ur);
2743 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2744 tcore_hal_send_request(hal, pending);
2747 dbg(" Function exit");
2748 return TCORE_RETURN_SUCCESS;
2751 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2753 TcoreHal *hal = NULL;
2754 TcoreATRequest *req = NULL;
2755 TcorePending *pending = NULL;
2756 char *cmd_str = NULL;
2757 const struct treq_sim_enable_facility *req_data;
2758 struct s_sim_property *sp = NULL;
2760 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
2762 dbg(" Function entry ");
2764 hal = tcore_object_get_hal(o);
2765 if(FALSE == tcore_hal_get_power_state(hal)){
2766 dbg("cp not ready/n");
2767 return TCORE_RETURN_ENOSYS;
2770 sp = tcore_sim_ref_userdata(o);
2771 pending = tcore_pending_new(o, 0);
2772 req_data = tcore_user_request_ref_data(ur, NULL);
2775 return TCORE_RETURN_EINVAL;
2777 if (req_data->type == SIM_FACILITY_PS) {
2778 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2779 sp->current_sec_op = SEC_SIM_ENABLE;
2780 } else if (req_data->type == SIM_FACILITY_SC) {
2781 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2782 sp->current_sec_op = SEC_PIN1_ENABLE;
2783 } else if (req_data->type == SIM_FACILITY_FD) {
2784 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2785 sp->current_sec_op = SEC_FDN_ENABLE;
2786 } else if (req_data->type == SIM_FACILITY_PN) {
2787 fac = "PN"; /*Network Personalization*/
2788 sp->current_sec_op = SEC_NET_ENABLE;
2789 } else if (req_data->type == SIM_FACILITY_PU) {
2790 fac = "PU"; /*network sUbset Personalization*/
2791 sp->current_sec_op = SEC_NS_ENABLE;
2792 } else if (req_data->type == SIM_FACILITY_PP) {
2793 fac = "PP"; /*service Provider Personalization*/
2794 sp->current_sec_op = SEC_SP_ENABLE;
2795 } else if (req_data->type == SIM_FACILITY_PC) {
2796 fac = "PC"; /*Corporate Personalization*/
2797 sp->current_sec_op = SEC_CP_ENABLE;
2799 return TCORE_RETURN_EINVAL;
2801 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2802 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2804 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2806 tcore_pending_set_request_data(pending, 0, req);
2807 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
2808 tcore_pending_link_user_request(pending, ur);
2809 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2810 tcore_hal_send_request(hal, pending);
2813 dbg(" Function exit");
2814 return TCORE_RETURN_SUCCESS;
2817 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2820 TcoreATRequest *req;
2821 TcorePending *pending = NULL;
2822 char *cmd_str = NULL;
2823 const struct treq_sim_enable_facility *req_data;
2824 struct s_sim_property *sp = NULL;
2826 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
2828 dbg(" Function entry ");
2830 hal = tcore_object_get_hal(o);
2831 if(FALSE == tcore_hal_get_power_state(hal)){
2832 dbg("cp not ready/n");
2833 return TCORE_RETURN_ENOSYS;
2836 sp = tcore_sim_ref_userdata(o);
2837 pending = tcore_pending_new(o, 0);
2838 req_data = tcore_user_request_ref_data(ur, NULL);
2841 return TCORE_RETURN_EINVAL;
2843 if (req_data->type == SIM_FACILITY_PS) {
2844 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2845 sp->current_sec_op = SEC_SIM_DISABLE;
2846 } else if (req_data->type == SIM_FACILITY_SC) {
2847 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2848 sp->current_sec_op = SEC_PIN1_DISABLE;
2849 } else if (req_data->type == SIM_FACILITY_FD) {
2850 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2851 sp->current_sec_op = SEC_FDN_DISABLE;
2852 } else if (req_data->type == SIM_FACILITY_PN) {
2853 fac = "PN"; /*Network Personalization*/
2854 sp->current_sec_op = SEC_NET_DISABLE;
2855 } else if (req_data->type == SIM_FACILITY_PU) {
2856 fac = "PU"; /*network sUbset Personalization*/
2857 sp->current_sec_op = SEC_NS_DISABLE;
2858 } else if (req_data->type == SIM_FACILITY_PP) {
2859 fac = "PP"; /*service Provider Personalization*/
2860 sp->current_sec_op = SEC_SP_DISABLE;
2861 } else if (req_data->type == SIM_FACILITY_PC) {
2862 fac = "PC"; /*Corporate Personalization*/
2863 sp->current_sec_op = SEC_CP_DISABLE;
2865 return TCORE_RETURN_EINVAL;
2867 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2868 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2870 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2872 tcore_pending_set_request_data(pending, 0, req);
2873 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
2874 tcore_pending_link_user_request(pending, ur);
2875 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2876 tcore_hal_send_request(hal, pending);
2879 dbg(" Function exit");
2880 return TCORE_RETURN_SUCCESS;
2883 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
2885 TcoreHal *hal = NULL;
2886 TcoreATRequest *req = NULL;
2887 TcorePending *pending = NULL;
2888 char *cmd_str = NULL;
2889 char *lock_type = NULL;
2890 const struct treq_sim_get_lock_info *req_data;
2891 struct s_sim_property *sp = NULL;
2893 dbg(" Function entry ");
2895 hal = tcore_object_get_hal(o);
2896 if(FALSE == tcore_hal_get_power_state(hal)){
2897 dbg("cp not ready/n");
2898 return TCORE_RETURN_ENOSYS;
2900 sp = tcore_sim_ref_userdata(o);
2901 pending = tcore_pending_new(o, 0);
2902 req_data = tcore_user_request_ref_data(ur, NULL);
2905 return TCORE_RETURN_EINVAL;
2907 switch (req_data->type) {
2908 case SIM_FACILITY_PS:
2912 case SIM_FACILITY_SC:
2916 case SIM_FACILITY_FD:
2920 case SIM_FACILITY_PN:
2924 case SIM_FACILITY_PU:
2928 case SIM_FACILITY_PP:
2932 case SIM_FACILITY_PC:
2939 cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
2940 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2942 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2944 tcore_pending_set_request_data(pending, 0, req);
2945 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
2946 tcore_pending_link_user_request(pending, ur);
2947 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2948 tcore_hal_send_request(hal, pending);
2951 dbg(" Function exit");
2952 return TCORE_RETURN_SUCCESS;
2955 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
2957 TReturn api_ret = TCORE_RETURN_SUCCESS;
2958 enum tcore_request_command command;
2960 command = tcore_user_request_get_command(ur);
2962 dbg(" Function entry ");
2965 return TCORE_RETURN_EINVAL;
2967 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
2968 dbg("cp not ready/n");
2969 return TCORE_RETURN_ENOSYS;
2973 case TREQ_SIM_GET_ECC:
2974 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
2977 case TREQ_SIM_GET_LANGUAGE:
2978 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
2979 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
2980 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
2981 api_ret = _get_file_info(o, ur, SIM_EF_LP);
2983 api_ret = TCORE_RETURN_ENOSYS;
2986 case TREQ_SIM_GET_ICCID:
2987 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
2990 case TREQ_SIM_GET_MAILBOX:
2991 if (tcore_sim_get_cphs_status(o))
2992 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
2994 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
2997 case TREQ_SIM_GET_CALLFORWARDING:
2998 if (tcore_sim_get_cphs_status(o))
2999 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3001 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3004 case TREQ_SIM_GET_MESSAGEWAITING:
3005 if (tcore_sim_get_cphs_status(o))
3006 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3008 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3011 case TREQ_SIM_GET_CPHS_INFO:
3012 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3015 case TREQ_SIM_GET_MSISDN:
3016 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3019 case TREQ_SIM_GET_SPN:
3020 dbg("enter case SPN");
3021 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3024 case TREQ_SIM_GET_SPDI:
3025 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3028 case TREQ_SIM_GET_OPL:
3029 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3032 case TREQ_SIM_GET_PNN:
3033 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3036 case TREQ_SIM_GET_CPHS_NETNAME:
3037 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3040 case TREQ_SIM_GET_OPLMNWACT:
3041 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3045 dbg("error - not handled read treq command[%d]", command);
3046 api_ret = TCORE_RETURN_EINVAL;
3049 dbg(" Function exit");
3053 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
3056 TcoreATRequest *req;
3057 TcorePending *pending = NULL;
3058 char *cmd_str = NULL;
3059 TReturn api_ret = TCORE_RETURN_SUCCESS;
3060 char *encoded_data = NULL;
3061 int encoded_len = 0;
3062 enum tcore_request_command command;
3063 enum tel_sim_file_id ef = SIM_EF_INVALID;
3064 const struct treq_sim_set_callforwarding *cf;
3065 const struct treq_sim_set_language *cl;
3066 struct s_sim_property file_meta = {0, };
3073 struct tel_sim_language sim_language;
3077 command = tcore_user_request_get_command(ur);
3079 dbg(" Function entry ");
3081 hal = tcore_object_get_hal(o);
3082 if(FALSE == tcore_hal_get_power_state(hal)){
3083 dbg("cp not ready/n");
3084 return TCORE_RETURN_ENOSYS;
3087 pending = tcore_pending_new(o, 0);
3090 return TCORE_RETURN_EINVAL;
3094 case TREQ_SIM_SET_LANGUAGE:
3095 cl = tcore_user_request_ref_data(ur, NULL);
3096 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
3099 sim_language.language_count = 1;
3100 sim_language.language[0] = cl->language;
3101 dbg("language %d", cl->language);
3103 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
3106 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
3108 encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
3109 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
3110 result = util_byte_to_hex(tmp, encoded_data, out_length);
3115 dbg("encoded_data - %s ---", encoded_data);
3116 dbg("out_length - %d ---", out_length);
3117 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
3120 tmp = tcore_sim_encode_li(&out_length, &sim_language);
3122 encoded_data = (char *) malloc(2 * (out_length) + 1);
3123 memset(encoded_data, 0x00, (2 * out_length) + 1);
3124 result = util_byte_to_hex(tmp, encoded_data, out_length);
3129 dbg("encoded_data - %s ---", encoded_data);
3130 dbg("out_length - %d ---", out_length);
3132 api_ret = TCORE_RETURN_ENOSYS;
3136 case TREQ_SIM_SET_CALLFORWARDING:
3137 cf = tcore_user_request_ref_data(ur, NULL);
3138 if (tcore_sim_get_cphs_status(o)) {
3139 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
3140 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
3144 encoded_data = (char *) malloc(2 * (p3) + 1);
3145 memset(encoded_data, 0x00, (2 *p3) + 1);
3146 result = util_byte_to_hex(tmp, encoded_data, p3);
3147 cmd = 214; /*command - 214 : UPDATE BINARY*/
3149 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
3150 ef = SIM_EF_USIM_CFIS;
3154 encoded_data = (char *) malloc(2 * (encoded_len) + 1);
3155 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
3156 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3157 cmd = 220; /*command - 220 : UPDATE RECORD*/
3162 dbg("error - not handled update treq command[%d]", command);
3163 api_ret = TCORE_RETURN_EINVAL;
3166 file_meta.file_id = ef;
3167 dbg("file_meta.file_id: %d", file_meta.file_id);
3169 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
3170 dbg("trt[%d]", trt);
3172 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3173 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3175 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3177 tcore_pending_set_request_data(pending, 0, req);
3178 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
3179 tcore_pending_link_user_request(pending, ur);
3180 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
3182 tcore_hal_send_request(hal, pending);
3183 if (NULL != encoded_data) {
3184 g_free(encoded_data);
3192 dbg(" Function exit");
3193 return TCORE_RETURN_SUCCESS;
3196 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3198 TcoreHal *hal = NULL;
3199 TcoreATRequest *req = NULL;
3200 TcorePending *pending = NULL;
3201 char *cmd_str = NULL;
3205 const struct treq_sim_transmit_apdu *req_data;
3207 dbg(" Function entry ");
3209 hal = tcore_object_get_hal(o);
3210 if(FALSE == tcore_hal_get_power_state(hal)){
3211 dbg("cp not ready/n");
3212 return TCORE_RETURN_ENOSYS;
3215 pending = tcore_pending_new(o, 0);
3216 req_data = tcore_user_request_ref_data(ur, NULL);
3219 return TCORE_RETURN_EINVAL;
3221 apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
3222 memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
3223 result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
3224 apdu_len = strlen(apdu);
3225 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", apdu_len, apdu);
3226 req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
3227 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3229 tcore_pending_set_request_data(pending, 0, req);
3230 tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
3231 tcore_pending_link_user_request(pending, ur);
3232 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
3233 tcore_hal_send_request(hal, pending);
3237 dbg(" Function exit");
3238 return TCORE_RETURN_SUCCESS;
3241 static struct tcore_sim_operations sim_ops = {
3242 .verify_pins = s_verify_pins,
3243 .verify_puks = s_verify_puks,
3244 .change_pins = s_change_pins,
3245 .get_facility_status = s_get_facility_status,
3246 .enable_facility = s_enable_facility,
3247 .disable_facility = s_disable_facility,
3248 .get_lock_info = s_get_lock_info,
3249 .read_file = s_read_file,
3250 .update_file = s_update_file,
3251 .transmit_apdu = s_transmit_apdu,
3253 .req_authentication = NULL,
3256 gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
3259 struct s_sim_property *file_meta = NULL;
3264 o = tcore_sim_new(p, "sim", &sim_ops, h);
3269 file_meta = calloc(sizeof(struct s_sim_property), 1);
3273 work_queue = g_queue_new();
3274 tcore_object_link_user_data(o, work_queue);
3276 file_meta->first_recv_status = SIM_STATUS_UNKNOWN;
3277 tcore_sim_link_userdata(o, file_meta);
3279 tcore_object_add_callback(o, "+XLOCK", on_event_facility_lock_status, NULL);
3280 tcore_object_add_callback(o, "+XSIM", on_event_pin_status, NULL);
3286 void s_sim_exit(TcorePlugin *p)
3290 o = tcore_plugin_ref_core_object(p, "sim");