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 s_sim_sec_op_e current_sec_op; /**< current index to read */
102 struct tel_sim_mbi_list mbi_list;
103 struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
104 struct tresp_sim_read files;
107 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
108 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
109 static gboolean _get_sim_type(CoreObject *o);
110 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
111 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
112 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
113 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
114 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
116 static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
118 TcoreATRequest *req = NULL;
119 TcoreHal *hal = NULL;
120 TcorePending *pending = NULL;
124 hal = tcore_object_get_hal(co);
127 pending = tcore_pending_new(co, 0);
129 dbg("Pending is NULL");
130 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
132 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
134 tcore_pending_set_request_data(pending, 0, req);
135 tcore_pending_set_response_callback(pending, callback, NULL);
136 tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
137 ret = tcore_hal_send_request(hal, pending);
142 static enum tcore_response_command _find_resp_command(UserRequest *ur)
144 enum tcore_request_command command;
146 command = tcore_user_request_get_command(ur);
148 case TREQ_SIM_VERIFY_PINS:
149 return TRESP_SIM_VERIFY_PINS;
152 case TREQ_SIM_VERIFY_PUKS:
153 return TRESP_SIM_VERIFY_PUKS;
156 case TREQ_SIM_CHANGE_PINS:
157 return TRESP_SIM_CHANGE_PINS;
160 case TREQ_SIM_GET_FACILITY_STATUS:
161 return TRESP_SIM_GET_FACILITY_STATUS;
164 case TREQ_SIM_DISABLE_FACILITY:
165 return TRESP_SIM_DISABLE_FACILITY;
168 case TREQ_SIM_ENABLE_FACILITY:
169 return TRESP_SIM_ENABLE_FACILITY;
172 case TREQ_SIM_GET_LOCK_INFO:
173 return TRESP_SIM_GET_LOCK_INFO;
176 case TREQ_SIM_TRANSMIT_APDU:
177 return TRESP_SIM_TRANSMIT_APDU;
180 case TREQ_SIM_GET_ATR:
181 return TRESP_SIM_GET_ATR;
184 case TREQ_SIM_GET_ECC:
185 return TRESP_SIM_GET_ECC;
188 case TREQ_SIM_GET_LANGUAGE:
189 return TRESP_SIM_GET_LANGUAGE;
192 case TREQ_SIM_SET_LANGUAGE:
193 return TRESP_SIM_SET_LANGUAGE;
196 case TREQ_SIM_GET_ICCID:
197 return TRESP_SIM_GET_ICCID;
200 case TREQ_SIM_GET_MAILBOX:
201 return TRESP_SIM_GET_MAILBOX;
204 case TREQ_SIM_GET_CALLFORWARDING:
205 return TRESP_SIM_GET_CALLFORWARDING;
208 case TREQ_SIM_SET_CALLFORWARDING:
209 return TRESP_SIM_SET_CALLFORWARDING;
212 case TREQ_SIM_GET_MESSAGEWAITING:
213 return TRESP_SIM_GET_MESSAGEWAITING;
216 case TREQ_SIM_GET_CPHS_INFO:
217 return TRESP_SIM_GET_CPHS_INFO;
220 case TREQ_SIM_GET_MSISDN:
221 return TRESP_SIM_GET_MSISDN;
224 case TREQ_SIM_GET_SPN:
225 return TRESP_SIM_GET_SPN;
228 case TREQ_SIM_GET_SPDI:
229 return TRESP_SIM_GET_SPDI;
232 case TREQ_SIM_GET_OPL:
233 return TRESP_SIM_GET_OPL;
236 case TREQ_SIM_GET_PNN:
237 return TRESP_SIM_GET_PNN;
240 case TREQ_SIM_GET_CPHS_NETNAME:
241 return TRESP_SIM_GET_CPHS_NETNAME;
244 case TREQ_SIM_GET_OPLMNWACT:
245 return TRESP_SIM_GET_OPLMNWACT;
248 case TREQ_SIM_REQ_AUTHENTICATION:
249 return TRESP_SIM_REQ_AUTHENTICATION;
255 return TRESP_UNKNOWN;
258 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
262 dbg("current sec_op[%d]", op);
265 case SEC_PIN1_VERIFY:
266 case SEC_PIN1_CHANGE:
267 ret_type = SIM_PTYPE_PIN1;
270 case SEC_PIN2_VERIFY:
271 case SEC_PIN2_CHANGE:
272 ret_type = SIM_PTYPE_PIN2;
275 case SEC_PUK1_VERIFY:
276 ret_type = SIM_PTYPE_PUK1;
279 case SEC_PUK2_VERIFY:
280 ret_type = SIM_PTYPE_PUK2;
284 ret_type = SIM_PTYPE_SIM;
288 ret_type = SIM_PTYPE_ADM;
291 case SEC_PIN1_ENABLE:
292 case SEC_PIN1_DISABLE:
293 case SEC_PIN1_STATUS:
294 ret_type = SIM_FACILITY_SC;
298 case SEC_SIM_DISABLE:
300 ret_type = SIM_FACILITY_PS;
304 case SEC_NET_DISABLE:
306 ret_type = SIM_FACILITY_PN;
312 ret_type = SIM_FACILITY_PU;
318 ret_type = SIM_FACILITY_PP;
324 ret_type = SIM_FACILITY_PC;
328 case SEC_FDN_DISABLE:
330 ret_type = SIM_FACILITY_FD;
334 dbg("not handled current sec op[%d]", op)
340 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
342 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
344 if (status_word1 == 0x93 && status_word2 == 0x00) {
345 rst = SIM_ACCESS_FAILED;
346 /*Failed SIM request command*/
347 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
348 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
349 rst = SIM_ACCESS_FAILED;
350 /*Failed SIM request command*/
351 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
352 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
353 rst = SIM_ACCESS_FAILED;
354 /*Failed SIM request command*/
355 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
356 status_word1, status_word2);
357 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
358 rst = SIM_ACCESS_FILE_NOT_FOUND;
359 /*Failed SIM request command*/
360 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
361 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
362 rst = SIM_ACCESS_FAILED; /* MOdem not support */
363 /*Failed SIM request command*/
364 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
365 status_word1, status_word2);
366 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
367 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
368 /*Failed SIM request command*/
369 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
370 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
371 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
372 /*Failed SIM request command*/
373 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
374 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
375 status_word1, status_word2);
376 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
377 status_word1, status_word2);
378 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
379 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
380 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
381 /*Failed SIM request command*/
382 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
383 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
384 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
385 /*Failed SIM request command*/
386 dbg(" error - Contradiction with invalidation status [%x][%x]",
387 status_word1, status_word2);
388 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
389 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
390 /*Failed SIM request command*/
391 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
392 status_word1, status_word2);
393 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
394 status_word1, status_word2);
395 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
396 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
397 rst = SIM_ACCESS_FAILED;
398 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
399 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
400 rst = SIM_ACCESS_FAILED;
401 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
402 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
403 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
404 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
405 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
406 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
407 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
408 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
409 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
410 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
411 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
412 rst = SIM_ACCESS_FAILED;
413 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
414 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
415 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
416 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
417 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
418 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
419 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
421 rst = SIM_ACCESS_CARD_ERROR;
422 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
427 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
430 Storage *strg = NULL;
431 char *old_imsi = NULL;
432 char new_imsi[15 + 1] = {0, };
434 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
436 dbg("there is no valid server at this point");
439 strg = (Storage *) tcore_server_find_storage(s, "vconf");
441 dbg("there is no valid storage plugin");
444 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
445 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
446 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
448 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
449 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
451 if (old_imsi != NULL) {
452 if (strncmp(old_imsi, new_imsi, 15) != 0) {
454 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
455 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
457 tcore_sim_set_identification(o, TRUE);
460 tcore_sim_set_identification(o, FALSE);
463 dbg("OLD SIM VALUE IS NULL. NEW SIM");
464 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
465 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
467 tcore_sim_set_identification(o, TRUE);
472 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
474 struct tresp_sim_read resp = {0, };
475 struct s_sim_property *file_meta = NULL;
477 dbg("EF[0x%x] access Result[%d]", ef, rt);
480 memset(&resp.data, 0x00, sizeof(resp.data));
481 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
483 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
484 && (rt != SIM_ACCESS_SUCCESS)) {
485 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
491 if (rt == SIM_ACCESS_SUCCESS) {
492 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
493 /* if (po->language_file == 0x00)
494 po->language_file = SIM_EF_ELP;*/
495 _get_file_data(o, ur, ef, 0, file_meta->data_size);
497 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
498 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
499 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
500 _get_file_info(o, ur, SIM_EF_LP);
501 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
503 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
504 /* EFELPand EFLI not present at this point. */
505 /* po->language.lang_cnt = 0;*/
506 tcore_user_request_send_response(ur, _find_resp_command(ur),
507 sizeof(struct tresp_sim_read), &resp);
513 case SIM_EF_LP: // same with SIM_EF_USIM_LI
514 if (rt == SIM_ACCESS_SUCCESS) {
515 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
516 _get_file_data(o, ur, ef, 0, file_meta->data_size);
518 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
519 tcore_sim_get_type(o));
520 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
521 tcore_user_request_send_response(ur, _find_resp_command(ur),
522 sizeof(struct tresp_sim_read), &resp);
525 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
526 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
527 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
528 _get_file_info(o, ur, SIM_EF_ELP);
534 if (rt == SIM_ACCESS_SUCCESS) {
535 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
536 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
538 /* EFELIand EFPL not present, so set language count as zero and select ECC */
540 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
541 tcore_user_request_send_response(ur, _find_resp_command(ur),
542 sizeof(struct tresp_sim_read), &resp);
548 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
549 _get_file_data(o, ur, ef, 0, file_meta->data_size);
550 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
551 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
552 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
555 file_meta->current_index++;
556 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
565 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
566 case SIM_EF_CPHS_VOICE_MSG_WAITING:
567 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
568 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
569 case SIM_EF_CPHS_DYNAMICFLAGS:
570 case SIM_EF_CPHS_DYNAMIC2FLAG:
571 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
572 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
573 _get_file_data(o, ur, ef, 0, file_meta->data_size);
576 case SIM_EF_CPHS_CPHS_INFO:
577 if (rt == SIM_ACCESS_SUCCESS) {
578 tcore_sim_set_cphs_status(o, TRUE);
579 if (!tcore_user_request_ref_communicator(ur)) {
580 dbg("internal CPHS INFO request before sim status update");
581 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
583 dbg("external CPHS INFO request");
584 _get_file_data(o, ur, ef, 0, file_meta->data_size);
587 tcore_sim_set_cphs_status(o, FALSE);
588 if (!tcore_user_request_ref_communicator(ur)) {
589 dbg("internal CPHS INFO request before sim status update");
590 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
592 dbg("external CPHS INFO request");
593 tcore_user_request_send_response(ur, _find_resp_command(ur),
594 sizeof(struct tresp_sim_read), &resp);
600 case SIM_EF_USIM_CFIS:
601 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
602 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
604 file_meta->current_index++;
605 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
610 case SIM_EF_USIM_MWIS:
611 case SIM_EF_USIM_MBI:
613 case SIM_EF_CPHS_MAILBOX_NUMBERS:
614 case SIM_EF_CPHS_INFORMATION_NUMBERS:
616 file_meta->current_index++;
617 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
621 dbg("error - File id for get file info [0x%x]", ef);
627 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
629 struct s_sim_property *file_meta = NULL;
633 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
634 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
635 switch (file_meta->file_id) {
640 if (decode_ret == TRUE) {
641 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
642 /* po->language_file = SIM_EF_LP;*/
643 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
644 /* po->language_file = SIM_EF_ELP;*/
646 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
649 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
650 - EFELP is not available;
651 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
652 - the ME does not support any of the languages in EFELP.
655 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
656 - if the EFLI has the value 'FFFF' in its highest priority position
657 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
659 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
660 if (file_meta->file_id == SIM_EF_LP) {
661 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
663 _get_file_info(o, ur, SIM_EF_LP);
665 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
666 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
667 _get_file_info(o, ur, SIM_EF_ELP);
669 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
676 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
677 if (file_meta->current_index == file_meta->rec_count) {
678 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
680 file_meta->current_index++;
681 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
683 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
684 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
686 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
691 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
692 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
696 if (file_meta->current_index == file_meta->rec_count) {
697 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
699 file_meta->current_index++;
700 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
705 if (file_meta->current_index == file_meta->rec_count) {
706 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
708 file_meta->current_index++;
709 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
714 if (file_meta->current_index == file_meta->rec_count) {
715 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
717 file_meta->current_index++;
718 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
722 case SIM_EF_USIM_CFIS:
723 case SIM_EF_USIM_MWIS:
724 case SIM_EF_USIM_MBI:
726 case SIM_EF_CPHS_MAILBOX_NUMBERS:
727 case SIM_EF_CPHS_INFORMATION_NUMBERS:
728 if (file_meta->current_index == file_meta->rec_count) {
729 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
731 file_meta->current_index++;
732 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
736 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
737 file_meta->files.result = rt;
738 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
739 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));
741 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
744 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
745 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
746 file_meta->files.result = SIM_ACCESS_SUCCESS;
748 if (strlen((char *) file_meta->files.data.cphs_net.full_name)) {
749 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));
751 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
758 case SIM_EF_OPLMN_ACT:
759 case SIM_EF_CPHS_CPHS_INFO:
760 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
761 case SIM_EF_CPHS_VOICE_MSG_WAITING:
762 case SIM_EF_CPHS_DYNAMICFLAGS:
763 case SIM_EF_CPHS_DYNAMIC2FLAG:
764 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
765 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
766 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
770 dbg("File id not handled [0x%x]", file_meta->file_id);
775 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
777 struct tnoti_sim_status noti_data = {0, };
779 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
780 tcore_sim_set_status(o, sim_status);
781 noti_data.sim_status = sim_status;
782 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
783 sizeof(struct tnoti_sim_status), ¬i_data);
786 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
788 const TcoreATResponse *resp = data;
789 UserRequest *ur = NULL;
790 CoreObject *co_sim = NULL;
791 struct s_sim_property *sp = NULL;
792 GSList *tokens = NULL;
793 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
797 dbg(" Function entry ");
799 co_sim = tcore_pending_ref_core_object(p);
800 sp = tcore_sim_ref_userdata(co_sim);
801 ur = tcore_pending_ref_user_request(p);
803 if (resp->success > 0) {
806 line = (const char *) resp->lines->data;
807 tokens = tcore_at_tok_new(line);
808 if (g_slist_length(tokens) != 1) {
809 msg("invalid message");
810 tcore_at_tok_free(tokens);
814 state = atoi(g_slist_nth_data(tokens, 0));
815 dbg("SIM Type is %d", state);
818 sim_type = SIM_TYPE_GSM;
819 } else if (state == 1) {
820 sim_type = SIM_TYPE_USIM;
822 sim_type = SIM_TYPE_UNKNOWN;
826 sim_type = SIM_TYPE_UNKNOWN;
829 tcore_sim_set_type(co_sim, sim_type);
831 if (sim_type != SIM_TYPE_UNKNOWN) {
832 /* set user request for using ur metainfo set/ref functionality */
833 ur = tcore_user_request_new(NULL, NULL);
834 _get_file_info(co_sim, ur, SIM_EF_IMSI);
837 tcore_at_tok_free(tokens);
838 dbg(" Function exit");
841 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
843 const TcoreATResponse *resp = data;
844 UserRequest *ur = NULL;
845 CoreObject *co_sim = NULL;
846 struct s_sim_property *file_meta = NULL;
847 GSList *tokens = NULL;
848 enum tel_sim_access_result rt;
849 const char *line = NULL;
853 dbg(" Function entry ");
855 co_sim = tcore_pending_ref_core_object(p);
856 ur = tcore_pending_ref_user_request(p);
857 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
859 if (resp->success > 0) {
862 line = (const char *) resp->lines->data;
863 tokens = tcore_at_tok_new(line);
864 if (g_slist_length(tokens) < 2) {
865 err("invalid message");
866 tcore_at_tok_free(tokens);
870 sw1 = atoi(g_slist_nth_data(tokens, 0));
871 sw2 = atoi(g_slist_nth_data(tokens, 1));
873 /*1. SIM access success case*/
874 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
875 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
876 unsigned short record_len = 0;
877 char num_of_records = 0;
878 unsigned char file_id_len = 0;
879 unsigned short file_id = 0;
880 unsigned short file_size = 0;
881 unsigned short file_type = 0;
882 unsigned short arr_file_id = 0;
883 int arr_file_id_rec_num = 0;
885 /* handling only last 3 bits */
886 unsigned char file_type_tag = 0x07;
887 unsigned char *ptr_data;
891 char *recordData = NULL;
892 hexData = g_slist_nth_data(tokens, 2);
893 dbg("hexData: %s", hexData);
894 dbg("hexData: %s", hexData + 1);
896 tmp = util_removeQuotes(hexData);
897 recordData = util_hexStringToBytes(tmp);
898 util_hex_dump(" ", strlen(hexData) / 2, recordData);
901 ptr_data = (unsigned char *) recordData;
902 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
904 ETSI TS 102 221 v7.9.0
906 '62' FCP template tag
908 '82' M File Descriptor
909 '83' M File Identifier
910 'A5' O Proprietary information
911 '8A' M Life Cycle Status Integer
912 '8B', '8C' or 'AB' C1 Security attributes
914 '81' O Total file size
915 '88' O Short File Identifier (SFI)
918 /* rsim.res_len has complete data length received */
920 /* FCP template tag - File Control Parameters tag*/
921 if (*ptr_data == 0x62) {
922 /* parse complete FCP tag*/
923 /* increment to next byte */
925 tag_len = *ptr_data++;
926 dbg("tag_len: %02x", tag_len);
927 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
928 if (*ptr_data == 0x82) {
929 /* increment to next byte */
933 /* unsigned char file_desc_len = *ptr_data++;*/
934 /* dbg("file descriptor length: [%d]", file_desc_len);*/
935 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
936 /* consider only last 3 bits*/
937 dbg("file_type_tag: %02x", file_type_tag);
938 file_type_tag = file_type_tag & (*ptr_data);
939 dbg("file_type_tag: %02x", file_type_tag);
941 switch (file_type_tag) {
942 /* increment to next byte */
945 dbg("Getting FileType: [Transparent file type]");
946 file_type = SIM_FTYPE_TRANSPARENT;
948 /* increment to next byte */
950 /* increment to next byte */
955 dbg("Getting FileType: [Linear fixed file type]");
956 /* increment to next byte */
958 /* data coding byte - value 21 */
961 memcpy(&record_len, ptr_data, 2);
963 SWAPBYTES16(record_len);
964 ptr_data = ptr_data + 2;
965 num_of_records = *ptr_data++;
966 /* Data lossy conversation from enum (int) to unsigned char */
967 file_type = SIM_FTYPE_LINEAR_FIXED;
971 dbg(" Cyclic fixed file type");
972 /* increment to next byte */
974 /* data coding byte - value 21 */
977 memcpy(&record_len, ptr_data, 2);
979 SWAPBYTES16(record_len);
980 ptr_data = ptr_data + 2;
981 num_of_records = *ptr_data++;
982 file_type = SIM_FTYPE_CYCLIC;
986 dbg("not handled file type [0x%x]", *ptr_data);
990 dbg("INVALID FCP received - DEbug!");
991 tcore_at_tok_free(tokens);
996 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
997 if (*ptr_data == 0x83) {
998 /* increment to next byte */
1000 file_id_len = *ptr_data++;
1001 dbg("file_id_len: %02x", file_id_len);
1003 memcpy(&file_id, ptr_data, file_id_len);
1004 dbg("file_id: %x", file_id);
1007 SWAPBYTES16(file_id);
1008 dbg("file_id: %x", file_id);
1010 ptr_data = ptr_data + 2;
1011 dbg("Getting FileID=[0x%x]", file_id);
1013 dbg("INVALID FCP received - DEbug!");
1014 tcore_at_tok_free(tokens);
1019 /* proprietary information */
1020 if (*ptr_data == 0xA5) {
1021 unsigned short prop_len;
1022 /* increment to next byte */
1026 prop_len = *ptr_data;
1027 dbg("prop_len: %02x", prop_len);
1030 ptr_data = ptr_data + prop_len + 1;
1032 dbg("INVALID FCP received - DEbug!");
1035 /* life cycle status integer [8A][length:0x01][status]*/
1038 00000000 : No information given
1039 00000001 : creation state
1040 00000011 : initialization state
1041 000001-1 : operation state -activated
1042 000001-0 : operation state -deactivated
1043 000011-- : Termination state
1044 b8~b5 !=0, b4~b1=X : Proprietary
1045 Any other value : RFU
1047 if (*ptr_data == 0x8A) {
1048 /* increment to next byte */
1050 /* length - value 1 */
1053 switch (*ptr_data) {
1056 dbg("<RX> operation state -deactivated");
1062 dbg("<RX> operation state -activated");
1067 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1073 /* related to security attributes : currently not handled*/
1074 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1075 /* increment to next byte */
1077 /* if tag length is 3 */
1078 if (*ptr_data == 0x03) {
1079 /* increment to next byte */
1082 memcpy(&arr_file_id, ptr_data, 2);
1084 SWAPBYTES16(arr_file_id);
1085 ptr_data = ptr_data + 2;
1086 arr_file_id_rec_num = *ptr_data++;
1088 /* if tag length is not 3 */
1089 /* ignoring bytes */
1090 // ptr_data = ptr_data + 4;
1091 dbg("Useless security attributes, so jump to next tag");
1092 ptr_data = ptr_data + (*ptr_data + 1);
1095 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1096 tcore_at_tok_free(tokens);
1101 dbg("Current ptr_data value is [%x]", *ptr_data);
1103 /* file size excluding structural info*/
1104 if (*ptr_data == 0x80) {
1105 /* for EF file size is body of file and for Linear or cyclic it is
1106 * number of recXsizeof(one record)
1108 /* increment to next byte */
1110 /* length is 1 byte - value is 2 bytes or more */
1112 memcpy(&file_size, ptr_data, 2);
1114 SWAPBYTES16(file_size);
1115 ptr_data = ptr_data + 2;
1117 dbg("INVALID FCP received - DEbug!");
1118 tcore_at_tok_free(tokens);
1123 /* total file size including structural info*/
1124 if (*ptr_data == 0x81) {
1126 /* increment to next byte */
1131 ptr_data = ptr_data + 3;
1133 dbg("INVALID FCP received - DEbug!");
1134 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1137 /*short file identifier ignored*/
1138 if (*ptr_data == 0x88) {
1139 dbg("0x88: Do Nothing");
1143 dbg("INVALID FCP received - DEbug!");
1144 tcore_at_tok_free(tokens);
1148 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1149 unsigned char gsm_specific_file_data_len = 0;
1150 /* ignore RFU byte1 and byte2 */
1154 // file_size = p_info->response_len;
1155 memcpy(&file_size, ptr_data, 2);
1157 SWAPBYTES16(file_size);
1158 /* parsed file size */
1159 ptr_data = ptr_data + 2;
1161 memcpy(&file_id, ptr_data, 2);
1162 SWAPBYTES16(file_id);
1163 dbg(" FILE id --> [%x]", file_id);
1164 ptr_data = ptr_data + 2;
1165 /* save file type - transparent, linear fixed or cyclic */
1166 file_type_tag = (*(ptr_data + 7));
1168 switch (*ptr_data) {
1171 dbg(" RFU file type- not handled - Debug!");
1176 dbg(" MF file type - not handled - Debug!");
1181 dbg(" DF file type - not handled - Debug!");
1186 dbg(" EF file type [%d] ", file_type_tag);
1187 /* increment to next byte */
1190 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1191 /* increament to next byte as this byte is RFU */
1194 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1196 /* increment to next byte */
1198 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1199 /* the INCREASE command is allowed on the selected cyclic file. */
1200 file_type = SIM_FTYPE_CYCLIC;
1202 /* bytes 9 to 11 give SIM file access conditions */
1204 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1206 /* byte 11 is invalidate and rehabilate nibbles */
1208 /* byte 12 - file status */
1210 /* byte 13 - GSM specific data */
1211 gsm_specific_file_data_len = *ptr_data;
1213 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1215 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1216 record_len = *ptr_data;
1217 dbg("record length[%d], file size[%d]", record_len, file_size);
1219 if (record_len != 0)
1220 num_of_records = (file_size / record_len);
1222 dbg("Number of records [%d]", num_of_records);
1226 dbg(" not handled file type");
1230 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1233 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1234 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1236 file_meta->file_type = file_type;
1237 file_meta->data_size = file_size;
1238 file_meta->rec_length = record_len;
1239 file_meta->rec_count = num_of_records;
1240 file_meta->current_index = 0; // reset for new record type EF
1241 rt = SIM_ACCESS_SUCCESS;
1244 /*2. SIM access fail case*/
1245 dbg("error to get ef[0x%x]", file_meta->file_id);
1246 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1247 rt = _decode_status_word(sw1, sw2);
1249 ur = tcore_user_request_ref(ur);
1251 dbg("Calling _next_from_get_file_info");
1252 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1253 tcore_at_tok_free(tokens);
1255 dbg("RESPONSE NOK");
1256 dbg("error to get ef[0x%x]", file_meta->file_id);
1257 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1258 rt = SIM_ACCESS_FAILED;
1260 ur = tcore_user_request_ref(ur);
1261 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1263 dbg(" Function exit");
1266 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1268 const TcoreATResponse *resp = data;
1269 UserRequest *ur = NULL;
1270 CoreObject *co_sim = NULL;
1271 struct s_sim_property *file_meta = NULL;
1272 GSList *tokens = NULL;
1273 enum tel_sim_access_result rt;
1274 struct tel_sim_imsi *imsi = NULL;
1275 struct tel_sim_service_table *svct = NULL;
1276 struct tel_sim_ecc *ecc = NULL;
1277 struct tel_sim_msisdn *msisdn = NULL;
1278 struct tel_sim_opl *opl = NULL;
1279 struct tel_sim_pnn *pnn = NULL;
1280 struct tel_sim_cfis *cf = NULL;
1281 struct tel_sim_mbi *mbi = NULL;
1282 struct tel_sim_mw *mw = NULL;
1283 gboolean dr = FALSE;
1284 const char *line = NULL;
1291 dbg(" Function entry ");
1293 co_sim = tcore_pending_ref_core_object(p);
1294 ur = tcore_pending_ref_user_request(p);
1295 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
1297 if (resp->success > 0) {
1300 line = (const char *) resp->lines->data;
1301 tokens = tcore_at_tok_new(line);
1302 if (g_slist_length(tokens) != 3) {
1303 msg("invalid message");
1304 tcore_at_tok_free(tokens);
1308 sw1 = atoi(g_slist_nth_data(tokens, 0));
1309 sw2 = atoi(g_slist_nth_data(tokens, 1));
1310 res = g_slist_nth_data(tokens, 2);
1312 tmp = util_removeQuotes(res);
1313 res = util_hexStringToBytes(tmp);
1314 res_len = strlen((const char *) res);
1315 dbg("res: %s res_len: %d", res, res_len);
1317 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1318 rt = SIM_ACCESS_SUCCESS;
1319 file_meta->files.result = rt;
1320 dbg("file_meta->file_id : %x", file_meta->file_id);
1322 switch (file_meta->file_id) {
1325 dbg("res: %s", res);
1326 imsi = calloc(sizeof(struct tel_sim_imsi),1);
1327 dr = tcore_sim_decode_imsi(imsi, (unsigned char *) res, res_len);
1329 dbg("imsi decoding failed");
1331 _sim_check_identity(co_sim, imsi);
1332 tcore_sim_set_imsi(co_sim, imsi);
1340 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
1343 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
1344 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1345 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
1346 case SIM_EF_LP: /* 1 byte encoding*/
1347 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1348 /*2G LP(0x6F05) has 1 byte for each language*/
1349 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
1351 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1352 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
1357 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
1361 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
1364 case SIM_EF_SST: //EF UST has same address
1365 svct = calloc(sizeof(struct tel_sim_service_table),1);
1366 if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1367 dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *) res, res_len);
1368 }else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1369 dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *) res, res_len);
1371 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1374 dbg("SST/UST decoding failed");
1376 tcore_sim_set_service_table(co_sim, svct);
1383 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1384 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
1385 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1386 ecc = calloc(sizeof(struct tel_sim_ecc),1);
1387 dbg("decode w/ index [%d]", file_meta->current_index);
1388 dr = tcore_sim_decode_uecc(ecc, (unsigned char *) res, res_len);
1390 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1391 file_meta->files.data.ecc.ecc_count++;
1396 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
1401 dbg("decode w/ index [%d]", file_meta->current_index);
1402 msisdn = calloc(sizeof(struct tel_sim_msisdn),1);
1403 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *) res, res_len);
1405 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], msisdn, sizeof(struct tel_sim_msisdn));
1406 file_meta->files.data.msisdn_list.count++;
1413 dbg("decode w/ index [%d]", file_meta->current_index);
1414 opl = calloc(sizeof(struct tel_sim_opl),1);
1415 dr = tcore_sim_decode_opl(opl, (unsigned char *) res, res_len);
1417 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], opl, sizeof(struct tel_sim_opl));
1418 file_meta->files.data.opl.opl_count++;
1423 dbg("decode w/ index [%d]", file_meta->current_index);
1424 pnn = calloc(sizeof(struct tel_sim_pnn),1);
1425 dr = tcore_sim_decode_pnn(pnn, (unsigned char *) res, res_len);
1427 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], pnn, sizeof(struct tel_sim_pnn));
1428 file_meta->files.data.pnn.pnn_count++;
1434 case SIM_EF_OPLMN_ACT:
1435 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
1438 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1439 /* dr = tcore_sim_decode_csp(&po->p_cphs->csp, p_data->response, p_data->response_len);*/
1442 case SIM_EF_USIM_MBI: //linear type
1443 mbi = calloc(sizeof(struct tel_sim_mbi),1);
1444 dr = tcore_sim_decode_mbi(mbi, (unsigned char *) res, res_len);
1446 memcpy( &file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count], mbi, sizeof(struct tel_sim_mbi) );
1447 file_meta->mbi_list.profile_count++;
1448 dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
1449 dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
1450 dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
1451 dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
1452 dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
1453 dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
1459 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1460 case SIM_EF_MBDN: //linear type
1461 dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info, (unsigned char *) res, res_len);
1462 file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
1465 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1466 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw, (unsigned char *) res, res_len);
1469 case SIM_EF_USIM_MWIS: //linear type
1470 mw = calloc(sizeof(struct tel_sim_mw),1);
1471 dr = tcore_sim_decode_mwis(mw, (unsigned char *) res, res_len);
1473 memcpy( &file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw) );
1474 file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
1475 file_meta->files.data.mw.mw_list.profile_count++;
1481 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
1482 dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf, (unsigned char *) res, res_len);
1485 case SIM_EF_USIM_CFIS: //linear type
1486 cf = calloc(sizeof(struct tel_sim_cfis),1);
1487 dr = tcore_sim_decode_cfis(cf, (unsigned char *) res, res_len);
1489 memcpy( &file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count], cf, sizeof(struct tel_sim_cfis) );
1490 file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
1491 file_meta->files.data.cf.cf_list.profile_count++;
1497 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1498 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1501 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1502 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
1503 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);
1506 case SIM_EF_CPHS_DYNAMICFLAGS:
1507 /* dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, p_data->response, p_data->response_len);*/
1510 case SIM_EF_CPHS_DYNAMIC2FLAG:
1511 /* dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response, p_data->response_len);*/
1514 case SIM_EF_CPHS_CPHS_INFO:
1515 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
1518 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1519 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
1522 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1523 /* dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1527 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1532 rt = _decode_status_word(sw1, sw2);
1533 file_meta->files.result = rt;
1537 tcore_at_tok_free(tokens);
1539 dbg("RESPONSE NOK");
1540 dbg("error to get ef[0x%x]", file_meta->file_id);
1541 rt = SIM_ACCESS_FAILED;
1543 ur = tcore_user_request_ref(ur);
1545 dbg("Calling _next_from_get_file_data");
1546 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1547 dbg(" Function exit");
1550 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1552 const TcoreATResponse *resp = data;
1553 UserRequest *ur = NULL;
1554 CoreObject *co_sim = NULL;
1555 struct s_sim_property *sp = NULL;
1556 GSList *tokens = NULL;
1557 const char *line = NULL;
1558 struct tresp_sim_verify_pins v_pin = {0, };
1559 struct tresp_sim_verify_puks v_puk = {0, };
1560 struct tresp_sim_change_pins change_pin = {0, };
1561 struct tresp_sim_disable_facility dis_facility = {0, };
1562 struct tresp_sim_enable_facility en_facility = {0, };
1564 int attempts_left = 0;
1565 int time_penalty = 0;
1567 dbg(" Function entry ");
1569 co_sim = tcore_pending_ref_core_object(p);
1570 sp = tcore_sim_ref_userdata(co_sim);
1571 ur = tcore_pending_ref_user_request(p);
1573 if (resp->success > 0) {
1576 line = (const char *) resp->lines->data;
1577 tokens = tcore_at_tok_new(line);
1578 if (g_slist_length(tokens) < 3) {
1579 msg("invalid message");
1580 tcore_at_tok_free(tokens);
1584 lock_type = atoi(g_slist_nth_data(tokens, 0));
1585 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1586 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1588 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1589 lock_type, attempts_left, time_penalty);
1591 switch (sp->current_sec_op) {
1592 case SEC_PIN1_VERIFY:
1593 case SEC_PIN2_VERIFY:
1594 case SEC_SIM_VERIFY:
1595 case SEC_ADM_VERIFY:
1596 v_pin.result = SIM_INCORRECT_PASSWORD;
1597 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1598 v_pin.retry_count = attempts_left;
1599 tcore_user_request_send_response(ur, _find_resp_command(ur),
1600 sizeof(struct tresp_sim_verify_pins), &v_pin);
1603 case SEC_PUK1_VERIFY:
1604 case SEC_PUK2_VERIFY:
1605 v_puk.result = SIM_INCORRECT_PASSWORD;
1606 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1607 v_puk.retry_count = attempts_left;
1608 tcore_user_request_send_response(ur, _find_resp_command(ur),
1609 sizeof(struct tresp_sim_verify_puks), &v_puk);
1612 case SEC_PIN1_CHANGE:
1613 case SEC_PIN2_CHANGE:
1614 change_pin.result = SIM_INCORRECT_PASSWORD;
1615 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1616 change_pin.retry_count = attempts_left;
1617 tcore_user_request_send_response(ur, _find_resp_command(ur),
1618 sizeof(struct tresp_sim_change_pins), &change_pin);
1621 case SEC_PIN1_DISABLE:
1622 case SEC_PIN2_DISABLE:
1623 case SEC_FDN_DISABLE:
1624 case SEC_SIM_DISABLE:
1625 case SEC_NET_DISABLE:
1626 case SEC_NS_DISABLE:
1627 case SEC_SP_DISABLE:
1628 case SEC_CP_DISABLE:
1629 dis_facility.result = SIM_INCORRECT_PASSWORD;
1630 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1631 dis_facility.retry_count = attempts_left;
1632 tcore_user_request_send_response(ur, _find_resp_command(ur),
1633 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1636 case SEC_PIN1_ENABLE:
1637 case SEC_PIN2_ENABLE:
1638 case SEC_FDN_ENABLE:
1639 case SEC_SIM_ENABLE:
1640 case SEC_NET_ENABLE:
1644 en_facility.result = SIM_INCORRECT_PASSWORD;
1645 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1646 en_facility.retry_count = attempts_left;
1647 tcore_user_request_send_response(ur, _find_resp_command(ur),
1648 sizeof(struct tresp_sim_enable_facility), &en_facility);
1652 dbg("not handled sec op[%d]", sp->current_sec_op);
1655 tcore_at_tok_free(tokens);
1657 dbg(" Function exit");
1660 static gboolean _get_sim_type(CoreObject *o)
1662 TcoreHal *hal = NULL;
1663 TcoreATRequest *req = NULL;
1664 TcorePending *pending = NULL;
1665 UserRequest *ur = NULL;
1666 char *cmd_str = NULL;
1668 dbg(" Function entry ");
1670 hal = tcore_object_get_hal(o);
1671 pending = tcore_pending_new(o, 0);
1673 cmd_str = g_strdup_printf("AT+XUICC?");
1674 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1676 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1678 tcore_pending_set_request_data(pending, 0, req);
1679 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1680 tcore_pending_link_user_request(pending, ur);
1681 tcore_hal_send_request(hal, pending);
1684 dbg(" Function exit");
1688 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1690 TcoreHal *hal = NULL;
1691 TcorePending *pending = NULL;
1692 struct s_sim_property file_meta = {0, };
1693 char *cmd_str = NULL;
1694 TReturn ret = TCORE_RETURN_FAILURE;
1697 dbg(" Function entry ");
1699 file_meta.file_id = ef;
1700 dbg("file_meta.file_id: %d", file_meta.file_id);
1701 hal = tcore_object_get_hal(o);
1702 dbg("hal: %x", hal);
1704 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1705 dbg("trt[%d]", trt);
1706 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1707 dbg("cmd_str: %s", cmd_str);
1709 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1710 tcore_pending_link_user_request(pending, ur);
1711 ret = tcore_hal_send_request(hal, pending);
1712 if (TCORE_RETURN_SUCCESS != ret) {
1713 tcore_user_request_free(ur);
1716 dbg(" Function exit");
1717 return TCORE_RETURN_SUCCESS;
1720 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1722 TcoreHal *hal = NULL;
1723 TcoreATRequest *req = NULL;
1724 TcorePending *pending = NULL;
1725 char *cmd_str = NULL;
1730 dbg(" Function entry ");
1731 hal = tcore_object_get_hal(o);
1732 pending = tcore_pending_new(o, 0);
1734 dbg("file_id: %x", ef);
1736 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1737 p2 = (unsigned char) offset & 0x00FF; // offset low
1738 p3 = (unsigned char) length;
1740 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1742 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1744 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1746 tcore_pending_set_request_data(pending, 0, req);
1747 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1748 tcore_pending_link_user_request(pending, ur);
1749 tcore_hal_send_request(hal, pending);
1752 dbg(" Function exit");
1756 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1758 TcoreHal *hal = NULL;
1759 TcoreATRequest *req = NULL;
1760 TcorePending *pending = NULL;
1761 char *cmd_str = NULL;
1766 dbg(" Function entry ");
1768 hal = tcore_object_get_hal(o);
1769 pending = tcore_pending_new(o, 0);
1771 p1 = (unsigned char) index;
1772 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1773 p3 = (unsigned char) length;
1775 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1777 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1779 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1781 tcore_pending_set_request_data(pending, 0, req);
1782 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1783 tcore_pending_link_user_request(pending, ur);
1784 tcore_hal_send_request(hal, pending);
1787 dbg(" Function exit");
1791 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1793 TcoreHal *hal = NULL;
1794 TcoreATRequest *req = NULL;
1795 TcorePending *pending = NULL;
1796 char *cmd_str = NULL;
1798 struct s_sim_property *sp = NULL;
1799 const struct treq_sim_get_lock_info *req_data = NULL;
1801 dbg(" Function entry ");
1803 hal = tcore_object_get_hal(o);
1804 pending = tcore_pending_new(o, 0);
1805 req_data = tcore_user_request_ref_data(ur, NULL);
1806 sp = tcore_sim_ref_userdata(o);
1808 switch (sp->current_sec_op) {
1809 case SEC_PIN1_VERIFY:
1810 case SEC_PIN1_CHANGE:
1811 case SEC_PIN1_ENABLE:
1812 case SEC_PIN1_DISABLE:
1816 case SEC_PIN2_VERIFY:
1817 case SEC_PIN2_CHANGE:
1818 case SEC_PIN2_ENABLE:
1819 case SEC_PIN2_DISABLE:
1820 case SEC_FDN_ENABLE:
1821 case SEC_FDN_DISABLE:
1825 case SEC_PUK1_VERIFY:
1829 case SEC_PUK2_VERIFY:
1833 case SEC_NET_ENABLE:
1834 case SEC_NET_DISABLE:
1839 case SEC_NS_DISABLE:
1844 case SEC_SP_DISABLE:
1849 case SEC_CP_DISABLE:
1853 case SEC_ADM_VERIFY:
1861 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1862 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1863 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1865 tcore_pending_set_request_data(pending, 0, req);
1866 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1867 tcore_pending_link_user_request(pending, ur);
1868 tcore_hal_send_request(hal, pending);
1871 dbg(" Function exit");
1872 return TCORE_RETURN_SUCCESS;
1876 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1878 struct s_sim_property *sp = NULL;
1880 GSList *tokens = NULL;
1881 GSList *lines = NULL;
1883 dbg("Function entry");
1886 sp = tcore_sim_ref_userdata(o);
1887 lines = (GSList *) event_info;
1888 if (1 != g_slist_length(lines)) {
1889 dbg("unsolicited msg but multiple line");
1892 line = (char *) (lines->data);
1893 tokens = tcore_at_tok_new(line);
1894 if (g_slist_length(tokens) != 1) {
1895 msg("invalid message");
1896 tcore_at_tok_free(tokens);
1901 dbg(" Function exit");
1903 tcore_at_tok_free(tokens);
1908 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1911 struct s_sim_property *sp = NULL;
1912 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1913 GSList *tokens = NULL;
1914 GSList *lines = NULL;
1915 const char *line = NULL;
1918 dbg(" Function entry ");
1920 sp = tcore_sim_ref_userdata(o);
1922 lines = (GSList *) event_info;
1923 if (1 != g_slist_length(lines)) {
1924 dbg("unsolicited msg but multiple line");
1927 line = (char *) (lines->data);
1929 tokens = tcore_at_tok_new(line);
1931 if (g_slist_length(tokens) == 4) {
1932 sim_state = atoi(g_slist_nth_data(tokens, 1));
1933 } else if (g_slist_length(tokens) == 1)
1934 sim_state = atoi(g_slist_nth_data(tokens, 0));
1936 msg("invalid message");
1937 tcore_at_tok_free(tokens);
1941 switch (sim_state) {
1942 case 0: // sim state = SIM not present
1943 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1947 case 1: // sim state = PIN verification needed
1948 sim_status = SIM_STATUS_PIN_REQUIRED;
1949 dbg(" PIN required");
1952 case 2: // sim state = PIN verification not needed \96 Ready
1953 case 3: // sim state = PIN verified \96 Ready
1954 sim_status = SIM_STATUS_INITIALIZING;
1955 dbg(" Inside PIN disabled at BOOT UP");
1958 case 4: // sim state = PUK verification needed
1959 sim_status = SIM_STATUS_PUK_REQUIRED;
1960 dbg(" PUK required");
1963 case 5: // sim state = SIM permanently blocked
1964 sim_status = SIM_STATUS_CARD_BLOCKED;
1965 dbg(" Card permanently blocked");
1968 case 6: // sim state = SIM error
1969 sim_status = SIM_STATUS_CARD_ERROR;
1970 dbg("SIM card error ");
1973 case 7: // sim state = ready for attach (+COPS)
1974 sim_status = SIM_STATUS_INIT_COMPLETED;
1975 dbg("Modem init completed");
1978 case 8: // sim state = SIM Technical Problem
1979 sim_status = SIM_STATUS_CARD_ERROR;
1980 dbg("SIM unavailable");
1983 case 9: // sim state = SIM removed
1984 sim_status = SIM_STATUS_CARD_REMOVED;
1988 case 99: // sim state = SIM State Unknown
1989 sim_status = SIM_STATUS_UNKNOWN;
1990 dbg("SIM State Unknown");
1994 dbg("SIM Status : %d", sim_status);
1998 dbg(" not handled SEC lock type ");
2002 switch (sim_status) {
2003 case SIM_STATUS_INIT_COMPLETED:
2004 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN)
2007 _sim_status_update(o, sim_status);
2010 case SIM_STATUS_INITIALIZING:
2011 case SIM_STATUS_PIN_REQUIRED:
2012 case SIM_STATUS_PUK_REQUIRED:
2013 case SIM_STATUS_CARD_BLOCKED:
2014 case SIM_STATUS_NCK_REQUIRED:
2015 case SIM_STATUS_NSCK_REQUIRED:
2016 case SIM_STATUS_SPCK_REQUIRED:
2017 case SIM_STATUS_CCK_REQUIRED:
2018 case SIM_STATUS_LOCK_REQUIRED:
2019 _sim_status_update(o, sim_status);
2022 case SIM_STATUS_CARD_REMOVED:
2023 case SIM_STATUS_CARD_NOT_PRESENT:
2024 case SIM_STATUS_CARD_ERROR:
2025 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
2026 dbg("[SIM]SIM CARD REMOVED!!");
2027 sim_status = SIM_STATUS_CARD_REMOVED;
2030 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2031 _sim_status_update(o, sim_status);
2035 dbg("not handled status[%d]", sim_status);
2040 dbg(" Function exit");
2042 tcore_at_tok_free(tokens);
2046 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2048 const TcoreATResponse *resp = data;
2049 CoreObject *co_sim = NULL;
2051 dbg(" Function entry ");
2053 co_sim = tcore_pending_ref_core_object(p);
2055 if (resp->success > 0) {
2058 on_event_pin_status(co_sim, resp->lines, NULL);
2060 dbg("RESPONSE NOK");
2063 dbg(" Function exit");
2066 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2067 unsigned int data_len, void *data, void *user_data)
2069 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2070 CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2073 return TCORE_HOOK_RETURN_CONTINUE;
2075 dbg("Get SIM status");
2077 sim_prepare_and_send_pending_request(co_sim, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2079 return TCORE_HOOK_RETURN_CONTINUE;
2082 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2084 const TcoreATResponse *resp = data;
2085 UserRequest *ur = NULL;
2086 CoreObject *co_sim = NULL;
2087 struct s_sim_property *sp = NULL;
2088 GSList *tokens = NULL;
2089 struct tresp_sim_verify_pins res;
2090 GQueue *queue = NULL;
2094 dbg(" Function entry ");
2096 co_sim = tcore_pending_ref_core_object(p);
2097 sp = tcore_sim_ref_userdata(co_sim);
2098 ur = tcore_pending_ref_user_request(p);
2100 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2102 if (resp->success > 0) {
2104 res.result = SIM_PIN_OPERATION_SUCCESS;
2105 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2106 if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
2107 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
2108 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2110 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2112 dbg("RESPONSE NOK");
2113 line = (const char *) resp->final_response;
2114 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;
2118 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2120 err = atoi(g_slist_nth_data(tokens, 0));
2121 dbg("on_response_verify_pins: err = %d", err);
2122 queue = tcore_object_ref_user_data(co_sim);
2123 ur = tcore_user_request_ref(ur);
2124 _get_retry_count(co_sim, ur);
2126 tcore_at_tok_free(tokens);
2128 dbg(" Function exit");
2131 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2133 const TcoreATResponse *resp = data;
2134 UserRequest *ur = NULL;
2135 CoreObject *co_sim = NULL;
2136 struct s_sim_property *sp = NULL;
2137 GSList *tokens = NULL;
2138 struct tresp_sim_verify_puks res;
2139 GQueue *queue = NULL;
2143 dbg(" Function entry ");
2145 co_sim = tcore_pending_ref_core_object(p);
2146 sp = tcore_sim_ref_userdata(co_sim);
2147 ur = tcore_pending_ref_user_request(p);
2149 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2151 if (resp->success > 0) {
2153 res.result = SIM_PIN_OPERATION_SUCCESS;
2154 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2155 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2157 dbg("RESPONSE NOK");
2158 line = (const char *) resp->final_response;
2159 tokens = tcore_at_tok_new(line);
2161 if (g_slist_length(tokens) < 1) {
2162 dbg("err cause not specified or string corrupted");
2163 res.result = TCORE_RETURN_3GPP_ERROR;
2164 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_verify_pins), &res);
2166 err = atoi(g_slist_nth_data(tokens, 0));
2167 queue = tcore_object_ref_user_data(co_sim);
2168 ur = tcore_user_request_ref(ur);
2169 _get_retry_count(co_sim, ur);
2171 tcore_at_tok_free(tokens);
2173 dbg(" Function exit");
2176 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2178 const TcoreATResponse *resp = data;
2179 UserRequest *ur = NULL;
2180 CoreObject *co_sim = NULL;
2181 struct s_sim_property *sp = NULL;
2182 GSList *tokens = NULL;
2183 struct tresp_sim_change_pins res;
2188 dbg(" Function entry ");
2190 co_sim = tcore_pending_ref_core_object(p);
2191 sp = tcore_sim_ref_userdata(co_sim);
2192 ur = tcore_pending_ref_user_request(p);
2194 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2196 if (resp->success > 0) {
2198 res.result = SIM_PIN_OPERATION_SUCCESS;
2199 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2200 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2202 dbg("RESPONSE NOK");
2203 line = (const char *) resp->final_response;
2204 tokens = tcore_at_tok_new(line);
2206 if (g_slist_length(tokens) < 1) {
2207 dbg("err cause not specified or string corrupted");
2208 res.result = TCORE_RETURN_3GPP_ERROR;
2209 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_change_pins), &res);
2211 err = atoi(g_slist_nth_data(tokens, 0));
2212 queue = tcore_object_ref_user_data(co_sim);
2213 ur = tcore_user_request_ref(ur);
2214 _get_retry_count(co_sim, ur);
2216 tcore_at_tok_free(tokens);
2218 dbg(" Function exit");
2221 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2223 const TcoreATResponse *resp = data;
2224 UserRequest *ur = NULL;
2225 CoreObject *co_sim = NULL;
2226 struct s_sim_property *sp = NULL;
2227 GSList *tokens = NULL;
2228 struct tresp_sim_get_facility_status res;
2231 dbg(" Function entry ");
2233 co_sim = tcore_pending_ref_core_object(p);
2234 sp = tcore_sim_ref_userdata(co_sim);
2235 ur = tcore_pending_ref_user_request(p);
2237 memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
2239 res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2240 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2242 if (resp->success > 0) {
2245 line = (const char *) resp->lines->data;
2246 tokens = tcore_at_tok_new(line);
2247 if (g_slist_length(tokens) != 1) {
2248 msg("invalid message");
2252 res.b_enable = atoi(g_slist_nth_data(tokens, 0));
2254 dbg("RESPONSE NOK");
2258 tcore_user_request_send_response(ur, _find_resp_command(ur),
2259 sizeof(struct tresp_sim_get_facility_status), &res);
2261 tcore_at_tok_free(tokens);
2262 dbg(" Function exit");
2265 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2267 const TcoreATResponse *resp = data;
2268 UserRequest *ur = NULL;
2269 CoreObject *co_sim = NULL;
2270 struct s_sim_property *sp = NULL;
2271 GSList *tokens = NULL;
2272 struct tresp_sim_enable_facility res;
2276 dbg(" Function entry ");
2278 co_sim = tcore_pending_ref_core_object(p);
2279 sp = tcore_sim_ref_userdata(co_sim);
2280 ur = tcore_pending_ref_user_request(p);
2282 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2284 res.result = SIM_CARD_ERROR;
2285 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2287 if (resp->success > 0) {
2290 line = (const char *) resp->lines->data;
2291 tokens = tcore_at_tok_new(line);
2292 if (g_slist_length(tokens) != 1) {
2293 msg("invalid message");
2294 tcore_user_request_send_response(ur, _find_resp_command(ur),
2295 sizeof(struct tresp_sim_enable_facility), &res);
2296 tcore_at_tok_free(tokens);
2300 res.result = SIM_PIN_OPERATION_SUCCESS;
2302 tcore_user_request_send_response(ur, _find_resp_command(ur),
2303 sizeof(struct tresp_sim_enable_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_disable_facility(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;
2322 struct tresp_sim_disable_facility res;
2326 dbg(" Function entry ");
2328 co_sim = tcore_pending_ref_core_object(p);
2329 sp = tcore_sim_ref_userdata(co_sim);
2330 ur = tcore_pending_ref_user_request(p);
2332 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2334 res.result = SIM_CARD_ERROR;
2335 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2337 if (resp->success > 0) {
2340 line = (const char *) resp->lines->data;
2341 tokens = tcore_at_tok_new(line);
2342 if (g_slist_length(tokens) != 1) {
2343 msg("invalid message");
2344 tcore_user_request_send_response(ur, _find_resp_command(ur),
2345 sizeof(struct tresp_sim_disable_facility), &res);
2346 tcore_at_tok_free(tokens);
2350 res.result = SIM_PIN_OPERATION_SUCCESS;
2352 tcore_user_request_send_response(ur, _find_resp_command(ur),
2353 sizeof(struct tresp_sim_disable_facility), &res);
2355 tcore_at_tok_free(tokens);
2357 dbg("RESPONSE NOK");
2358 queue = tcore_object_ref_user_data(co_sim);
2359 ur = tcore_user_request_ref(ur);
2360 _get_retry_count(co_sim, ur);
2362 dbg(" Function exit");
2365 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2367 const TcoreATResponse *resp = data;
2368 UserRequest *ur = NULL;
2369 CoreObject *co_sim = NULL;
2370 struct s_sim_property *sp = NULL;
2371 GSList *tokens = NULL;
2373 struct tresp_sim_verify_pins v_pin = {0, };
2374 struct tresp_sim_verify_puks v_puk = {0, };
2375 struct tresp_sim_change_pins change_pin = {0, };
2376 struct tresp_sim_disable_facility dis_facility = {0, };
2377 struct tresp_sim_enable_facility en_facility = {0, };
2379 int attempts_left = 0;
2380 int time_penalty = 0;
2382 dbg(" Function entry ");
2384 co_sim = tcore_pending_ref_core_object(p);
2385 sp = tcore_sim_ref_userdata(co_sim);
2386 ur = tcore_pending_ref_user_request(p);
2388 if (resp->success > 0) {
2391 line = (const char *) resp->lines->data;
2392 tokens = tcore_at_tok_new(line);
2393 if (g_slist_length(tokens) != 3) {
2394 msg("invalid message");
2395 tcore_at_tok_free(tokens);
2399 lock_type = atoi(g_slist_nth_data(tokens, 0));
2400 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2401 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2403 switch (sp->current_sec_op) {
2404 case SEC_PIN1_VERIFY:
2405 case SEC_PIN2_VERIFY:
2406 case SEC_SIM_VERIFY:
2407 case SEC_ADM_VERIFY:
2408 v_pin.result = SIM_INCORRECT_PASSWORD;
2409 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2410 v_pin.retry_count = attempts_left;
2411 tcore_user_request_send_response(ur, _find_resp_command(ur),
2412 sizeof(struct tresp_sim_verify_pins), &v_pin);
2415 case SEC_PUK1_VERIFY:
2416 case SEC_PUK2_VERIFY:
2417 v_puk.result = SIM_INCORRECT_PASSWORD;
2418 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2419 v_puk.retry_count = attempts_left;
2420 tcore_user_request_send_response(ur, _find_resp_command(ur),
2421 sizeof(struct tresp_sim_verify_puks), &v_puk);
2424 case SEC_PIN1_CHANGE:
2425 case SEC_PIN2_CHANGE:
2426 change_pin.result = SIM_INCORRECT_PASSWORD;
2427 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2428 change_pin.retry_count = attempts_left;
2429 tcore_user_request_send_response(ur, _find_resp_command(ur),
2430 sizeof(struct tresp_sim_change_pins), &change_pin);
2433 case SEC_PIN1_DISABLE:
2434 case SEC_PIN2_DISABLE:
2435 case SEC_FDN_DISABLE:
2436 case SEC_SIM_DISABLE:
2437 case SEC_NET_DISABLE:
2438 case SEC_NS_DISABLE:
2439 case SEC_SP_DISABLE:
2440 case SEC_CP_DISABLE:
2441 dis_facility.result = SIM_INCORRECT_PASSWORD;
2442 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2443 dis_facility.retry_count = attempts_left;
2444 tcore_user_request_send_response(ur, _find_resp_command(ur),
2445 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2448 case SEC_PIN1_ENABLE:
2449 case SEC_PIN2_ENABLE:
2450 case SEC_FDN_ENABLE:
2451 case SEC_SIM_ENABLE:
2452 case SEC_NET_ENABLE:
2456 en_facility.result = SIM_INCORRECT_PASSWORD;
2457 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2458 en_facility.retry_count = attempts_left;
2459 tcore_user_request_send_response(ur, _find_resp_command(ur),
2460 sizeof(struct tresp_sim_enable_facility), &en_facility);
2464 dbg("not handled sec op[%d]", sp->current_sec_op);
2467 tcore_at_tok_free(tokens);
2469 dbg(" Function exit");
2472 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2474 const TcoreATResponse *resp = data;
2475 UserRequest *ur = NULL;
2476 CoreObject *co_sim = NULL;
2477 struct tresp_sim_set_data resp_cf = {0, };
2478 struct tresp_sim_set_data resp_language = {0, };
2479 struct s_sim_property *sp = NULL;
2480 GSList *tokens = NULL;
2481 enum tel_sim_access_result result = SIM_CARD_ERROR;
2486 dbg(" Function entry ");
2488 co_sim = tcore_pending_ref_core_object(p);
2489 ur = tcore_pending_ref_user_request(p);
2490 sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
2492 if (resp->success > 0) {
2495 line = (const char *) resp->lines->data;
2496 tokens = tcore_at_tok_new(line);
2497 if (g_slist_length(tokens) != 2) {
2498 msg("invalid message");
2502 sw1 = atoi(g_slist_nth_data(tokens, 0));
2503 sw2 = atoi(g_slist_nth_data(tokens, 1));
2505 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2506 result = SIM_ACCESS_SUCCESS;
2508 result = _decode_status_word(sw1, sw2);
2511 dbg("RESPONSE NOK");
2512 result = SIM_ACCESS_FAILED;
2515 switch (sp->file_id) {
2516 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2517 case SIM_EF_USIM_CFIS:
2518 resp_cf.result = result;
2519 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_cf);
2524 case SIM_EF_USIM_LI:
2525 case SIM_EF_USIM_PL:
2526 resp_language.result = result;
2527 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_data), &resp_language);
2531 dbg("Invalid File ID - %d", sp->file_id)
2534 tcore_at_tok_free(tokens);
2535 dbg(" Function exit");
2538 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2540 const TcoreATResponse *resp = data;
2541 UserRequest *ur = NULL;
2542 CoreObject *co_sim = NULL;
2543 GSList *tokens = NULL;
2544 struct tresp_sim_transmit_apdu res;
2547 dbg(" Function entry ");
2549 co_sim = tcore_pending_ref_core_object(p);
2550 ur = tcore_pending_ref_user_request(p);
2552 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2553 res.result = SIM_ACCESS_FAILED;
2555 if (resp->success > 0) {
2559 char *decoded_data = NULL;
2560 line = (const char *) resp->lines->data;
2561 tokens = tcore_at_tok_new(line);
2562 if (g_slist_length(tokens) != 2) {
2563 msg("invalid message");
2566 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
2568 tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
2569 decoded_data = util_hexStringToBytes(tmp);
2571 memcpy((char *) res.apdu_resp, decoded_data, res.apdu_resp_length);
2574 res.result = SIM_ACCESS_SUCCESS;
2577 dbg("RESPONSE NOK");
2581 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
2583 tcore_at_tok_free(tokens);
2584 dbg(" Function exit");
2587 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
2589 const TcoreATResponse *resp = data;
2590 UserRequest *ur = NULL;
2591 GSList *tokens = NULL;
2592 struct tresp_sim_get_atr res;
2595 dbg(" Function entry ");
2597 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
2598 ur = tcore_pending_ref_user_request(p);
2600 res.result = SIM_ACCESS_FAILED;
2601 if (resp->success > 0) {
2605 char *decoded_data = NULL;
2606 line = (const char *) resp->lines->data;
2607 tokens = tcore_at_tok_new(line);
2608 if (g_slist_length(tokens) < 1) {
2609 msg("invalid message");
2613 tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
2614 decoded_data = util_hexStringToBytes(tmp);
2616 res.atr_length = strlen(decoded_data);
2617 memcpy((char *) res.atr, decoded_data, res.atr_length);
2620 res.result = SIM_ACCESS_SUCCESS;
2623 dbg("RESPONSE NOK");
2628 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_get_atr), &res);
2630 tcore_at_tok_free(tokens);
2631 dbg(" Function exit");
2634 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2636 TcoreHal *hal = NULL;
2637 TcoreATRequest *req = NULL;
2638 TcorePending *pending = NULL;
2639 char *cmd_str = NULL;
2640 const struct treq_sim_verify_pins *req_data = NULL;
2641 struct s_sim_property *sp = NULL;
2642 TReturn ret = TCORE_RETURN_FAILURE;
2644 dbg(" Function entry ");
2647 return TCORE_RETURN_EINVAL;
2649 hal = tcore_object_get_hal(o);
2650 if(FALSE == tcore_hal_get_power_state(hal)){
2651 dbg("cp not ready/n");
2652 return TCORE_RETURN_ENOSYS;
2655 sp = tcore_sim_ref_userdata(o);
2656 pending = tcore_pending_new(o, 0);
2657 req_data = tcore_user_request_ref_data(ur, NULL);
2659 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2660 sp->current_sec_op = SEC_PIN1_VERIFY;
2661 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2662 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2663 sp->current_sec_op = SEC_PIN2_VERIFY;
2664 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
2665 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
2666 sp->current_sec_op = SEC_SIM_VERIFY;
2667 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2668 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
2669 sp->current_sec_op = SEC_ADM_VERIFY;
2670 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2672 return TCORE_RETURN_EINVAL;
2675 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2677 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2679 tcore_pending_set_request_data(pending, 0, req);
2680 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
2681 tcore_pending_link_user_request(pending, ur);
2682 ret = tcore_hal_send_request(hal, pending);
2685 dbg(" Function exit");
2689 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2691 TcoreHal *hal = NULL;
2692 TcoreATRequest *req = NULL;
2693 TcorePending *pending = NULL;
2694 char *cmd_str = NULL;
2695 const struct treq_sim_verify_puks *req_data;
2696 struct s_sim_property *sp = NULL;
2697 TReturn ret = TCORE_RETURN_FAILURE;
2699 dbg(" Function entry ");
2702 return TCORE_RETURN_EINVAL;
2704 hal = tcore_object_get_hal(o);
2705 if(FALSE == tcore_hal_get_power_state(hal)){
2706 dbg("cp not ready/n");
2707 return TCORE_RETURN_ENOSYS;
2710 sp = tcore_sim_ref_userdata(o);
2711 pending = tcore_pending_new(o, 0);
2712 req_data = tcore_user_request_ref_data(ur, NULL);
2714 if (req_data->puk_type == SIM_PTYPE_PUK1) {
2715 sp->current_sec_op = SEC_PUK1_VERIFY;
2716 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2717 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
2718 sp->current_sec_op = SEC_PUK2_VERIFY;
2719 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2721 return TCORE_RETURN_EINVAL;
2723 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2725 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2727 tcore_pending_set_request_data(pending, 0, req);
2728 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
2729 tcore_pending_link_user_request(pending, ur);
2730 ret = tcore_hal_send_request(hal, pending);
2733 dbg(" Function exit");
2737 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2739 TcoreHal *hal = NULL;
2740 TcoreATRequest *req = NULL;
2741 TcorePending *pending = NULL;
2742 char *cmd_str = NULL;
2743 const struct treq_sim_change_pins *req_data;
2744 struct s_sim_property *sp = NULL;
2747 TReturn ret = TCORE_RETURN_FAILURE;
2749 dbg(" Function entry ");
2752 return TCORE_RETURN_EINVAL;
2754 hal = tcore_object_get_hal(o);
2755 if(FALSE == tcore_hal_get_power_state(hal)){
2756 dbg("cp not ready/n");
2757 return TCORE_RETURN_ENOSYS;
2760 sp = tcore_sim_ref_userdata(o);
2761 pending = tcore_pending_new(o, 0);
2762 req_data = tcore_user_request_ref_data(ur, NULL);
2764 if (req_data->type == SIM_PTYPE_PIN1) {
2765 sp->current_sec_op = SEC_PIN1_CHANGE;
2766 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
2767 } else if (req_data->type == SIM_PTYPE_PIN2) {
2768 sp->current_sec_op = SEC_PIN2_CHANGE;
2769 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
2771 return TCORE_RETURN_EINVAL;
2773 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2775 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2777 tcore_pending_set_request_data(pending, 0, req);
2778 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
2779 tcore_pending_link_user_request(pending, ur);
2780 ret = tcore_hal_send_request(hal, pending);
2783 dbg(" Function exit");
2787 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2789 TcoreHal *hal = NULL;
2790 TcoreATRequest *req = NULL;
2791 TcorePending *pending = NULL;
2792 char *cmd_str = NULL;
2793 const struct treq_sim_get_facility_status *req_data;
2795 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
2796 TReturn ret = TCORE_RETURN_FAILURE;
2798 dbg(" Function entry ");
2801 return TCORE_RETURN_EINVAL;
2803 hal = tcore_object_get_hal(o);
2804 if(FALSE == tcore_hal_get_power_state(hal)){
2805 dbg("cp not ready/n");
2806 return TCORE_RETURN_ENOSYS;
2809 pending = tcore_pending_new(o, 0);
2810 req_data = tcore_user_request_ref_data(ur, NULL);
2812 if (req_data->type == SIM_FACILITY_PS) {
2813 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2814 } else if (req_data->type == SIM_FACILITY_SC) {
2815 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2816 } else if (req_data->type == SIM_FACILITY_FD) {
2817 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2818 } else if (req_data->type == SIM_FACILITY_PN) {
2819 fac = "PN"; /*Network Personalization*/
2820 } else if (req_data->type == SIM_FACILITY_PU) {
2821 fac = "PU"; /*network sUbset Personalization*/
2822 } else if (req_data->type == SIM_FACILITY_PP) {
2823 fac = "PP"; /*service Provider Personalization*/
2824 } else if (req_data->type == SIM_FACILITY_PC) {
2825 fac = "PC"; /*Corporate Personalization*/
2827 return TCORE_RETURN_EINVAL;
2829 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
2830 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2832 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2834 tcore_pending_set_request_data(pending, 0, req);
2835 tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
2836 tcore_pending_link_user_request(pending, ur);
2837 ret = tcore_hal_send_request(hal, pending);
2840 dbg(" Function exit");
2844 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2846 TcoreHal *hal = NULL;
2847 TcoreATRequest *req = NULL;
2848 TcorePending *pending = NULL;
2849 char *cmd_str = NULL;
2850 const struct treq_sim_enable_facility *req_data;
2851 struct s_sim_property *sp = NULL;
2853 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
2854 TReturn ret = TCORE_RETURN_FAILURE;
2856 dbg(" Function entry ");
2859 return TCORE_RETURN_EINVAL;
2861 hal = tcore_object_get_hal(o);
2862 if(FALSE == tcore_hal_get_power_state(hal)){
2863 dbg("cp not ready/n");
2864 return TCORE_RETURN_ENOSYS;
2867 sp = tcore_sim_ref_userdata(o);
2868 pending = tcore_pending_new(o, 0);
2869 req_data = tcore_user_request_ref_data(ur, NULL);
2871 if (req_data->type == SIM_FACILITY_PS) {
2872 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2873 sp->current_sec_op = SEC_SIM_ENABLE;
2874 } else if (req_data->type == SIM_FACILITY_SC) {
2875 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2876 sp->current_sec_op = SEC_PIN1_ENABLE;
2877 } else if (req_data->type == SIM_FACILITY_FD) {
2878 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2879 sp->current_sec_op = SEC_FDN_ENABLE;
2880 } else if (req_data->type == SIM_FACILITY_PN) {
2881 fac = "PN"; /*Network Personalization*/
2882 sp->current_sec_op = SEC_NET_ENABLE;
2883 } else if (req_data->type == SIM_FACILITY_PU) {
2884 fac = "PU"; /*network sUbset Personalization*/
2885 sp->current_sec_op = SEC_NS_ENABLE;
2886 } else if (req_data->type == SIM_FACILITY_PP) {
2887 fac = "PP"; /*service Provider Personalization*/
2888 sp->current_sec_op = SEC_SP_ENABLE;
2889 } else if (req_data->type == SIM_FACILITY_PC) {
2890 fac = "PC"; /*Corporate Personalization*/
2891 sp->current_sec_op = SEC_CP_ENABLE;
2893 return TCORE_RETURN_EINVAL;
2895 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2896 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2898 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2900 tcore_pending_set_request_data(pending, 0, req);
2901 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
2902 tcore_pending_link_user_request(pending, ur);
2903 ret = tcore_hal_send_request(hal, pending);
2906 dbg(" Function exit");
2910 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2913 TcoreATRequest *req;
2914 TcorePending *pending = NULL;
2915 char *cmd_str = NULL;
2916 const struct treq_sim_enable_facility *req_data;
2917 struct s_sim_property *sp = NULL;
2919 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
2920 TReturn ret = TCORE_RETURN_FAILURE;
2922 dbg(" Function entry ");
2925 return TCORE_RETURN_EINVAL;
2927 hal = tcore_object_get_hal(o);
2928 if(FALSE == tcore_hal_get_power_state(hal)){
2929 dbg("cp not ready/n");
2930 return TCORE_RETURN_ENOSYS;
2933 sp = tcore_sim_ref_userdata(o);
2934 pending = tcore_pending_new(o, 0);
2935 req_data = tcore_user_request_ref_data(ur, NULL);
2937 if (req_data->type == SIM_FACILITY_PS) {
2938 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2939 sp->current_sec_op = SEC_SIM_DISABLE;
2940 } else if (req_data->type == SIM_FACILITY_SC) {
2941 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2942 sp->current_sec_op = SEC_PIN1_DISABLE;
2943 } else if (req_data->type == SIM_FACILITY_FD) {
2944 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2945 sp->current_sec_op = SEC_FDN_DISABLE;
2946 } else if (req_data->type == SIM_FACILITY_PN) {
2947 fac = "PN"; /*Network Personalization*/
2948 sp->current_sec_op = SEC_NET_DISABLE;
2949 } else if (req_data->type == SIM_FACILITY_PU) {
2950 fac = "PU"; /*network sUbset Personalization*/
2951 sp->current_sec_op = SEC_NS_DISABLE;
2952 } else if (req_data->type == SIM_FACILITY_PP) {
2953 fac = "PP"; /*service Provider Personalization*/
2954 sp->current_sec_op = SEC_SP_DISABLE;
2955 } else if (req_data->type == SIM_FACILITY_PC) {
2956 fac = "PC"; /*Corporate Personalization*/
2957 sp->current_sec_op = SEC_CP_DISABLE;
2959 return TCORE_RETURN_EINVAL;
2961 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2962 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2964 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2966 tcore_pending_set_request_data(pending, 0, req);
2967 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
2968 tcore_pending_link_user_request(pending, ur);
2969 ret = tcore_hal_send_request(hal, pending);
2972 dbg(" Function exit");
2976 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
2978 TcoreHal *hal = NULL;
2979 TcoreATRequest *req = NULL;
2980 TcorePending *pending = NULL;
2981 char *cmd_str = NULL;
2982 char *lock_type = NULL;
2983 const struct treq_sim_get_lock_info *req_data;
2984 TReturn ret = TCORE_RETURN_FAILURE;
2986 dbg(" Function entry ");
2989 return TCORE_RETURN_EINVAL;
2991 hal = tcore_object_get_hal(o);
2992 if(FALSE == tcore_hal_get_power_state(hal)){
2993 dbg("cp not ready/n");
2994 return TCORE_RETURN_ENOSYS;
2996 pending = tcore_pending_new(o, 0);
2997 req_data = tcore_user_request_ref_data(ur, NULL);
2999 switch (req_data->type) {
3000 case SIM_FACILITY_PS:
3004 case SIM_FACILITY_SC:
3008 case SIM_FACILITY_FD:
3012 case SIM_FACILITY_PN:
3016 case SIM_FACILITY_PU:
3020 case SIM_FACILITY_PP:
3024 case SIM_FACILITY_PC:
3031 cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
3032 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
3034 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3036 tcore_pending_set_request_data(pending, 0, req);
3037 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
3038 tcore_pending_link_user_request(pending, ur);
3039 ret = tcore_hal_send_request(hal, pending);
3042 dbg(" Function exit");
3046 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
3048 TReturn api_ret = TCORE_RETURN_SUCCESS;
3049 enum tcore_request_command command;
3051 dbg(" Function entry ");
3054 return TCORE_RETURN_EINVAL;
3056 command = tcore_user_request_get_command(ur);
3057 if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
3058 dbg("cp not ready/n");
3059 return TCORE_RETURN_ENOSYS;
3063 case TREQ_SIM_GET_ECC:
3064 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
3067 case TREQ_SIM_GET_LANGUAGE:
3068 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
3069 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
3070 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
3071 api_ret = _get_file_info(o, ur, SIM_EF_LP);
3073 api_ret = TCORE_RETURN_ENOSYS;
3076 case TREQ_SIM_GET_ICCID:
3077 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
3080 case TREQ_SIM_GET_MAILBOX:
3081 if (tcore_sim_get_cphs_status(o))
3082 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3084 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
3087 case TREQ_SIM_GET_CALLFORWARDING:
3088 if (tcore_sim_get_cphs_status(o))
3089 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3091 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3094 case TREQ_SIM_GET_MESSAGEWAITING:
3095 if (tcore_sim_get_cphs_status(o))
3096 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3098 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3101 case TREQ_SIM_GET_CPHS_INFO:
3102 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3105 case TREQ_SIM_GET_MSISDN:
3106 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3109 case TREQ_SIM_GET_SPN:
3110 dbg("enter case SPN");
3111 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3114 case TREQ_SIM_GET_SPDI:
3115 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3118 case TREQ_SIM_GET_OPL:
3119 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3122 case TREQ_SIM_GET_PNN:
3123 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3126 case TREQ_SIM_GET_CPHS_NETNAME:
3127 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3130 case TREQ_SIM_GET_OPLMNWACT:
3131 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3135 dbg("error - not handled read treq command[%d]", command);
3136 api_ret = TCORE_RETURN_EINVAL;
3139 dbg(" Function exit");
3143 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
3146 TcoreATRequest *req;
3147 TcorePending *pending = NULL;
3148 char *cmd_str = NULL;
3149 TReturn ret = TCORE_RETURN_SUCCESS;
3150 char *encoded_data = NULL;
3151 int encoded_len = 0;
3152 enum tcore_request_command command;
3153 enum tel_sim_file_id ef = SIM_EF_INVALID;
3154 const struct treq_sim_set_callforwarding *cf;
3155 const struct treq_sim_set_language *cl;
3156 struct s_sim_property file_meta = {0, };
3163 struct tel_sim_language sim_language;
3167 command = tcore_user_request_get_command(ur);
3169 dbg(" Function entry ");
3172 return TCORE_RETURN_EINVAL;
3175 hal = tcore_object_get_hal(o);
3176 if(FALSE == tcore_hal_get_power_state(hal)){
3177 dbg("cp not ready/n");
3178 return TCORE_RETURN_ENOSYS;
3181 pending = tcore_pending_new(o, 0);
3184 case TREQ_SIM_SET_LANGUAGE:
3185 cl = tcore_user_request_ref_data(ur, NULL);
3186 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
3189 sim_language.language_count = 1;
3190 sim_language.language[0] = cl->language;
3191 dbg("language %d", cl->language);
3193 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
3196 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
3198 encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
3199 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
3200 result = util_byte_to_hex(tmp, encoded_data, out_length);
3205 dbg("encoded_data - %s ---", encoded_data);
3206 dbg("out_length - %d ---", out_length);
3207 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
3210 tmp = tcore_sim_encode_li(&out_length, &sim_language);
3212 encoded_data = (char *) malloc(2 * (out_length) + 1);
3213 memset(encoded_data, 0x00, (2 * out_length) + 1);
3214 result = util_byte_to_hex(tmp, encoded_data, out_length);
3219 dbg("encoded_data - %s ---", encoded_data);
3220 dbg("out_length - %d ---", out_length);
3222 ret = TCORE_RETURN_ENOSYS;
3226 case TREQ_SIM_SET_CALLFORWARDING:
3227 cf = tcore_user_request_ref_data(ur, NULL);
3228 if (tcore_sim_get_cphs_status(o)) {
3229 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
3230 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
3234 encoded_data = (char *) malloc(2 * (p3) + 1);
3235 memset(encoded_data, 0x00, (2 *p3) + 1);
3236 result = util_byte_to_hex(tmp, encoded_data, p3);
3237 cmd = 214; /*command - 214 : UPDATE BINARY*/
3239 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
3240 ef = SIM_EF_USIM_CFIS;
3244 encoded_data = (char *) malloc(2 * (encoded_len) + 1);
3245 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
3246 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3247 cmd = 220; /*command - 220 : UPDATE RECORD*/
3252 dbg("error - not handled update treq command[%d]", command);
3253 ret = TCORE_RETURN_EINVAL;
3256 file_meta.file_id = ef;
3257 dbg("file_meta.file_id: %d", file_meta.file_id);
3259 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
3260 dbg("trt[%d]", trt);
3262 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3263 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3265 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3267 tcore_pending_set_request_data(pending, 0, req);
3268 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
3269 tcore_pending_link_user_request(pending, ur);
3270 ret = tcore_hal_send_request(hal, pending);
3272 if (NULL != encoded_data) {
3273 g_free(encoded_data);
3281 dbg(" Function exit");
3285 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3287 TcoreHal *hal = NULL;
3288 TcoreATRequest *req = NULL;
3289 TcorePending *pending = NULL;
3290 char *cmd_str = NULL;
3294 const struct treq_sim_transmit_apdu *req_data;
3295 TReturn ret = TCORE_RETURN_FAILURE;
3297 dbg(" Function entry ");
3300 return TCORE_RETURN_EINVAL;
3302 hal = tcore_object_get_hal(o);
3303 if(FALSE == tcore_hal_get_power_state(hal)){
3304 dbg("cp not ready/n");
3305 return TCORE_RETURN_ENOSYS;
3308 pending = tcore_pending_new(o, 0);
3309 req_data = tcore_user_request_ref_data(ur, NULL);
3311 apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
3312 memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
3313 result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
3314 apdu_len = strlen(apdu);
3315 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", apdu_len, apdu);
3316 req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
3317 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3319 tcore_pending_set_request_data(pending, 0, req);
3320 tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
3321 tcore_pending_link_user_request(pending, ur);
3322 ret = tcore_hal_send_request(hal, pending);
3326 dbg(" Function exit");
3330 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
3332 TcoreHal *hal = NULL;
3333 TcoreATRequest *req = NULL;
3334 TcorePending *pending = NULL;
3335 char *cmd_str = NULL;
3336 TReturn ret = TCORE_RETURN_FAILURE;
3338 dbg(" Function entry ");
3341 return TCORE_RETURN_EINVAL;
3343 hal = tcore_object_get_hal(o);
3344 if(FALSE == tcore_hal_get_power_state(hal)) {
3345 dbg("cp not ready/n");
3346 return TCORE_RETURN_ENOSYS;
3348 pending = tcore_pending_new(o, 0);
3350 cmd_str = g_strdup_printf("AT+XGATR");
3351 req = tcore_at_request_new(cmd_str, "+XGATR:", TCORE_AT_SINGLELINE);
3352 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3354 tcore_pending_set_request_data(pending, 0, req);
3355 tcore_pending_set_response_callback(pending, on_response_get_atr, hal);
3356 tcore_pending_link_user_request(pending, ur);
3357 ret = tcore_hal_send_request(hal, pending);
3360 dbg(" Function exit");
3364 static struct tcore_sim_operations sim_ops = {
3365 .verify_pins = s_verify_pins,
3366 .verify_puks = s_verify_puks,
3367 .change_pins = s_change_pins,
3368 .get_facility_status = s_get_facility_status,
3369 .enable_facility = s_enable_facility,
3370 .disable_facility = s_disable_facility,
3371 .get_lock_info = s_get_lock_info,
3372 .read_file = s_read_file,
3373 .update_file = s_update_file,
3374 .transmit_apdu = s_transmit_apdu,
3375 .get_atr = s_get_atr,
3376 .req_authentication = NULL,
3379 gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim)
3381 struct s_sim_property *file_meta;
3385 tcore_sim_override_ops(co_sim, &sim_ops);
3387 file_meta = g_try_new0(struct s_sim_property, 1);
3391 tcore_sim_link_userdata(co_sim, file_meta);
3393 tcore_object_override_callback(co_sim, "+XLOCK", on_event_facility_lock_status, NULL);
3394 tcore_object_override_callback(co_sim, "+XSIM", on_event_pin_status, NULL);
3396 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
3403 void s_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
3405 struct s_sim_property *file_meta;
3407 file_meta = tcore_sim_ref_userdata(co_sim);