4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <core_object.h>
33 #include <user_request.h>
41 #define ID_RESERVED_AT 0x0229
43 #define SWAPBYTES16(x) \
45 unsigned short int data = *(unsigned short int *)&(x); \
46 data = ((data & 0xff00) >> 8) | \
47 ((data & 0x00ff) << 8); \
48 *(unsigned short int *)&(x) = data; \
51 enum s_sim_file_type_e {
52 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
53 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
54 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
55 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
56 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
71 SEC_PIN2_DISABLE, // 10
92 SEC_SIM_UNKNOWN = 0xff
95 struct s_sim_property {
96 gboolean b_valid; /**< Valid or not */
97 enum tel_sim_file_id file_id; /**< File identifier */
98 enum s_sim_file_type_e file_type; /**< File type and structure */
99 int rec_length; /**< Length of one record in file */
100 int rec_count; /**< Number of records in file */
101 int data_size; /**< File size */
102 int current_index; /**< current index to read */
103 enum s_sim_sec_op_e current_sec_op; /**< current index to read */
104 struct tel_sim_mbi_list mbi_list;
105 struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
106 struct tresp_sim_read files;
109 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
110 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
111 static gboolean _get_sim_type(CoreObject *o);
112 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
113 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
114 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
115 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
116 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
118 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)
120 TcoreATRequest *req = NULL;
121 TcoreHal *hal = NULL;
122 TcorePending *pending = NULL;
126 hal = tcore_object_get_hal(co);
129 pending = tcore_pending_new(co, 0);
131 dbg("Pending is NULL");
132 req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
134 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
136 tcore_pending_set_request_data(pending, 0, req);
137 tcore_pending_set_response_callback(pending, callback, NULL);
138 tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
139 ret = tcore_hal_send_request(hal, pending);
144 static enum tcore_response_command _find_resp_command(UserRequest *ur)
146 enum tcore_request_command command;
148 command = tcore_user_request_get_command(ur);
150 case TREQ_SIM_VERIFY_PINS:
151 return TRESP_SIM_VERIFY_PINS;
154 case TREQ_SIM_VERIFY_PUKS:
155 return TRESP_SIM_VERIFY_PUKS;
158 case TREQ_SIM_CHANGE_PINS:
159 return TRESP_SIM_CHANGE_PINS;
162 case TREQ_SIM_GET_FACILITY_STATUS:
163 return TRESP_SIM_GET_FACILITY_STATUS;
166 case TREQ_SIM_DISABLE_FACILITY:
167 return TRESP_SIM_DISABLE_FACILITY;
170 case TREQ_SIM_ENABLE_FACILITY:
171 return TRESP_SIM_ENABLE_FACILITY;
174 case TREQ_SIM_GET_LOCK_INFO:
175 return TRESP_SIM_GET_LOCK_INFO;
178 case TREQ_SIM_TRANSMIT_APDU:
179 return TRESP_SIM_TRANSMIT_APDU;
182 case TREQ_SIM_GET_ATR:
183 return TRESP_SIM_GET_ATR;
186 case TREQ_SIM_GET_ECC:
187 return TRESP_SIM_GET_ECC;
190 case TREQ_SIM_GET_LANGUAGE:
191 return TRESP_SIM_GET_LANGUAGE;
194 case TREQ_SIM_SET_LANGUAGE:
195 return TRESP_SIM_SET_LANGUAGE;
198 case TREQ_SIM_GET_ICCID:
199 return TRESP_SIM_GET_ICCID;
202 case TREQ_SIM_GET_MAILBOX:
203 return TRESP_SIM_GET_MAILBOX;
206 case TREQ_SIM_GET_CALLFORWARDING:
207 return TRESP_SIM_GET_CALLFORWARDING;
210 case TREQ_SIM_SET_CALLFORWARDING:
211 return TRESP_SIM_SET_CALLFORWARDING;
214 case TREQ_SIM_GET_MESSAGEWAITING:
215 return TRESP_SIM_GET_MESSAGEWAITING;
218 case TREQ_SIM_GET_CPHS_INFO:
219 return TRESP_SIM_GET_CPHS_INFO;
222 case TREQ_SIM_GET_MSISDN:
223 return TRESP_SIM_GET_MSISDN;
226 case TREQ_SIM_GET_SPN:
227 return TRESP_SIM_GET_SPN;
230 case TREQ_SIM_GET_SPDI:
231 return TRESP_SIM_GET_SPDI;
234 case TREQ_SIM_GET_OPL:
235 return TRESP_SIM_GET_OPL;
238 case TREQ_SIM_GET_PNN:
239 return TRESP_SIM_GET_PNN;
242 case TREQ_SIM_GET_CPHS_NETNAME:
243 return TRESP_SIM_GET_CPHS_NETNAME;
246 case TREQ_SIM_GET_OPLMNWACT:
247 return TRESP_SIM_GET_OPLMNWACT;
250 case TREQ_SIM_REQ_AUTHENTICATION:
251 return TRESP_SIM_REQ_AUTHENTICATION;
257 return TRESP_UNKNOWN;
260 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
264 dbg("current sec_op[%d]", op);
267 case SEC_PIN1_VERIFY:
268 case SEC_PIN1_CHANGE:
269 ret_type = SIM_PTYPE_PIN1;
272 case SEC_PIN2_VERIFY:
273 case SEC_PIN2_CHANGE:
274 ret_type = SIM_PTYPE_PIN2;
277 case SEC_PUK1_VERIFY:
278 ret_type = SIM_PTYPE_PUK1;
281 case SEC_PUK2_VERIFY:
282 ret_type = SIM_PTYPE_PUK2;
286 ret_type = SIM_PTYPE_SIM;
290 ret_type = SIM_PTYPE_ADM;
293 case SEC_PIN1_ENABLE:
294 case SEC_PIN1_DISABLE:
295 case SEC_PIN1_STATUS:
296 ret_type = SIM_FACILITY_SC;
300 case SEC_SIM_DISABLE:
302 ret_type = SIM_FACILITY_PS;
306 case SEC_NET_DISABLE:
308 ret_type = SIM_FACILITY_PN;
314 ret_type = SIM_FACILITY_PU;
320 ret_type = SIM_FACILITY_PP;
326 ret_type = SIM_FACILITY_PC;
330 case SEC_FDN_DISABLE:
332 ret_type = SIM_FACILITY_FD;
336 dbg("not handled current sec op[%d]", op);
342 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
344 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
346 if (status_word1 == 0x93 && status_word2 == 0x00) {
347 rst = SIM_ACCESS_FAILED;
348 /*Failed SIM request command*/
349 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
350 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
351 rst = SIM_ACCESS_FAILED;
352 /*Failed SIM request command*/
353 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
354 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
355 rst = SIM_ACCESS_FAILED;
356 /*Failed SIM request command*/
357 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
358 status_word1, status_word2);
359 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
360 rst = SIM_ACCESS_FILE_NOT_FOUND;
361 /*Failed SIM request command*/
362 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
363 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
364 rst = SIM_ACCESS_FAILED; /* MOdem not support */
365 /*Failed SIM request command*/
366 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
367 status_word1, status_word2);
368 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
369 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
370 /*Failed SIM request command*/
371 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
372 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
373 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
374 /*Failed SIM request command*/
375 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
376 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
377 status_word1, status_word2);
378 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
379 status_word1, status_word2);
380 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
381 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
382 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
383 /*Failed SIM request command*/
384 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
385 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
386 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
387 /*Failed SIM request command*/
388 dbg("error - Contradiction with invalidation status [%x][%x]",
389 status_word1, status_word2);
390 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
391 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
392 /*Failed SIM request command*/
393 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
394 status_word1, status_word2);
395 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
396 status_word1, status_word2);
397 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
398 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
399 rst = SIM_ACCESS_FAILED;
400 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
401 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
402 rst = SIM_ACCESS_FAILED;
403 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
404 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
405 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
406 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
407 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
408 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
409 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
410 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
411 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
412 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
413 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
414 rst = SIM_ACCESS_FAILED;
415 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
416 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
417 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
418 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
419 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
420 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
421 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
423 rst = SIM_ACCESS_CARD_ERROR;
424 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
429 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
432 Storage *strg = NULL;
433 char *old_imsi = NULL;
434 char new_imsi[15 + 1] = {0, };
436 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
438 dbg("there is no valid server at this point");
441 strg = (Storage *)tcore_server_find_storage(s, "vconf");
443 dbg("there is no valid storage plugin");
446 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
447 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
448 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
450 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
451 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
453 if (old_imsi != NULL) {
454 if (strncmp(old_imsi, new_imsi, 15) != 0) {
456 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
457 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
459 tcore_sim_set_identification(o, TRUE);
462 tcore_sim_set_identification(o, FALSE);
465 dbg("OLD SIM VALUE IS NULL. NEW SIM");
466 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
467 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
469 tcore_sim_set_identification(o, TRUE);
474 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
476 struct tresp_sim_read resp = {0, };
477 struct s_sim_property *file_meta = NULL;
479 dbg("EF[0x%x] access Result[%d]", ef, rt);
482 memset(&resp.data, 0x00, sizeof(resp.data));
483 file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
485 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
486 && (rt != SIM_ACCESS_SUCCESS)) {
487 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
493 if (rt == SIM_ACCESS_SUCCESS) {
494 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
495 /* if (po->language_file == 0x00)
496 po->language_file = SIM_EF_ELP;*/
497 _get_file_data(o, ur, ef, 0, file_meta->data_size);
499 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
500 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
501 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
502 _get_file_info(o, ur, SIM_EF_LP);
503 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
505 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
506 /* EFELPand EFLI not present at this point. */
507 /* po->language.lang_cnt = 0;*/
508 tcore_user_request_send_response(ur, _find_resp_command(ur),
509 sizeof(struct tresp_sim_read), &resp);
515 case SIM_EF_LP: // same with SIM_EF_USIM_LI
516 if (rt == SIM_ACCESS_SUCCESS) {
517 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
518 _get_file_data(o, ur, ef, 0, file_meta->data_size);
520 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
521 tcore_sim_get_type(o));
522 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
523 tcore_user_request_send_response(ur, _find_resp_command(ur),
524 sizeof(struct tresp_sim_read), &resp);
527 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
528 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
529 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
530 _get_file_info(o, ur, SIM_EF_ELP);
536 if (rt == SIM_ACCESS_SUCCESS) {
537 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
538 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
540 /* EFELIand EFPL not present, so set language count as zero and select ECC */
542 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
543 tcore_user_request_send_response(ur, _find_resp_command(ur),
544 sizeof(struct tresp_sim_read), &resp);
550 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
551 _get_file_data(o, ur, ef, 0, file_meta->data_size);
552 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
553 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
554 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
557 file_meta->current_index++;
558 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
567 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
568 case SIM_EF_CPHS_VOICE_MSG_WAITING:
569 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
570 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
571 case SIM_EF_CPHS_DYNAMICFLAGS:
572 case SIM_EF_CPHS_DYNAMIC2FLAG:
573 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
574 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
575 _get_file_data(o, ur, ef, 0, file_meta->data_size);
578 case SIM_EF_CPHS_CPHS_INFO:
579 if (rt == SIM_ACCESS_SUCCESS) {
580 tcore_sim_set_cphs_status(o, TRUE);
581 if (!tcore_user_request_ref_communicator(ur)) {
582 dbg("internal CPHS INFO request before sim status update");
583 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
585 dbg("external CPHS INFO request");
586 _get_file_data(o, ur, ef, 0, file_meta->data_size);
589 tcore_sim_set_cphs_status(o, FALSE);
590 if (!tcore_user_request_ref_communicator(ur)) {
591 dbg("internal CPHS INFO request before sim status update");
592 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
594 dbg("external CPHS INFO request");
595 tcore_user_request_send_response(ur, _find_resp_command(ur),
596 sizeof(struct tresp_sim_read), &resp);
602 case SIM_EF_USIM_CFIS:
603 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
604 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
606 file_meta->current_index++;
607 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
612 case SIM_EF_USIM_MWIS:
613 case SIM_EF_USIM_MBI:
615 case SIM_EF_CPHS_MAILBOX_NUMBERS:
616 case SIM_EF_CPHS_INFORMATION_NUMBERS:
618 file_meta->current_index++;
619 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
623 dbg("error - File id for get file info [0x%x]", ef);
629 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
631 struct s_sim_property *file_meta = NULL;
635 file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
636 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
637 switch (file_meta->file_id) {
642 if (decode_ret == TRUE) {
643 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
644 /* po->language_file = SIM_EF_LP;*/
645 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
646 /* po->language_file = SIM_EF_ELP;*/
648 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
651 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
652 - EFELP is not available;
653 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
654 - the ME does not support any of the languages in EFELP.
657 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
658 - if the EFLI has the value 'FFFF' in its highest priority position
659 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
661 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
662 if (file_meta->file_id == SIM_EF_LP) {
663 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
665 _get_file_info(o, ur, SIM_EF_LP);
667 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
668 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
669 _get_file_info(o, ur, SIM_EF_ELP);
671 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
678 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
679 if (file_meta->current_index == file_meta->rec_count) {
680 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
682 file_meta->current_index++;
683 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
685 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
686 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
688 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
693 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
694 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
698 if (file_meta->current_index == file_meta->rec_count) {
699 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
701 file_meta->current_index++;
702 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
707 if (file_meta->current_index == file_meta->rec_count) {
708 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
710 file_meta->current_index++;
711 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
716 if (file_meta->current_index == file_meta->rec_count) {
717 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
719 file_meta->current_index++;
720 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
724 case SIM_EF_USIM_CFIS:
725 case SIM_EF_USIM_MWIS:
726 case SIM_EF_USIM_MBI:
728 case SIM_EF_CPHS_MAILBOX_NUMBERS:
729 case SIM_EF_CPHS_INFORMATION_NUMBERS:
730 if (file_meta->current_index == file_meta->rec_count) {
731 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
733 file_meta->current_index++;
734 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
738 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
739 file_meta->files.result = rt;
740 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
741 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));
743 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
746 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
747 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
748 file_meta->files.result = SIM_ACCESS_SUCCESS;
750 if (strlen((char *)file_meta->files.data.cphs_net.full_name)) {
751 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));
753 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
760 case SIM_EF_OPLMN_ACT:
761 case SIM_EF_CPHS_CPHS_INFO:
762 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
763 case SIM_EF_CPHS_VOICE_MSG_WAITING:
764 case SIM_EF_CPHS_DYNAMICFLAGS:
765 case SIM_EF_CPHS_DYNAMIC2FLAG:
766 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
767 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
768 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
772 dbg("File id not handled [0x%x]", file_meta->file_id);
777 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
779 struct tnoti_sim_status noti_data = {0, };
781 if (sim_status != tcore_sim_get_status(o)) {
782 dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
783 tcore_sim_get_status(o), sim_status);
785 /* Update SIM Status */
786 tcore_sim_set_status(o, sim_status);
787 noti_data.sim_status = sim_status;
789 /* Send notification */
790 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
791 o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
795 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
797 const TcoreATResponse *resp = data;
798 UserRequest *ur = NULL;
799 CoreObject *co_sim = NULL;
800 struct s_sim_property *sp = NULL;
801 GSList *tokens = NULL;
802 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
808 co_sim = tcore_pending_ref_core_object(p);
809 sp = tcore_sim_ref_userdata(co_sim);
810 ur = tcore_pending_ref_user_request(p);
812 if (resp->success > 0) {
815 line = (const char *)resp->lines->data;
816 tokens = tcore_at_tok_new(line);
817 if (g_slist_length(tokens) != 1) {
818 msg("Invalid message");
819 tcore_at_tok_free(tokens);
823 state = atoi(g_slist_nth_data(tokens, 0));
824 dbg("SIM Type is %d", state);
827 sim_type = SIM_TYPE_GSM;
828 } else if (state == 1) {
829 sim_type = SIM_TYPE_USIM;
831 sim_type = SIM_TYPE_UNKNOWN;
835 sim_type = SIM_TYPE_UNKNOWN;
838 tcore_sim_set_type(co_sim, sim_type);
840 if (sim_type != SIM_TYPE_UNKNOWN) {
841 /* set user request for using ur metainfo set/ref functionality */
842 ur = tcore_user_request_new(NULL, NULL);
843 _get_file_info(co_sim, ur, SIM_EF_IMSI);
846 tcore_at_tok_free(tokens);
850 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
852 const TcoreATResponse *resp = data;
853 UserRequest *ur = NULL;
854 CoreObject *co_sim = NULL;
855 struct s_sim_property *file_meta = NULL;
856 GSList *tokens = NULL;
857 enum tel_sim_access_result rt;
858 const char *line = NULL;
864 co_sim = tcore_pending_ref_core_object(p);
865 ur = tcore_pending_ref_user_request(p);
866 file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
868 if (resp->success > 0) {
871 line = (const char *)resp->lines->data;
872 tokens = tcore_at_tok_new(line);
873 if (g_slist_length(tokens) < 2) {
874 err("Invalid message");
875 tcore_at_tok_free(tokens);
879 sw1 = atoi(g_slist_nth_data(tokens, 0));
880 sw2 = atoi(g_slist_nth_data(tokens, 1));
882 /*1. SIM access success case*/
883 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
884 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
885 unsigned short record_len = 0;
886 char num_of_records = 0;
887 unsigned char file_id_len = 0;
888 unsigned short file_id = 0;
889 unsigned short file_size = 0;
890 unsigned short file_type = 0;
891 unsigned short arr_file_id = 0;
892 int arr_file_id_rec_num = 0;
894 /* handling only last 3 bits */
895 unsigned char file_type_tag = 0x07;
896 unsigned char *ptr_data;
900 char *recordData = NULL;
901 hexData = g_slist_nth_data(tokens, 2);
902 dbg("hexData: %s", hexData);
903 dbg("hexData: %s", hexData + 1);
905 tmp = util_removeQuotes(hexData);
906 recordData = util_hexStringToBytes(tmp);
907 util_hex_dump(" ", strlen(hexData) / 2, recordData);
910 ptr_data = (unsigned char *)recordData;
911 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
913 ETSI TS 102 221 v7.9.0
915 '62' FCP template tag
917 '82' M File Descriptor
918 '83' M File Identifier
919 'A5' O Proprietary information
920 '8A' M Life Cycle Status Integer
921 '8B', '8C' or 'AB' C1 Security attributes
923 '81' O Total file size
924 '88' O Short File Identifier (SFI)
927 /* rsim.res_len has complete data length received */
929 /* FCP template tag - File Control Parameters tag*/
930 if (*ptr_data == 0x62) {
931 /* parse complete FCP tag*/
932 /* increment to next byte */
934 tag_len = *ptr_data++;
935 dbg("tag_len: %02x", tag_len);
936 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
937 if (*ptr_data == 0x82) {
938 /* increment to next byte */
942 /* unsigned char file_desc_len = *ptr_data++;*/
943 /* dbg("file descriptor length: [%d]", file_desc_len);*/
944 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
945 /* consider only last 3 bits*/
946 dbg("file_type_tag: %02x", file_type_tag);
947 file_type_tag = file_type_tag & (*ptr_data);
948 dbg("file_type_tag: %02x", file_type_tag);
950 switch (file_type_tag) {
951 /* increment to next byte */
954 dbg("Getting FileType: [Transparent file type]");
955 file_type = SIM_FTYPE_TRANSPARENT;
957 /* increment to next byte */
959 /* increment to next byte */
964 dbg("Getting FileType: [Linear fixed file type]");
965 /* increment to next byte */
967 /* data coding byte - value 21 */
970 memcpy(&record_len, ptr_data, 2);
972 SWAPBYTES16(record_len);
973 ptr_data = ptr_data + 2;
974 num_of_records = *ptr_data++;
975 /* Data lossy conversation from enum (int) to unsigned char */
976 file_type = SIM_FTYPE_LINEAR_FIXED;
980 dbg("Cyclic fixed file type");
981 /* increment to next byte */
983 /* data coding byte - value 21 */
986 memcpy(&record_len, ptr_data, 2);
988 SWAPBYTES16(record_len);
989 ptr_data = ptr_data + 2;
990 num_of_records = *ptr_data++;
991 file_type = SIM_FTYPE_CYCLIC;
995 dbg("not handled file type [0x%x]", *ptr_data);
999 dbg("INVALID FCP received - DEbug!");
1000 tcore_at_tok_free(tokens);
1005 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1006 if (*ptr_data == 0x83) {
1007 /* increment to next byte */
1009 file_id_len = *ptr_data++;
1010 dbg("file_id_len: %02x", file_id_len);
1012 memcpy(&file_id, ptr_data, file_id_len);
1013 dbg("file_id: %x", file_id);
1016 SWAPBYTES16(file_id);
1017 dbg("file_id: %x", file_id);
1019 ptr_data = ptr_data + 2;
1020 dbg("Getting FileID=[0x%x]", file_id);
1022 dbg("INVALID FCP received - DEbug!");
1023 tcore_at_tok_free(tokens);
1028 /* proprietary information */
1029 if (*ptr_data == 0xA5) {
1030 unsigned short prop_len;
1031 /* increment to next byte */
1035 prop_len = *ptr_data;
1036 dbg("prop_len: %02x", prop_len);
1039 ptr_data = ptr_data + prop_len + 1;
1041 dbg("INVALID FCP received - DEbug!");
1044 /* life cycle status integer [8A][length:0x01][status]*/
1047 00000000 : No information given
1048 00000001 : creation state
1049 00000011 : initialization state
1050 000001-1 : operation state -activated
1051 000001-0 : operation state -deactivated
1052 000011-- : Termination state
1053 b8~b5 !=0, b4~b1=X : Proprietary
1054 Any other value : RFU
1056 if (*ptr_data == 0x8A) {
1057 /* increment to next byte */
1059 /* length - value 1 */
1062 switch (*ptr_data) {
1065 dbg("<RX> operation state -deactivated");
1071 dbg("<RX> operation state -activated");
1076 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1082 /* related to security attributes : currently not handled*/
1083 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1084 /* increment to next byte */
1086 /* if tag length is 3 */
1087 if (*ptr_data == 0x03) {
1088 /* increment to next byte */
1091 memcpy(&arr_file_id, ptr_data, 2);
1093 SWAPBYTES16(arr_file_id);
1094 ptr_data = ptr_data + 2;
1095 arr_file_id_rec_num = *ptr_data++;
1097 /* if tag length is not 3 */
1098 /* ignoring bytes */
1099 // ptr_data = ptr_data + 4;
1100 dbg("Useless security attributes, so jump to next tag");
1101 ptr_data = ptr_data + (*ptr_data + 1);
1104 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1105 tcore_at_tok_free(tokens);
1110 dbg("Current ptr_data value is [%x]", *ptr_data);
1112 /* file size excluding structural info*/
1113 if (*ptr_data == 0x80) {
1114 /* for EF file size is body of file and for Linear or cyclic it is
1115 * number of recXsizeof(one record)
1117 /* increment to next byte */
1119 /* length is 1 byte - value is 2 bytes or more */
1121 memcpy(&file_size, ptr_data, 2);
1123 SWAPBYTES16(file_size);
1124 ptr_data = ptr_data + 2;
1126 dbg("INVALID FCP received - DEbug!");
1127 tcore_at_tok_free(tokens);
1132 /* total file size including structural info*/
1133 if (*ptr_data == 0x81) {
1135 /* increment to next byte */
1140 ptr_data = ptr_data + 3;
1142 dbg("INVALID FCP received - DEbug!");
1143 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1146 /*short file identifier ignored*/
1147 if (*ptr_data == 0x88) {
1148 dbg("0x88: Do Nothing");
1152 dbg("INVALID FCP received - DEbug!");
1153 tcore_at_tok_free(tokens);
1157 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1158 unsigned char gsm_specific_file_data_len = 0;
1159 /* ignore RFU byte1 and byte2 */
1163 // file_size = p_info->response_len;
1164 memcpy(&file_size, ptr_data, 2);
1166 SWAPBYTES16(file_size);
1167 /* parsed file size */
1168 ptr_data = ptr_data + 2;
1170 memcpy(&file_id, ptr_data, 2);
1171 SWAPBYTES16(file_id);
1172 dbg("FILE id --> [%x]", file_id);
1173 ptr_data = ptr_data + 2;
1174 /* save file type - transparent, linear fixed or cyclic */
1175 file_type_tag = (*(ptr_data + 7));
1177 switch (*ptr_data) {
1180 dbg("RFU file type- not handled - Debug!");
1185 dbg("MF file type - not handled - Debug!");
1190 dbg("DF file type - not handled - Debug!");
1195 dbg("EF file type [%d] ", file_type_tag);
1196 /* increment to next byte */
1199 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1200 /* increament to next byte as this byte is RFU */
1203 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1205 /* increment to next byte */
1207 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1208 /* the INCREASE command is allowed on the selected cyclic file. */
1209 file_type = SIM_FTYPE_CYCLIC;
1211 /* bytes 9 to 11 give SIM file access conditions */
1213 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1215 /* byte 11 is invalidate and rehabilate nibbles */
1217 /* byte 12 - file status */
1219 /* byte 13 - GSM specific data */
1220 gsm_specific_file_data_len = *ptr_data;
1222 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1224 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1225 record_len = *ptr_data;
1226 dbg("record length[%d], file size[%d]", record_len, file_size);
1228 if (record_len != 0)
1229 num_of_records = (file_size / record_len);
1231 dbg("Number of records [%d]", num_of_records);
1235 dbg("not handled file type");
1239 dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1242 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1243 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1245 file_meta->file_type = file_type;
1246 file_meta->data_size = file_size;
1247 file_meta->rec_length = record_len;
1248 file_meta->rec_count = num_of_records;
1249 file_meta->current_index = 0; // reset for new record type EF
1250 rt = SIM_ACCESS_SUCCESS;
1253 /*2. SIM access fail case*/
1254 dbg("error to get ef[0x%x]", file_meta->file_id);
1255 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1256 rt = _decode_status_word(sw1, sw2);
1258 ur = tcore_user_request_ref(ur);
1260 dbg("Calling _next_from_get_file_info");
1261 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1262 tcore_at_tok_free(tokens);
1264 dbg("RESPONSE NOK");
1265 dbg("error to get ef[0x%x]", file_meta->file_id);
1266 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1267 rt = SIM_ACCESS_FAILED;
1269 ur = tcore_user_request_ref(ur);
1270 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1275 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1277 const TcoreATResponse *resp = data;
1278 UserRequest *ur = NULL;
1279 CoreObject *co_sim = NULL;
1280 struct s_sim_property *file_meta = NULL;
1281 GSList *tokens = NULL;
1282 enum tel_sim_access_result rt;
1283 gboolean dr = FALSE;
1284 const char *line = NULL;
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(tmp) / 2;
1315 dbg("Response: [%s] Response length: [%d]", res, res_len);
1317 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1318 rt = SIM_ACCESS_SUCCESS;
1319 file_meta->files.result = rt;
1321 dbg("File ID: [0x%x]", file_meta->file_id);
1322 switch (file_meta->file_id) {
1325 struct tel_sim_imsi *imsi = NULL;
1327 dbg("Data: [%s]", res);
1328 imsi = g_try_new0(struct tel_sim_imsi, 1);
1329 dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
1331 err("IMSI decoding failed");
1333 _sim_check_identity(co_sim, imsi);
1334 tcore_sim_set_imsi(co_sim, imsi);
1343 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *)res, res_len);
1346 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1347 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1348 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1349 case SIM_EF_LP: /* 1 byte encoding */
1350 if ((tcore_sim_get_type(co_sim) == SIM_TYPE_GSM)
1351 && (file_meta->file_id == SIM_EF_LP)) {
1353 * 2G LP(0x6F05) has 1 byte for each language
1355 dr = tcore_sim_decode_lp(&file_meta->files.data.language,
1356 (unsigned char *)res, res_len);
1359 * 3G LI(0x6F05)/PL(0x2F05),
1360 * 2G ELP(0x2F05) has 2 bytes for each language
1362 dr = tcore_sim_decode_li(file_meta->file_id,
1363 &file_meta->files.data.language,
1364 (unsigned char *)res, res_len);
1369 dr = tcore_sim_decode_spn(&file_meta->files.data.spn,
1370 (unsigned char *)res, res_len);
1374 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi,
1375 (unsigned char *)res, res_len);
1378 case SIM_EF_SST: //EF UST has same address
1380 struct tel_sim_service_table *svct = NULL;
1382 svct = g_try_new0(struct tel_sim_service_table, 1);
1383 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1384 dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *)res, res_len);
1385 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1386 dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *)res, res_len);
1388 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1392 dbg("SST/UST decoding failed");
1394 tcore_sim_set_service_table(co_sim, svct);
1404 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1405 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *)res, res_len);
1406 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1407 struct tel_sim_ecc *ecc = NULL;
1409 ecc = g_try_new0(struct tel_sim_ecc, 1);
1410 dbg("Index [%d]", file_meta->current_index);
1412 dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
1414 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
1415 file_meta->files.data.ecc.ecc_count++;
1421 dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(co_sim));
1428 struct tel_sim_msisdn *msisdn = NULL;
1430 dbg("Index [%d]", file_meta->current_index);
1431 msisdn = g_try_new0(struct tel_sim_msisdn, 1);
1432 dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
1434 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count],
1435 msisdn, sizeof(struct tel_sim_msisdn));
1437 file_meta->files.data.msisdn_list.count++;
1447 struct tel_sim_opl *opl = NULL;
1449 dbg("decode w/ index [%d]", file_meta->current_index);
1450 opl = g_try_new0(struct tel_sim_opl, 1);
1452 dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
1454 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count],
1455 opl, sizeof(struct tel_sim_opl));
1457 file_meta->files.data.opl.opl_count++;
1467 struct tel_sim_pnn *pnn = NULL;
1469 dbg("decode w/ index [%d]", file_meta->current_index);
1470 pnn = g_try_new0(struct tel_sim_pnn, 1);
1472 dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
1474 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count],
1475 pnn, sizeof(struct tel_sim_pnn));
1477 file_meta->files.data.pnn.pnn_count++;
1485 case SIM_EF_OPLMN_ACT:
1486 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1487 (unsigned char *)res, res_len);
1490 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1491 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1492 p_data->response, p_data->response_len);*/
1495 case SIM_EF_USIM_MBI: //linear type
1497 struct tel_sim_mbi *mbi = NULL;
1499 mbi = g_try_new0(struct tel_sim_mbi, 1);
1500 dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
1502 memcpy(&file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count],
1503 mbi, sizeof(struct tel_sim_mbi));
1504 file_meta->mbi_list.profile_count++;
1506 dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
1507 dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
1508 dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
1509 dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
1510 dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
1511 dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
1519 case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
1520 case SIM_EF_MBDN: //linear type
1521 dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info,
1522 (unsigned char *)res, res_len);
1523 file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
1526 case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
1527 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw,
1528 (unsigned char *)res, res_len);
1531 case SIM_EF_USIM_MWIS: //linear type
1533 struct tel_sim_mw *mw = NULL;
1535 mw = g_try_new0(struct tel_sim_mw, 1);
1537 dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
1539 memcpy(&file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
1540 file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
1541 file_meta->files.data.mw.mw_list.profile_count++;
1549 case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
1550 dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf,
1551 (unsigned char *)res, res_len);
1554 case SIM_EF_USIM_CFIS: //linear type
1556 struct tel_sim_cfis *cf = NULL;
1558 cf = g_try_new0(struct tel_sim_cfis, 1);
1559 dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
1561 memcpy(&file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count],
1562 cf, sizeof(struct tel_sim_cfis));
1564 file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
1565 file_meta->files.data.cf.cf_list.profile_count++;
1573 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1574 dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1577 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1578 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name,
1579 (unsigned char *)res, res_len);
1580 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1581 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1584 case SIM_EF_CPHS_DYNAMICFLAGS:
1585 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1586 p_data->response, p_data->response_len);*/
1589 case SIM_EF_CPHS_DYNAMIC2FLAG:
1590 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1591 p_data->response_len);*/
1594 case SIM_EF_CPHS_CPHS_INFO:
1595 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1596 (unsigned char *)res, res_len);
1599 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1600 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name,
1601 (unsigned char *)res, res_len);
1604 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1605 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1609 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1614 rt = _decode_status_word(sw1, sw2);
1615 file_meta->files.result = rt;
1623 tcore_at_tok_free(tokens);
1625 dbg("RESPONSE NOK");
1626 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1627 rt = SIM_ACCESS_FAILED;
1630 /* Reference User Request */
1631 ur = tcore_user_request_ref(ur);
1634 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1639 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1641 const TcoreATResponse *resp = data;
1642 UserRequest *ur = NULL;
1643 CoreObject *co_sim = NULL;
1644 struct s_sim_property *sp = NULL;
1645 GSList *tokens = NULL;
1646 const char *line = NULL;
1648 int attempts_left = 0;
1649 int time_penalty = 0;
1653 co_sim = tcore_pending_ref_core_object(p);
1654 sp = tcore_sim_ref_userdata(co_sim);
1655 ur = tcore_pending_ref_user_request(p);
1657 if (resp->success > 0) {
1660 line = (const char *)resp->lines->data;
1661 tokens = tcore_at_tok_new(line);
1662 if (g_slist_length(tokens) < 3) {
1663 msg("Invalid message");
1664 tcore_at_tok_free(tokens);
1668 lock_type = atoi(g_slist_nth_data(tokens, 0));
1669 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1670 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1672 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1673 lock_type, attempts_left, time_penalty);
1675 switch (sp->current_sec_op) {
1676 case SEC_PIN1_VERIFY:
1677 case SEC_PIN2_VERIFY:
1678 case SEC_SIM_VERIFY:
1679 case SEC_ADM_VERIFY:
1681 struct tresp_sim_verify_pins v_pin = {0, };
1683 v_pin.result = SIM_INCORRECT_PASSWORD;
1684 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1685 v_pin.retry_count = attempts_left;
1686 tcore_user_request_send_response(ur, _find_resp_command(ur),
1687 sizeof(struct tresp_sim_verify_pins), &v_pin);
1691 case SEC_PUK1_VERIFY:
1692 case SEC_PUK2_VERIFY:
1694 struct tresp_sim_verify_puks v_puk = {0, };
1696 v_puk.result = SIM_INCORRECT_PASSWORD;
1697 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1698 v_puk.retry_count = attempts_left;
1699 tcore_user_request_send_response(ur, _find_resp_command(ur),
1700 sizeof(struct tresp_sim_verify_puks), &v_puk);
1704 case SEC_PIN1_CHANGE:
1705 case SEC_PIN2_CHANGE:
1707 struct tresp_sim_change_pins change_pin = {0, };
1709 change_pin.result = SIM_INCORRECT_PASSWORD;
1710 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1711 change_pin.retry_count = attempts_left;
1712 tcore_user_request_send_response(ur, _find_resp_command(ur),
1713 sizeof(struct tresp_sim_change_pins), &change_pin);
1717 case SEC_PIN1_DISABLE:
1718 case SEC_PIN2_DISABLE:
1719 case SEC_FDN_DISABLE:
1720 case SEC_SIM_DISABLE:
1721 case SEC_NET_DISABLE:
1722 case SEC_NS_DISABLE:
1723 case SEC_SP_DISABLE:
1724 case SEC_CP_DISABLE:
1726 struct tresp_sim_disable_facility dis_facility = {0, };
1728 dis_facility.result = SIM_INCORRECT_PASSWORD;
1729 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1730 dis_facility.retry_count = attempts_left;
1731 tcore_user_request_send_response(ur, _find_resp_command(ur),
1732 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1736 case SEC_PIN1_ENABLE:
1737 case SEC_PIN2_ENABLE:
1738 case SEC_FDN_ENABLE:
1739 case SEC_SIM_ENABLE:
1740 case SEC_NET_ENABLE:
1745 struct tresp_sim_enable_facility en_facility = {0, };
1747 en_facility.result = SIM_INCORRECT_PASSWORD;
1748 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1749 en_facility.retry_count = attempts_left;
1750 tcore_user_request_send_response(ur, _find_resp_command(ur),
1751 sizeof(struct tresp_sim_enable_facility), &en_facility);
1756 dbg("not handled sec op[%d]", sp->current_sec_op);
1761 tcore_at_tok_free(tokens);
1767 static gboolean _get_sim_type(CoreObject *o)
1769 TcoreHal *hal = NULL;
1770 TcoreATRequest *req = NULL;
1771 TcorePending *pending = NULL;
1772 UserRequest *ur = NULL;
1773 char *cmd_str = NULL;
1777 hal = tcore_object_get_hal(o);
1778 pending = tcore_pending_new(o, 0);
1780 cmd_str = g_strdup_printf("AT+XUICC?");
1781 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1784 dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
1785 req->cmd, req->prefix, strlen(req->cmd));
1787 tcore_pending_set_request_data(pending, 0, req);
1788 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1789 tcore_pending_link_user_request(pending, ur);
1790 tcore_hal_send_request(hal, pending);
1796 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1798 TcoreHal *hal = NULL;
1799 TcorePending *pending = NULL;
1800 struct s_sim_property file_meta = {0, };
1801 char *cmd_str = NULL;
1802 TReturn ret = TCORE_RETURN_FAILURE;
1807 file_meta.file_id = ef;
1808 dbg("file_meta.file_id: [0x%02x]", file_meta.file_id);
1809 hal = tcore_object_get_hal(o);
1810 dbg("hal: %x", hal);
1812 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1813 dbg("trt[%d]", trt);
1814 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1815 dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
1817 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1818 tcore_pending_link_user_request(pending, ur);
1819 ret = tcore_hal_send_request(hal, pending);
1820 if (TCORE_RETURN_SUCCESS != ret) {
1821 tcore_user_request_free(ur);
1826 return TCORE_RETURN_SUCCESS;
1829 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1831 TcoreHal *hal = NULL;
1832 TcoreATRequest *req = NULL;
1833 TcorePending *pending = NULL;
1834 char *cmd_str = NULL;
1840 hal = tcore_object_get_hal(o);
1841 pending = tcore_pending_new(o, 0);
1843 dbg("file_id: %x", ef);
1845 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1846 p2 = (unsigned char) offset & 0x00FF; // offset low
1847 p3 = (unsigned char) length;
1849 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1851 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1854 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
1855 req->cmd, req->prefix, strlen(req->cmd));
1857 tcore_pending_set_request_data(pending, 0, req);
1858 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1859 tcore_pending_link_user_request(pending, ur);
1860 tcore_hal_send_request(hal, pending);
1866 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1868 TcoreHal *hal = NULL;
1869 TcoreATRequest *req = NULL;
1870 TcorePending *pending = NULL;
1871 char *cmd_str = NULL;
1878 hal = tcore_object_get_hal(o);
1879 pending = tcore_pending_new(o, 0);
1881 p1 = (unsigned char) index;
1882 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1883 p3 = (unsigned char) length;
1885 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1887 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1890 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
1891 req->cmd, req->prefix, strlen(req->cmd));
1893 tcore_pending_set_request_data(pending, 0, req);
1894 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1895 tcore_pending_link_user_request(pending, ur);
1896 tcore_hal_send_request(hal, pending);
1902 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1904 TcoreHal *hal = NULL;
1905 TcoreATRequest *req = NULL;
1906 TcorePending *pending = NULL;
1907 char *cmd_str = NULL;
1909 struct s_sim_property *sp = NULL;
1910 const struct treq_sim_get_lock_info *req_data = NULL;
1914 hal = tcore_object_get_hal(o);
1915 pending = tcore_pending_new(o, 0);
1916 req_data = tcore_user_request_ref_data(ur, NULL);
1917 sp = tcore_sim_ref_userdata(o);
1919 switch (sp->current_sec_op) {
1920 case SEC_PIN1_VERIFY:
1921 case SEC_PIN1_CHANGE:
1922 case SEC_PIN1_ENABLE:
1923 case SEC_PIN1_DISABLE:
1927 case SEC_PIN2_VERIFY:
1928 case SEC_PIN2_CHANGE:
1929 case SEC_PIN2_ENABLE:
1930 case SEC_PIN2_DISABLE:
1931 case SEC_FDN_ENABLE:
1932 case SEC_FDN_DISABLE:
1936 case SEC_PUK1_VERIFY:
1940 case SEC_PUK2_VERIFY:
1944 case SEC_NET_ENABLE:
1945 case SEC_NET_DISABLE:
1950 case SEC_NS_DISABLE:
1955 case SEC_SP_DISABLE:
1960 case SEC_CP_DISABLE:
1964 case SEC_ADM_VERIFY:
1972 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1973 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1976 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
1977 req->cmd, req->prefix, strlen(req->cmd));
1979 tcore_pending_set_request_data(pending, 0, req);
1980 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1981 tcore_pending_link_user_request(pending, ur);
1982 tcore_hal_send_request(hal, pending);
1985 return TCORE_RETURN_SUCCESS;
1988 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1990 struct s_sim_property *sp = NULL;
1992 GSList *tokens = NULL;
1993 GSList *lines = NULL;
1995 dbg("Function entry");
1998 sp = tcore_sim_ref_userdata(o);
1999 lines = (GSList *)event_info;
2000 if (1 != g_slist_length(lines)) {
2001 dbg("unsolicited msg but multiple line");
2004 line = (char *)(lines->data);
2005 tokens = tcore_at_tok_new(line);
2006 if (g_slist_length(tokens) != 1) {
2007 msg("Invalid message");
2008 tcore_at_tok_free(tokens);
2015 tcore_at_tok_free(tokens);
2019 static void notify_sms_state(TcorePlugin *plugin, CoreObject *co_sim,
2022 Server *server = tcore_plugin_ref_server(plugin);
2023 struct tnoti_sms_ready_status sms_ready_noti;
2028 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
2029 if (co_sms == NULL) {
2030 err("Can't find SMS core object");
2034 if (tcore_sms_get_ready_status(co_sms) == sms_ready)
2037 tcore_sms_set_ready_status(co_sms, sms_ready);
2039 if (tcore_sim_get_status(co_sim) == SIM_STATUS_INIT_COMPLETED) {
2040 sms_ready_noti.status = sms_ready;
2041 tcore_server_send_notification(server, co_sms,
2042 TNOTI_SMS_DEVICE_READY,
2043 sizeof(sms_ready_noti),
2050 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
2052 TcorePlugin *plugin = tcore_object_ref_plugin(o);
2053 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
2054 GSList *tokens = NULL;
2062 lines = (GSList *)event_info;
2063 if (g_slist_length(lines) != 1) {
2064 err("Unsolicited message BUT multiple lines");
2070 /* Create 'tokens' */
2071 tokens = tcore_at_tok_new(line);
2074 if (g_slist_length(tokens) == 4) {
2075 sim_state = atoi(g_slist_nth_data(tokens, 1));
2076 sms_state = atoi(g_slist_nth_data(tokens, 3));
2077 notify_sms_state(plugin, o, (sms_state > 0));
2078 } else if (g_slist_length(tokens) == 1) {
2079 sim_state = atoi(g_slist_nth_data(tokens, 0));
2081 err("Invalid message");
2085 switch (sim_state) {
2087 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
2092 sim_status = SIM_STATUS_PIN_REQUIRED;
2093 dbg("PIN REQUIRED");
2097 sim_status = SIM_STATUS_INITIALIZING;
2098 dbg("PIN DISABLED AT BOOT UP");
2102 sim_status = SIM_STATUS_INITIALIZING;
2103 dbg("PIN VERIFIED");
2107 sim_status = SIM_STATUS_PUK_REQUIRED;
2108 dbg("PUK REQUIRED");
2112 sim_status = SIM_STATUS_CARD_BLOCKED;
2113 dbg("CARD PERMANENTLY BLOCKED");
2117 sim_status = SIM_STATUS_CARD_ERROR;
2118 dbg("SIM CARD ERROR");
2122 sim_status = SIM_STATUS_INIT_COMPLETED;
2123 dbg("SIM INIT COMPLETED");
2127 sim_status = SIM_STATUS_CARD_ERROR;
2128 dbg("SIM CARD ERROR");
2132 sim_status = SIM_STATUS_CARD_REMOVED;
2137 dbg("SIM SMS Ready");
2138 notify_sms_state(plugin, o, TRUE);
2142 sim_status = SIM_STATUS_UNKNOWN;
2143 dbg("SIM STATE UNKNOWN");
2147 err("Unknown/Unsupported SIM state: [%d]", sim_state);
2151 switch (sim_status) {
2152 case SIM_STATUS_INIT_COMPLETED:
2153 dbg("[SIM] SIM INIT COMPLETED");
2154 if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
2161 case SIM_STATUS_CARD_REMOVED:
2162 dbg("[SIM] SIM CARD REMOVED");
2163 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2166 case SIM_STATUS_CARD_NOT_PRESENT:
2167 dbg("[SIM] SIM CARD NOT PRESENT");
2168 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2171 case SIM_STATUS_CARD_ERROR:
2172 dbg("[SIM] SIM CARD ERROR");
2173 tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
2177 dbg("SIM Status: [0x%02x]", sim_status);
2181 _sim_status_update(o, sim_status);
2184 tcore_at_tok_free(tokens);
2190 static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
2192 const TcoreATResponse *resp = data;
2193 CoreObject *co_sim = NULL;
2197 co_sim = tcore_pending_ref_core_object(p);
2199 if (resp->success > 0) {
2202 on_event_pin_status(co_sim, resp->lines, NULL);
2204 dbg("RESPONSE NOK");
2210 static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
2211 unsigned int data_len, void *data, void *user_data)
2213 TcorePlugin *plugin = tcore_object_ref_plugin(source);
2214 CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
2217 return TCORE_HOOK_RETURN_CONTINUE;
2219 dbg("Get SIM status");
2221 sim_prepare_and_send_pending_request(co_sim, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
2223 return TCORE_HOOK_RETURN_CONTINUE;
2226 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2228 const TcoreATResponse *resp = data;
2229 UserRequest *ur = NULL;
2230 CoreObject *co_sim = NULL;
2231 struct s_sim_property *sp = NULL;
2232 GSList *tokens = NULL;
2233 struct tresp_sim_verify_pins res;
2234 GQueue *queue = NULL;
2240 co_sim = tcore_pending_ref_core_object(p);
2241 sp = tcore_sim_ref_userdata(co_sim);
2242 ur = tcore_pending_ref_user_request(p);
2244 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2246 if (resp->success > 0) {
2248 res.result = SIM_PIN_OPERATION_SUCCESS;
2250 /* Get PIN facility */
2251 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2252 if ((res.pin_type == SIM_PTYPE_PIN1)
2253 || (res.pin_type == SIM_PTYPE_SIM)) {
2254 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
2255 /* Update SIM Status */
2256 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
2261 tcore_user_request_send_response(ur, _find_resp_command(ur),
2262 sizeof(struct tresp_sim_verify_pins), &res);
2264 dbg("RESPONSE NOK");
2265 line = (const char *)resp->final_response;
2266 tokens = tcore_at_tok_new(line);
2267 if (g_slist_length(tokens) < 1) {
2268 dbg("Unkown Error OR String corrupted");
2269 res.result = TCORE_RETURN_3GPP_ERROR;
2272 tcore_user_request_send_response(ur, _find_resp_command(ur),
2273 sizeof(struct tresp_sim_verify_pins), &res);
2275 err = atoi(g_slist_nth_data(tokens, 0));
2276 dbg("Error: [%d]", err);
2278 queue = tcore_object_ref_user_data(co_sim);
2279 ur = tcore_user_request_ref(ur);
2281 /* Get retry count */
2282 _get_retry_count(co_sim, ur);
2286 tcore_at_tok_free(tokens);
2292 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
2294 const TcoreATResponse *resp = data;
2295 UserRequest *ur = NULL;
2296 CoreObject *co_sim = NULL;
2297 struct s_sim_property *sp = NULL;
2298 GSList *tokens = NULL;
2299 struct tresp_sim_verify_puks res;
2300 GQueue *queue = NULL;
2306 co_sim = tcore_pending_ref_core_object(p);
2307 sp = tcore_sim_ref_userdata(co_sim);
2308 ur = tcore_pending_ref_user_request(p);
2310 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2312 if (resp->success > 0) {
2314 res.result = SIM_PIN_OPERATION_SUCCESS;
2315 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2318 tcore_user_request_send_response(ur, _find_resp_command(ur),
2319 sizeof(struct tresp_sim_verify_pins), &res);
2321 dbg("RESPONSE NOK");
2322 line = (const char *)resp->final_response;
2323 tokens = tcore_at_tok_new(line);
2325 if (g_slist_length(tokens) < 1) {
2326 dbg("Unkown Error OR String corrupted");
2327 res.result = TCORE_RETURN_3GPP_ERROR;
2330 tcore_user_request_send_response(ur, _find_resp_command(ur),
2331 sizeof(struct tresp_sim_verify_pins), &res);
2333 err = atoi(g_slist_nth_data(tokens, 0));
2334 queue = tcore_object_ref_user_data(co_sim);
2335 ur = tcore_user_request_ref(ur);
2336 _get_retry_count(co_sim, ur);
2338 tcore_at_tok_free(tokens);
2343 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2345 const TcoreATResponse *resp = data;
2346 UserRequest *ur = NULL;
2347 CoreObject *co_sim = NULL;
2348 struct s_sim_property *sp = NULL;
2349 GSList *tokens = NULL;
2350 struct tresp_sim_change_pins res;
2357 co_sim = tcore_pending_ref_core_object(p);
2358 sp = tcore_sim_ref_userdata(co_sim);
2359 ur = tcore_pending_ref_user_request(p);
2361 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2363 if (resp->success > 0) {
2365 res.result = SIM_PIN_OPERATION_SUCCESS;
2366 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2369 tcore_user_request_send_response(ur, _find_resp_command(ur),
2370 sizeof(struct tresp_sim_change_pins), &res);
2372 dbg("RESPONSE NOK");
2373 line = (const char *)resp->final_response;
2374 tokens = tcore_at_tok_new(line);
2376 if (g_slist_length(tokens) < 1) {
2377 dbg("Unkown Error OR String corrupted");
2378 res.result = TCORE_RETURN_3GPP_ERROR;
2381 tcore_user_request_send_response(ur, _find_resp_command(ur),
2382 sizeof(struct tresp_sim_change_pins), &res);
2384 err = atoi(g_slist_nth_data(tokens, 0));
2385 queue = tcore_object_ref_user_data(co_sim);
2386 ur = tcore_user_request_ref(ur);
2387 _get_retry_count(co_sim, ur);
2391 tcore_at_tok_free(tokens);
2396 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2398 const TcoreATResponse *resp = data;
2399 UserRequest *ur = NULL;
2400 GSList *tokens = NULL;
2401 struct tresp_sim_get_facility_status *res = user_data;
2406 ur = tcore_pending_ref_user_request(p);
2408 res->result = SIM_PIN_OPERATION_SUCCESS;
2410 if (resp->success > 0) {
2413 line = (const char *)resp->lines->data;
2414 tokens = tcore_at_tok_new(line);
2415 if (g_slist_length(tokens) != 1) {
2416 msg("Invalid message");
2417 tcore_at_tok_free(tokens);
2421 res->b_enable = atoi(g_slist_nth_data(tokens, 0));
2423 dbg("RESPONSE NOK");
2424 res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
2429 tcore_user_request_send_response(ur, _find_resp_command(ur),
2430 sizeof(struct tresp_sim_get_facility_status), res);
2432 tcore_at_tok_free(tokens);
2437 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2439 const TcoreATResponse *resp = data;
2440 UserRequest *ur = NULL;
2441 CoreObject *co_sim = NULL;
2442 struct s_sim_property *sp = NULL;
2443 GSList *tokens = NULL;
2444 struct tresp_sim_enable_facility res;
2450 co_sim = tcore_pending_ref_core_object(p);
2451 sp = tcore_sim_ref_userdata(co_sim);
2452 ur = tcore_pending_ref_user_request(p);
2454 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2456 res.result = SIM_CARD_ERROR;
2457 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2459 if (resp->success > 0) {
2462 line = (const char *)resp->lines->data;
2463 tokens = tcore_at_tok_new(line);
2464 if (g_slist_length(tokens) != 1) {
2465 msg("Invalid message");
2468 tcore_user_request_send_response(ur, _find_resp_command(ur),
2469 sizeof(struct tresp_sim_enable_facility), &res);
2470 tcore_at_tok_free(tokens);
2475 res.result = SIM_PIN_OPERATION_SUCCESS;
2479 tcore_user_request_send_response(ur, _find_resp_command(ur),
2480 sizeof(struct tresp_sim_enable_facility), &res);
2484 tcore_at_tok_free(tokens);
2486 dbg("RESPONSE NOK");
2487 queue = tcore_object_ref_user_data(co_sim);
2488 ur = tcore_user_request_ref(ur);
2489 _get_retry_count(co_sim, ur);
2494 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2496 const TcoreATResponse *resp = data;
2497 UserRequest *ur = NULL;
2498 CoreObject *co_sim = NULL;
2499 struct s_sim_property *sp = NULL;
2500 GSList *tokens = NULL;
2501 struct tresp_sim_disable_facility res;
2507 co_sim = tcore_pending_ref_core_object(p);
2508 sp = tcore_sim_ref_userdata(co_sim);
2509 ur = tcore_pending_ref_user_request(p);
2511 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2513 res.result = SIM_CARD_ERROR;
2514 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2516 if (resp->success > 0) {
2519 line = (const char *)resp->lines->data;
2520 tokens = tcore_at_tok_new(line);
2521 if (g_slist_length(tokens) != 1) {
2522 msg("Invalid message");
2525 tcore_user_request_send_response(ur, _find_resp_command(ur),
2526 sizeof(struct tresp_sim_disable_facility), &res);
2527 tcore_at_tok_free(tokens);
2532 res.result = SIM_PIN_OPERATION_SUCCESS;
2535 tcore_user_request_send_response(ur, _find_resp_command(ur),
2536 sizeof(struct tresp_sim_disable_facility), &res);
2540 tcore_at_tok_free(tokens);
2542 dbg("RESPONSE NOK");
2543 queue = tcore_object_ref_user_data(co_sim);
2544 ur = tcore_user_request_ref(ur);
2545 _get_retry_count(co_sim, ur);
2550 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2552 const TcoreATResponse *resp = data;
2553 UserRequest *ur = NULL;
2554 CoreObject *co_sim = NULL;
2555 struct s_sim_property *sp = NULL;
2556 GSList *tokens = NULL;
2559 int attempts_left = 0;
2560 int time_penalty = 0;
2564 co_sim = tcore_pending_ref_core_object(p);
2565 sp = tcore_sim_ref_userdata(co_sim);
2566 ur = tcore_pending_ref_user_request(p);
2568 if (resp->success > 0) {
2571 line = (const char *)resp->lines->data;
2572 dbg("Line: [%s]", line);
2573 tokens = tcore_at_tok_new(line);
2574 if (g_slist_length(tokens) != 3) {
2575 msg("Invalid message");
2576 tcore_at_tok_free(tokens);
2581 lock_type = atoi(g_slist_nth_data(tokens, 0));
2582 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2583 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2585 switch (sp->current_sec_op) {
2586 case SEC_PIN1_VERIFY:
2587 case SEC_PIN2_VERIFY:
2588 case SEC_SIM_VERIFY:
2589 case SEC_ADM_VERIFY:
2591 struct tresp_sim_verify_pins v_pin = {0, };
2593 v_pin.result = SIM_INCORRECT_PASSWORD;
2594 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2595 v_pin.retry_count = attempts_left;
2596 dbg("PIN Type: [0x%02x] Attempts left: [%d]",
2597 v_pin.pin_type, v_pin.retry_count);
2600 tcore_user_request_send_response(ur, _find_resp_command(ur),
2601 sizeof(v_pin), &v_pin);
2605 case SEC_PUK1_VERIFY:
2606 case SEC_PUK2_VERIFY:
2608 struct tresp_sim_verify_puks v_puk = {0, };
2610 v_puk.result = SIM_INCORRECT_PASSWORD;
2611 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2612 v_puk.retry_count = attempts_left;
2613 dbg("PUK Type: [0x%02x] Attempts left: [%d]",
2614 v_puk.pin_type, v_puk.retry_count);
2617 tcore_user_request_send_response(ur, _find_resp_command(ur),
2618 sizeof(v_puk), &v_puk);
2622 case SEC_PIN1_CHANGE:
2623 case SEC_PIN2_CHANGE:
2625 struct tresp_sim_change_pins change_pin = {0, };
2627 change_pin.result = SIM_INCORRECT_PASSWORD;
2628 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2629 change_pin.retry_count = attempts_left;
2630 dbg("PIN Type: [0x%02x] Attempts left: [%d]",
2631 change_pin.pin_type, change_pin.retry_count);
2634 tcore_user_request_send_response(ur, _find_resp_command(ur),
2635 sizeof(change_pin), &change_pin);
2639 case SEC_PIN1_DISABLE:
2640 case SEC_PIN2_DISABLE:
2641 case SEC_FDN_DISABLE:
2642 case SEC_SIM_DISABLE:
2643 case SEC_NET_DISABLE:
2644 case SEC_NS_DISABLE:
2645 case SEC_SP_DISABLE:
2646 case SEC_CP_DISABLE:
2648 struct tresp_sim_disable_facility dis_facility = {0, };
2650 dis_facility.result = SIM_INCORRECT_PASSWORD;
2651 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2652 dis_facility.retry_count = attempts_left;
2653 dbg("Facility Type: [0x%02x] Attempts left: [%d]",
2654 dis_facility.type, dis_facility.retry_count);
2657 tcore_user_request_send_response(ur, _find_resp_command(ur),
2658 sizeof(dis_facility), &dis_facility);
2662 case SEC_PIN1_ENABLE:
2663 case SEC_PIN2_ENABLE:
2664 case SEC_FDN_ENABLE:
2665 case SEC_SIM_ENABLE:
2666 case SEC_NET_ENABLE:
2671 struct tresp_sim_enable_facility en_facility = {0, };
2673 en_facility.result = SIM_INCORRECT_PASSWORD;
2674 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2675 en_facility.retry_count = attempts_left;
2676 dbg("Facility Type: [0x%02x] Attempts left: [%d]",
2677 en_facility.type, en_facility.retry_count);
2680 tcore_user_request_send_response(ur, _find_resp_command(ur),
2681 sizeof(en_facility), &en_facility);
2686 dbg("not handled sec op[%d]", sp->current_sec_op);
2691 tcore_at_tok_free(tokens);
2696 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2698 const TcoreATResponse *resp = data;
2699 UserRequest *ur = NULL;
2700 CoreObject *co_sim = NULL;
2701 struct tresp_sim_set_data resp_cf = {0, };
2702 struct tresp_sim_set_data resp_language = {0, };
2703 struct s_sim_property *sp = NULL;
2704 GSList *tokens = NULL;
2705 enum tel_sim_access_result result = SIM_CARD_ERROR;
2712 co_sim = tcore_pending_ref_core_object(p);
2713 ur = tcore_pending_ref_user_request(p);
2714 sp = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
2716 if (resp->success > 0) {
2719 line = (const char *)resp->lines->data;
2720 tokens = tcore_at_tok_new(line);
2721 if (g_slist_length(tokens) != 2) {
2722 msg("Invalid message");
2726 sw1 = atoi(g_slist_nth_data(tokens, 0));
2727 sw2 = atoi(g_slist_nth_data(tokens, 1));
2729 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2730 result = SIM_ACCESS_SUCCESS;
2732 result = _decode_status_word(sw1, sw2);
2735 dbg("RESPONSE NOK");
2736 result = SIM_ACCESS_FAILED;
2739 switch (sp->file_id) {
2740 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2741 case SIM_EF_USIM_CFIS:
2742 resp_cf.result = result;
2745 tcore_user_request_send_response(ur, _find_resp_command(ur),
2746 sizeof(struct tresp_sim_set_data), &resp_cf);
2751 case SIM_EF_USIM_LI:
2752 case SIM_EF_USIM_PL:
2753 resp_language.result = result;
2756 tcore_user_request_send_response(ur, _find_resp_command(ur),
2757 sizeof(struct tresp_sim_set_data), &resp_language);
2761 dbg("Invalid File ID - %d", sp->file_id);
2764 tcore_at_tok_free(tokens);
2768 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2770 const TcoreATResponse *resp = data;
2771 UserRequest *ur = NULL;
2772 CoreObject *co_sim = NULL;
2773 GSList *tokens = NULL;
2774 struct tresp_sim_transmit_apdu res;
2779 co_sim = tcore_pending_ref_core_object(p);
2780 ur = tcore_pending_ref_user_request(p);
2782 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2783 res.result = SIM_ACCESS_FAILED;
2785 if (resp->success > 0) {
2789 char *decoded_data = NULL;
2790 line = (const char *)resp->lines->data;
2791 tokens = tcore_at_tok_new(line);
2792 if (g_slist_length(tokens) != 2) {
2793 msg("Invalid message");
2796 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
2798 tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
2799 decoded_data = util_hexStringToBytes(tmp);
2801 memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
2803 g_free(decoded_data);
2804 res.result = SIM_ACCESS_SUCCESS;
2807 dbg("RESPONSE NOK");
2813 tcore_user_request_send_response(ur, _find_resp_command(ur),
2814 sizeof(struct tresp_sim_transmit_apdu), &res);
2816 tcore_at_tok_free(tokens);
2820 static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
2822 const TcoreATResponse *resp = data;
2823 UserRequest *ur = NULL;
2824 GSList *tokens = NULL;
2825 struct tresp_sim_get_atr res;
2830 memset(&res, 0, sizeof(struct tresp_sim_get_atr));
2831 ur = tcore_pending_ref_user_request(p);
2833 res.result = SIM_ACCESS_FAILED;
2834 if (resp->success > 0) {
2838 char *decoded_data = NULL;
2839 line = (const char *)resp->lines->data;
2840 tokens = tcore_at_tok_new(line);
2841 if (g_slist_length(tokens) < 1) {
2842 msg("Invalid message");
2846 tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
2847 decoded_data = util_hexStringToBytes(tmp);
2849 res.atr_length = strlen(tmp) / 2;
2850 memcpy((char *)res.atr, decoded_data, res.atr_length);
2852 g_free(decoded_data);
2853 res.result = SIM_ACCESS_SUCCESS;
2856 dbg("RESPONSE NOK");
2862 tcore_user_request_send_response(ur, _find_resp_command(ur),
2863 sizeof(struct tresp_sim_get_atr), &res);
2865 tcore_at_tok_free(tokens);
2869 static void on_response_req_authentication(TcorePending *p, int data_len,
2870 const void *data, void *user_data)
2872 const TcoreATResponse *at_resp = data;
2873 GSList *tokens = NULL;
2874 struct tresp_sim_req_authentication resp_auth;
2875 const struct treq_sim_req_authentication *req_data;
2876 UserRequest *ur = tcore_pending_ref_user_request(p);
2880 memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
2882 if (at_resp == NULL) {
2883 err("at_resp is NULL");
2884 resp_auth.result = SIM_ACCESS_FAILED;
2885 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2889 req_data = tcore_user_request_ref_data(ur, NULL);
2890 if (req_data == NULL) {
2891 err("req_data is NULL");
2892 resp_auth.result = SIM_ACCESS_FAILED;
2893 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2896 resp_auth.auth_type = req_data->auth_type;
2898 if (at_resp->success == TRUE) {
2903 if (at_resp->lines != NULL) {
2904 line = at_resp->lines->data;
2905 dbg("Received data: [%s]", line);
2907 err("at_resp->lines is NULL");
2908 resp_auth.result = SIM_ACCESS_FAILED;
2909 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2913 tokens = tcore_at_tok_new(line);
2914 if (tokens == NULL) {
2915 err("tokens is NULL");
2916 resp_auth.result = SIM_ACCESS_FAILED;
2917 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2921 status = atoi(g_slist_nth_data(tokens, 0));
2924 dbg("Authentications successful");
2925 resp_auth.auth_result = SIM_AUTH_NO_ERROR;
2928 err("Synchronize fail");
2929 resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
2933 resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
2936 err("Does not support security context");
2937 resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
2940 err("Other failure");
2941 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2945 if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
2947 char *convert_kc, *convert_sres;
2949 kc = g_slist_nth_data(tokens, 1);
2951 kc = tcore_at_tok_extract(kc);
2952 dbg("Kc: [%s]", kc);
2953 convert_kc = util_hexStringToBytes(kc);
2954 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
2955 resp_auth.authentication_key_length = strlen(convert_kc);
2956 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
2959 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2965 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2969 sres = g_slist_nth_data(tokens, 2);
2971 sres = tcore_at_tok_extract(sres);
2972 dbg("SRES: [%s]", sres);
2973 convert_sres = util_hexStringToBytes(sres);
2974 if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
2975 resp_auth.resp_length = strlen(convert_sres);
2976 memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
2978 err("Invalid SRES");
2979 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2982 g_free(convert_sres);
2984 err("Invalid SRES");
2985 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
2988 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G) {
2989 char *res, *ck, *ik, *kc;
2990 char *convert_res, *convert_ck;
2991 char *convert_ik, *convert_kc;
2993 res = g_slist_nth_data(tokens, 1);
2995 res = tcore_at_tok_extract(res);
2996 dbg("RES/AUTS: [%s]", res);
2997 convert_res = util_hexStringToBytes(res);
2998 if (convert_ck && strlen(res) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
2999 resp_auth.resp_length = strlen(convert_res);
3000 memcpy(resp_auth.resp_data, convert_res, strlen(convert_res));
3002 err("Invalid RES/AUTS");
3003 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3006 g_free(convert_res);
3008 err("Invalid RES/AUTS");
3009 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3013 ck = g_slist_nth_data(tokens, 2);
3015 ck = tcore_at_tok_extract(ck);
3016 dbg("CK: [%s]", ck);
3017 convert_ck = util_hexStringToBytes(ck);
3018 if (convert_ck && strlen(ck) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3019 resp_auth.cipher_length = strlen(convert_ck);
3020 memcpy(&resp_auth.cipher_data, convert_ck, strlen(convert_ck));
3023 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3029 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3033 ik = g_slist_nth_data(tokens, 3);
3035 ik = tcore_at_tok_extract(ik);
3036 dbg("IK: [%s]", ik);
3037 convert_ik = util_hexStringToBytes(ik);
3038 if (convert_ik && strlen(ik) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3039 resp_auth.integrity_length = strlen(convert_ik);
3040 memcpy(&resp_auth.integrity_data, convert_ik, strlen(convert_ik));
3043 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3049 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3053 kc = g_slist_nth_data(tokens, 4);
3055 kc = tcore_at_tok_extract(kc);
3056 dbg("Kc: [%s]", kc);
3057 convert_kc = util_hexStringToBytes(kc);
3058 if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
3059 resp_auth.authentication_key_length = strlen(convert_kc);
3060 memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
3063 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3069 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3072 } else if (resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
3073 err("Not supported");
3076 err("RESPONSE NOK");
3077 resp_auth.result = SIM_ACCESS_FAILED;
3078 resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
3082 tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
3083 sizeof(struct tresp_sim_req_authentication), &resp_auth);
3085 tcore_at_tok_free(tokens);
3088 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
3090 TcoreHal *hal = NULL;
3091 TcoreATRequest *req = NULL;
3092 TcorePending *pending = NULL;
3093 char *cmd_str = NULL;
3094 const struct treq_sim_verify_pins *req_data = NULL;
3095 struct s_sim_property *sp = NULL;
3096 TReturn ret = TCORE_RETURN_FAILURE;
3100 if ((o == NULL )|| (ur == NULL))
3101 return TCORE_RETURN_EINVAL;
3103 hal = tcore_object_get_hal(o);
3104 if (FALSE == tcore_hal_get_power_state(hal)) {
3105 err("CP NOT READY");
3106 return TCORE_RETURN_ENOSYS;
3109 sp = tcore_sim_ref_userdata(o);
3110 pending = tcore_pending_new(o, 0);
3111 req_data = tcore_user_request_ref_data(ur, NULL);
3113 if (req_data->pin_type == SIM_PTYPE_PIN1) {
3114 sp->current_sec_op = SEC_PIN1_VERIFY;
3115 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3116 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
3117 sp->current_sec_op = SEC_PIN2_VERIFY;
3118 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
3119 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
3120 sp->current_sec_op = SEC_SIM_VERIFY;
3121 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3122 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
3123 sp->current_sec_op = SEC_ADM_VERIFY;
3124 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
3126 return TCORE_RETURN_EINVAL;
3129 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3132 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3133 req->cmd, req->prefix, strlen(req->cmd));
3135 tcore_pending_set_request_data(pending, 0, req);
3136 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
3137 tcore_pending_link_user_request(pending, ur);
3138 ret = tcore_hal_send_request(hal, pending);
3144 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
3146 TcoreHal *hal = NULL;
3147 TcoreATRequest *req = NULL;
3148 TcorePending *pending = NULL;
3149 char *cmd_str = NULL;
3150 const struct treq_sim_verify_puks *req_data;
3151 struct s_sim_property *sp = NULL;
3152 TReturn ret = TCORE_RETURN_FAILURE;
3156 if ((o == NULL )|| (ur == NULL))
3157 return TCORE_RETURN_EINVAL;
3159 hal = tcore_object_get_hal(o);
3160 if (FALSE == tcore_hal_get_power_state(hal)) {
3161 err("CP NOT READY");
3162 return TCORE_RETURN_ENOSYS;
3165 sp = tcore_sim_ref_userdata(o);
3166 pending = tcore_pending_new(o, 0);
3167 req_data = tcore_user_request_ref_data(ur, NULL);
3169 if (req_data->puk_type == SIM_PTYPE_PUK1) {
3170 sp->current_sec_op = SEC_PUK1_VERIFY;
3171 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3172 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
3173 sp->current_sec_op = SEC_PUK2_VERIFY;
3174 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
3176 return TCORE_RETURN_EINVAL;
3179 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3182 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3183 req->cmd, req->prefix, strlen(req->cmd));
3185 tcore_pending_set_request_data(pending, 0, req);
3186 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
3187 tcore_pending_link_user_request(pending, ur);
3188 ret = tcore_hal_send_request(hal, pending);
3194 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
3196 TcoreHal *hal = NULL;
3197 TcoreATRequest *req = NULL;
3198 TcorePending *pending = NULL;
3199 char *cmd_str = NULL;
3200 const struct treq_sim_change_pins *req_data;
3201 struct s_sim_property *sp = NULL;
3204 TReturn ret = TCORE_RETURN_FAILURE;
3208 if ((o == NULL )|| (ur == NULL))
3209 return TCORE_RETURN_EINVAL;
3211 hal = tcore_object_get_hal(o);
3212 if (FALSE == tcore_hal_get_power_state(hal)) {
3213 err("CP NOT READY");
3214 return TCORE_RETURN_ENOSYS;
3217 sp = tcore_sim_ref_userdata(o);
3218 pending = tcore_pending_new(o, 0);
3219 req_data = tcore_user_request_ref_data(ur, NULL);
3221 if (req_data->type == SIM_PTYPE_PIN1) {
3222 sp->current_sec_op = SEC_PIN1_CHANGE;
3223 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
3224 } else if (req_data->type == SIM_PTYPE_PIN2) {
3225 sp->current_sec_op = SEC_PIN2_CHANGE;
3226 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
3228 return TCORE_RETURN_EINVAL;
3230 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
3233 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3234 req->cmd, req->prefix, strlen(req->cmd));
3236 tcore_pending_set_request_data(pending, 0, req);
3237 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
3238 tcore_pending_link_user_request(pending, ur);
3239 ret = tcore_hal_send_request(hal, pending);
3245 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
3247 TcoreHal *hal = NULL;
3248 TcoreATRequest *req = NULL;
3249 TcorePending *pending = NULL;
3250 char *cmd_str = NULL;
3251 const struct treq_sim_get_facility_status *req_data;
3252 struct tresp_sim_get_facility_status *res;
3254 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
3255 TReturn ret = TCORE_RETURN_FAILURE;
3259 if ((o == NULL )|| (ur == NULL))
3260 return TCORE_RETURN_EINVAL;
3262 hal = tcore_object_get_hal(o);
3263 if (FALSE == tcore_hal_get_power_state(hal)) {
3264 err("CP NOT READY");
3265 return TCORE_RETURN_ENOSYS;
3268 pending = tcore_pending_new(o, 0);
3269 req_data = tcore_user_request_ref_data(ur, NULL);
3271 res = g_try_new0(struct tresp_sim_get_facility_status, 1);
3273 return TCORE_RETURN_ENOMEM;
3275 res->type = req_data->type;
3277 if (req_data->type == SIM_FACILITY_PS) {
3278 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3279 } else if (req_data->type == SIM_FACILITY_SC) {
3280 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3281 } else if (req_data->type == SIM_FACILITY_FD) {
3282 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3283 } else if (req_data->type == SIM_FACILITY_PN) {
3284 fac = "PN"; /*Network Personalization*/
3285 } else if (req_data->type == SIM_FACILITY_PU) {
3286 fac = "PU"; /*network sUbset Personalization*/
3287 } else if (req_data->type == SIM_FACILITY_PP) {
3288 fac = "PP"; /*service Provider Personalization*/
3289 } else if (req_data->type == SIM_FACILITY_PC) {
3290 fac = "PC"; /*Corporate Personalization*/
3292 return TCORE_RETURN_EINVAL;
3294 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3295 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3298 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3299 req->cmd, req->prefix, strlen(req->cmd));
3301 tcore_pending_set_request_data(pending, 0, req);
3302 tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
3303 tcore_pending_link_user_request(pending, ur);
3304 ret = tcore_hal_send_request(hal, pending);
3310 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
3312 TcoreHal *hal = NULL;
3313 TcoreATRequest *req = NULL;
3314 TcorePending *pending = NULL;
3315 char *cmd_str = NULL;
3316 const struct treq_sim_enable_facility *req_data;
3317 struct s_sim_property *sp = NULL;
3319 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
3320 TReturn ret = TCORE_RETURN_FAILURE;
3324 if ((o == NULL )|| (ur == NULL))
3325 return TCORE_RETURN_EINVAL;
3327 hal = tcore_object_get_hal(o);
3328 if (FALSE == tcore_hal_get_power_state(hal)) {
3329 err("CP NOT READY");
3330 return TCORE_RETURN_ENOSYS;
3333 sp = tcore_sim_ref_userdata(o);
3334 pending = tcore_pending_new(o, 0);
3335 req_data = tcore_user_request_ref_data(ur, NULL);
3337 if (req_data->type == SIM_FACILITY_PS) {
3338 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3339 sp->current_sec_op = SEC_SIM_ENABLE;
3340 } else if (req_data->type == SIM_FACILITY_SC) {
3341 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3342 sp->current_sec_op = SEC_PIN1_ENABLE;
3343 } else if (req_data->type == SIM_FACILITY_FD) {
3344 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3345 sp->current_sec_op = SEC_FDN_ENABLE;
3346 } else if (req_data->type == SIM_FACILITY_PN) {
3347 fac = "PN"; /*Network Personalization*/
3348 sp->current_sec_op = SEC_NET_ENABLE;
3349 } else if (req_data->type == SIM_FACILITY_PU) {
3350 fac = "PU"; /*network sUbset Personalization*/
3351 sp->current_sec_op = SEC_NS_ENABLE;
3352 } else if (req_data->type == SIM_FACILITY_PP) {
3353 fac = "PP"; /*service Provider Personalization*/
3354 sp->current_sec_op = SEC_SP_ENABLE;
3355 } else if (req_data->type == SIM_FACILITY_PC) {
3356 fac = "PC"; /*Corporate Personalization*/
3357 sp->current_sec_op = SEC_CP_ENABLE;
3359 return TCORE_RETURN_EINVAL;
3361 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3362 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3365 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3366 req->cmd, req->prefix, strlen(req->cmd));
3368 tcore_pending_set_request_data(pending, 0, req);
3369 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
3370 tcore_pending_link_user_request(pending, ur);
3371 ret = tcore_hal_send_request(hal, pending);
3377 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
3380 TcoreATRequest *req;
3381 TcorePending *pending = NULL;
3382 char *cmd_str = NULL;
3383 const struct treq_sim_enable_facility *req_data;
3384 struct s_sim_property *sp = NULL;
3386 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
3387 TReturn ret = TCORE_RETURN_FAILURE;
3391 if ((o == NULL )|| (ur == NULL))
3392 return TCORE_RETURN_EINVAL;
3394 hal = tcore_object_get_hal(o);
3395 if (FALSE == tcore_hal_get_power_state(hal)) {
3396 err("CP NOT READY");
3397 return TCORE_RETURN_ENOSYS;
3400 sp = tcore_sim_ref_userdata(o);
3401 pending = tcore_pending_new(o, 0);
3402 req_data = tcore_user_request_ref_data(ur, NULL);
3404 if (req_data->type == SIM_FACILITY_PS) {
3405 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
3406 sp->current_sec_op = SEC_SIM_DISABLE;
3407 } else if (req_data->type == SIM_FACILITY_SC) {
3408 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
3409 sp->current_sec_op = SEC_PIN1_DISABLE;
3410 } else if (req_data->type == SIM_FACILITY_FD) {
3411 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
3412 sp->current_sec_op = SEC_FDN_DISABLE;
3413 } else if (req_data->type == SIM_FACILITY_PN) {
3414 fac = "PN"; /*Network Personalization*/
3415 sp->current_sec_op = SEC_NET_DISABLE;
3416 } else if (req_data->type == SIM_FACILITY_PU) {
3417 fac = "PU"; /*network sUbset Personalization*/
3418 sp->current_sec_op = SEC_NS_DISABLE;
3419 } else if (req_data->type == SIM_FACILITY_PP) {
3420 fac = "PP"; /*service Provider Personalization*/
3421 sp->current_sec_op = SEC_SP_DISABLE;
3422 } else if (req_data->type == SIM_FACILITY_PC) {
3423 fac = "PC"; /*Corporate Personalization*/
3424 sp->current_sec_op = SEC_CP_DISABLE;
3426 return TCORE_RETURN_EINVAL;
3428 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
3429 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
3432 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3433 req->cmd, req->prefix, strlen(req->cmd));
3435 tcore_pending_set_request_data(pending, 0, req);
3436 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
3437 tcore_pending_link_user_request(pending, ur);
3438 ret = tcore_hal_send_request(hal, pending);
3444 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
3446 TcoreHal *hal = NULL;
3447 TcoreATRequest *req = NULL;
3448 TcorePending *pending = NULL;
3449 char *cmd_str = NULL;
3451 const struct treq_sim_get_lock_info *req_data;
3452 struct s_sim_property *sp = NULL;
3456 hal = tcore_object_get_hal(o);
3458 sp = tcore_sim_ref_userdata(o);
3459 pending = tcore_pending_new(o, 0);
3460 req_data = tcore_user_request_ref_data(ur, NULL);
3462 if ((o == NULL )|| (ur == NULL))
3463 return TCORE_RETURN_EINVAL;
3465 switch (req_data->type) {
3466 case SIM_FACILITY_PS:
3467 lock_type = 9; // IMSI lock
3470 case SIM_FACILITY_SC:
3474 case SIM_FACILITY_FD:
3478 case SIM_FACILITY_PN:
3482 case SIM_FACILITY_PU:
3486 case SIM_FACILITY_PP:
3490 case SIM_FACILITY_PC:
3497 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
3498 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
3501 dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
3502 req->cmd, req->prefix, strlen(req->cmd));
3504 tcore_pending_set_request_data(pending, 0, req);
3505 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
3506 tcore_pending_link_user_request(pending, ur);
3507 tcore_hal_send_request(hal, pending);
3510 return TCORE_RETURN_SUCCESS;
3513 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
3515 TReturn api_ret = TCORE_RETURN_SUCCESS;
3516 enum tcore_request_command command;
3520 if ((o == NULL )|| (ur == NULL))
3521 return TCORE_RETURN_EINVAL;
3523 command = tcore_user_request_get_command(ur);
3524 if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
3525 err("CP NOT READY");
3526 return TCORE_RETURN_ENOSYS;
3530 case TREQ_SIM_GET_ECC:
3531 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
3534 case TREQ_SIM_GET_LANGUAGE:
3535 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
3536 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
3537 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
3538 api_ret = _get_file_info(o, ur, SIM_EF_LP);
3540 api_ret = TCORE_RETURN_ENOSYS;
3543 case TREQ_SIM_GET_ICCID:
3544 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
3547 case TREQ_SIM_GET_MAILBOX:
3548 if (tcore_sim_get_cphs_status(o))
3549 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
3551 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
3554 case TREQ_SIM_GET_CALLFORWARDING:
3555 if (tcore_sim_get_cphs_status(o))
3556 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
3558 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
3561 case TREQ_SIM_GET_MESSAGEWAITING:
3562 if (tcore_sim_get_cphs_status(o))
3563 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
3565 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
3568 case TREQ_SIM_GET_CPHS_INFO:
3569 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
3572 case TREQ_SIM_GET_MSISDN:
3573 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
3576 case TREQ_SIM_GET_SPN:
3577 dbg("enter case SPN");
3578 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
3581 case TREQ_SIM_GET_SPDI:
3582 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
3585 case TREQ_SIM_GET_OPL:
3586 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
3589 case TREQ_SIM_GET_PNN:
3590 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
3593 case TREQ_SIM_GET_CPHS_NETNAME:
3594 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
3597 case TREQ_SIM_GET_OPLMNWACT:
3598 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
3602 dbg("error - not handled read treq command[%d]", command);
3603 api_ret = TCORE_RETURN_EINVAL;
3610 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
3613 char *cmd_str = NULL;
3614 TReturn ret = TCORE_RETURN_SUCCESS;
3615 char *encoded_data = NULL;
3616 int encoded_len = 0;
3617 enum tcore_request_command command;
3618 enum tel_sim_file_id ef = SIM_EF_INVALID;
3619 const struct treq_sim_set_callforwarding *cf;
3620 const struct treq_sim_set_language *cl;
3621 struct s_sim_property file_meta = {0, };
3628 struct tel_sim_language sim_language;
3632 command = tcore_user_request_get_command(ur);
3636 if ((o == NULL )|| (ur == NULL)) {
3637 return TCORE_RETURN_EINVAL;
3640 hal = tcore_object_get_hal(o);
3641 if (FALSE == tcore_hal_get_power_state(hal)) {
3642 err("CP NOT READY");
3643 return TCORE_RETURN_ENOSYS;
3647 case TREQ_SIM_SET_LANGUAGE:
3648 cl = tcore_user_request_ref_data(ur, NULL);
3649 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
3652 sim_language.language_count = 1;
3653 sim_language.language[0] = cl->language;
3654 dbg("language %d", cl->language);
3656 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
3659 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
3661 encoded_data = (char *)malloc(2 * (sim_language.language_count) + 1);
3662 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
3663 result = util_byte_to_hex(tmp, encoded_data, out_length);
3668 dbg("encoded_data - %s ---", encoded_data);
3669 dbg("out_length - %d ---", out_length);
3670 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
3673 tmp = tcore_sim_encode_li(&out_length, &sim_language);
3675 encoded_data = (char *)malloc(2 * (out_length) + 1);
3676 memset(encoded_data, 0x00, (2 * out_length) + 1);
3677 result = util_byte_to_hex(tmp, encoded_data, out_length);
3682 dbg("encoded_data - %s ---", encoded_data);
3683 dbg("out_length - %d ---", out_length);
3685 ret = TCORE_RETURN_ENOSYS;
3689 case TREQ_SIM_SET_CALLFORWARDING:
3690 cf = tcore_user_request_ref_data(ur, NULL);
3691 if (tcore_sim_get_cphs_status(o)) {
3692 tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf);
3693 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
3697 encoded_data = (char *)g_try_malloc0(2 * (p3) + 1);
3698 result = util_byte_to_hex(tmp, encoded_data, p3);
3699 cmd = 214; /*command - 214 : UPDATE BINARY*/
3701 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
3702 ef = SIM_EF_USIM_CFIS;
3706 encoded_data = (char *)g_try_malloc0(2 * (encoded_len) + 1);
3707 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3708 cmd = 220; /*command - 220 : UPDATE RECORD*/
3713 dbg("error - not handled update treq command[%d]", command);
3714 ret = TCORE_RETURN_EINVAL;
3718 file_meta.file_id = ef;
3719 dbg("File ID: [0x%x]", file_meta.file_id);
3721 trt = tcore_user_request_set_metainfo(ur,
3722 sizeof(struct s_sim_property), &file_meta);
3723 dbg("trt[%d]", trt);
3725 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3727 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CRSM:",
3728 TCORE_AT_SINGLELINE, ur,
3729 on_response_update_file, hal,
3733 g_free(encoded_data);
3742 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3744 const struct treq_sim_transmit_apdu *req_data;
3745 TcoreHal *hal = NULL;
3746 char *cmd_str = NULL;
3749 TReturn ret = TCORE_RETURN_FAILURE;
3753 if ((o == NULL )|| (ur == NULL))
3754 return TCORE_RETURN_EINVAL;
3756 hal = tcore_object_get_hal(o);
3757 if (FALSE == tcore_hal_get_power_state(hal)) {
3758 err("CP NOT READY");
3759 return TCORE_RETURN_ENOSYS;
3762 req_data = tcore_user_request_ref_data(ur, NULL);
3764 apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
3765 result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
3766 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen(apdu), apdu);
3768 ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
3769 TCORE_AT_SINGLELINE, ur,
3770 on_response_transmit_apdu, hal,
3779 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
3781 TcoreHal *hal = NULL;
3785 if ((o == NULL )|| (ur == NULL)) {
3786 err("Invalid parameters");
3787 return TCORE_RETURN_EINVAL;
3790 hal = tcore_object_get_hal(o);
3791 if (FALSE == tcore_hal_get_power_state(hal)) {
3792 err("CP NOT READY");
3793 return TCORE_RETURN_ENOSYS;
3796 return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
3797 TCORE_AT_SINGLELINE, ur,
3798 on_response_get_atr, hal,
3802 static TReturn s_req_authentication(CoreObject *co, UserRequest *ur)
3804 const struct treq_sim_req_authentication *req_data;
3805 char *cmd_str = NULL;
3806 enum tel_sim_type sim_type;
3809 TReturn ret = TCORE_RETURN_FAILURE;
3810 char *convert_rand = NULL;
3811 char *convert_autn = NULL;
3815 req_data = tcore_user_request_ref_data(ur, NULL);
3816 if (req_data == NULL) {
3817 err("req_data is NULL");
3821 if (req_data->rand_data != NULL) {
3822 convert_rand = util_hex_to_string(req_data->rand_data,
3823 req_data->rand_length);
3824 dbg("Convert RAND hex to string: [%s]", convert_rand);
3826 err("rand_data is NULL");
3830 sim_type = tcore_sim_get_type(co);
3837 err("Not supported");
3838 ret = TCORE_RETURN_ENOSYS;
3842 switch (req_data->auth_type) {
3843 case SIM_AUTH_TYPE_GSM:
3845 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"", session_id,
3846 context_type, convert_rand);
3848 case SIM_AUTH_TYPE_3G:
3850 if (req_data->autn_data != NULL) {
3851 convert_autn = util_hex_to_string(req_data->autn_data,
3852 req_data->autn_length);
3853 dbg("Convert AUTN hex to string: [%s]", convert_autn);
3855 err("autn_data is NULL");
3858 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3859 session_id, context_type,
3860 convert_rand, convert_autn);
3863 err("Not supported");
3864 ret = TCORE_RETURN_ENOSYS;
3868 ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
3869 TCORE_AT_SINGLELINE, ur,
3870 on_response_req_authentication, NULL, NULL, NULL);
3874 g_free(convert_rand);
3875 g_free(convert_autn);
3880 /* SIM Operations */
3881 static struct tcore_sim_operations sim_ops = {
3882 .verify_pins = s_verify_pins,
3883 .verify_puks = s_verify_puks,
3884 .change_pins = s_change_pins,
3885 .get_facility_status = s_get_facility_status,
3886 .enable_facility = s_enable_facility,
3887 .disable_facility = s_disable_facility,
3888 .get_lock_info = s_get_lock_info,
3889 .read_file = s_read_file,
3890 .update_file = s_update_file,
3891 .transmit_apdu = s_transmit_apdu,
3892 .get_atr = s_get_atr,
3893 .req_authentication = s_req_authentication,
3896 gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim)
3898 struct s_sim_property *file_meta;
3902 tcore_sim_override_ops(co_sim, &sim_ops);
3904 file_meta = g_try_new0(struct s_sim_property, 1);
3905 if (file_meta == NULL)
3908 tcore_sim_link_userdata(co_sim, file_meta);
3910 tcore_object_override_callback(co_sim, "+XLOCK:",
3911 on_event_facility_lock_status, NULL);
3912 tcore_object_override_callback(co_sim, "+XSIM:",
3913 on_event_pin_status, NULL);
3915 tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
3916 TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
3923 void s_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
3925 struct s_sim_property *file_meta;
3927 file_meta = tcore_sim_ref_userdata(co_sim);