4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <core_object.h>
32 #include <user_request.h>
39 #define ID_RESERVED_AT 0x0229
41 #define SWAPBYTES16(x) \
43 unsigned short int data = *(unsigned short int *) &(x); \
44 data = ((data & 0xff00) >> 8) | \
45 ((data & 0x00ff) << 8); \
46 *(unsigned short int *) &(x) = data; \
49 enum s_sim_file_type_e {
50 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
51 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
52 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
53 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
54 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
69 SEC_PIN2_DISABLE, // 10
90 SEC_SIM_UNKNOWN = 0xff
93 struct s_sim_property {
94 gboolean b_valid; /**< Valid or not */
95 enum tel_sim_file_id file_id; /**< File identifier */
96 enum s_sim_file_type_e file_type; /**< File type and structure */
97 int rec_length; /**< Length of one record in file */
98 int rec_count; /**< Number of records in file */
99 int data_size; /**< File size */
100 int current_index; /**< current index to read */
101 enum tel_sim_status first_recv_status;
102 enum s_sim_sec_op_e current_sec_op; /**< current index to read */
103 struct tresp_sim_read files;
106 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
107 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
108 static gboolean _get_sim_type(CoreObject *o);
109 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
110 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
111 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
112 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
113 static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
114 extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
116 static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data)
118 dbg("on_confirmation_sim_message_send - msg out from queue.\n");
120 if (result == FALSE) {
128 static enum tcore_response_command _find_resp_command(UserRequest *ur)
130 enum tcore_request_command command;
132 command = tcore_user_request_get_command(ur);
134 case TREQ_SIM_VERIFY_PINS:
135 return TRESP_SIM_VERIFY_PINS;
138 case TREQ_SIM_VERIFY_PUKS:
139 return TRESP_SIM_VERIFY_PUKS;
142 case TREQ_SIM_CHANGE_PINS:
143 return TRESP_SIM_CHANGE_PINS;
146 case TREQ_SIM_GET_FACILITY_STATUS:
147 return TRESP_SIM_GET_FACILITY_STATUS;
150 case TREQ_SIM_DISABLE_FACILITY:
151 return TRESP_SIM_DISABLE_FACILITY;
154 case TREQ_SIM_ENABLE_FACILITY:
155 return TRESP_SIM_ENABLE_FACILITY;
158 case TREQ_SIM_GET_LOCK_INFO:
159 return TRESP_SIM_GET_LOCK_INFO;
162 case TREQ_SIM_TRANSMIT_APDU:
163 return TRESP_SIM_TRANSMIT_APDU;
166 case TREQ_SIM_GET_ATR:
167 return TRESP_SIM_GET_ATR;
170 case TREQ_SIM_GET_ECC:
171 return TRESP_SIM_GET_ECC;
174 case TREQ_SIM_GET_LANGUAGE:
175 return TRESP_SIM_GET_LANGUAGE;
178 case TREQ_SIM_SET_LANGUAGE:
179 return TRESP_SIM_SET_LANGUAGE;
182 case TREQ_SIM_GET_ICCID:
183 return TRESP_SIM_GET_ICCID;
186 case TREQ_SIM_GET_MAILBOX:
187 return TRESP_SIM_GET_MAILBOX;
190 case TREQ_SIM_GET_CALLFORWARDING:
191 return TRESP_SIM_GET_CALLFORWARDING;
194 case TREQ_SIM_SET_CALLFORWARDING:
195 return TRESP_SIM_SET_CALLFORWARDING;
198 case TREQ_SIM_GET_MESSAGEWAITING:
199 return TRESP_SIM_GET_MESSAGEWAITING;
202 case TREQ_SIM_GET_CPHS_INFO:
203 return TRESP_SIM_GET_CPHS_INFO;
206 case TREQ_SIM_GET_MSISDN:
207 return TRESP_SIM_GET_MSISDN;
210 case TREQ_SIM_GET_SPN:
211 return TRESP_SIM_GET_SPN;
214 case TREQ_SIM_GET_SPDI:
215 return TRESP_SIM_GET_SPDI;
218 case TREQ_SIM_GET_OPL:
219 return TRESP_SIM_GET_OPL;
222 case TREQ_SIM_GET_PNN:
223 return TRESP_SIM_GET_PNN;
226 case TREQ_SIM_GET_CPHS_NETNAME:
227 return TRESP_SIM_GET_CPHS_NETNAME;
230 case TREQ_SIM_GET_OPLMNWACT:
231 return TRESP_SIM_GET_OPLMNWACT;
234 case TREQ_SIM_REQ_AUTHENTICATION:
235 return TRESP_SIM_REQ_AUTHENTICATION;
241 return TRESP_UNKNOWN;
244 static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
248 dbg("current sec_op[%d]", op);
251 case SEC_PIN1_VERIFY:
252 case SEC_PIN1_CHANGE:
253 ret_type = SIM_PTYPE_PIN1;
256 case SEC_PIN2_VERIFY:
257 case SEC_PIN2_CHANGE:
258 ret_type = SIM_PTYPE_PIN2;
261 case SEC_PUK1_VERIFY:
262 ret_type = SIM_PTYPE_PUK1;
265 case SEC_PUK2_VERIFY:
266 ret_type = SIM_PTYPE_PUK2;
270 ret_type = SIM_PTYPE_SIM;
274 ret_type = SIM_PTYPE_ADM;
277 case SEC_PIN1_ENABLE:
278 case SEC_PIN1_DISABLE:
279 case SEC_PIN1_STATUS:
280 ret_type = SIM_FACILITY_SC;
284 case SEC_SIM_DISABLE:
286 ret_type = SIM_FACILITY_PS;
290 case SEC_NET_DISABLE:
292 ret_type = SIM_FACILITY_PN;
298 ret_type = SIM_FACILITY_PU;
304 ret_type = SIM_FACILITY_PP;
310 ret_type = SIM_FACILITY_PC;
314 case SEC_FDN_DISABLE:
316 ret_type = SIM_FACILITY_FD;
320 dbg("not handled current sec op[%d]", op)
326 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
328 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
330 if (status_word1 == 0x93 && status_word2 == 0x00) {
331 rst = SIM_ACCESS_FAILED;
332 /*Failed SIM request command*/
333 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
334 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
335 rst = SIM_ACCESS_FAILED;
336 /*Failed SIM request command*/
337 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
338 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
339 rst = SIM_ACCESS_FAILED;
340 /*Failed SIM request command*/
341 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
342 status_word1, status_word2);
343 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
344 rst = SIM_ACCESS_FILE_NOT_FOUND;
345 /*Failed SIM request command*/
346 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
347 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
348 rst = SIM_ACCESS_FAILED; /* MOdem not support */
349 /*Failed SIM request command*/
350 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
351 status_word1, status_word2);
352 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
353 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
354 /*Failed SIM request command*/
355 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
356 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
357 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
358 /*Failed SIM request command*/
359 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
360 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
361 status_word1, status_word2);
362 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
363 status_word1, status_word2);
364 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
365 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
366 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
367 /*Failed SIM request command*/
368 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
369 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
370 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
371 /*Failed SIM request command*/
372 dbg(" error - Contradiction with invalidation status [%x][%x]",
373 status_word1, status_word2);
374 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
375 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
376 /*Failed SIM request command*/
377 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
378 status_word1, status_word2);
379 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
380 status_word1, status_word2);
381 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
382 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
383 rst = SIM_ACCESS_FAILED;
384 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
385 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
386 rst = SIM_ACCESS_FAILED;
387 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
388 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
389 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
390 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
391 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
392 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
393 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
394 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
395 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
396 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
397 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
398 rst = SIM_ACCESS_FAILED;
399 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
400 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
401 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
402 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
403 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
404 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
405 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
407 rst = SIM_ACCESS_CARD_ERROR;
408 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
413 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
416 Storage *strg = NULL;
417 char *old_imsi = NULL;
418 char new_imsi[15 + 1] = {0, };
420 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
422 dbg("there is no valid server at this point");
425 strg = (Storage *) tcore_server_find_storage(s, "vconf");
427 dbg("there is no valid storage plugin");
430 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
431 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
432 new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
434 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
435 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
437 if (old_imsi != NULL) {
438 if (strncmp(old_imsi, new_imsi, 15) != 0) {
440 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
441 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
443 tcore_sim_set_identification(o, TRUE);
446 tcore_sim_set_identification(o, FALSE);
449 dbg("OLD SIM VALUE IS NULL. NEW SIM");
450 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
451 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
453 tcore_sim_set_identification(o, TRUE);
458 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
460 struct tresp_sim_read resp = {0, };
461 struct s_sim_property *file_meta = NULL;
463 dbg("EF[0x%x] access Result[%d]", ef, rt);
466 memset(&resp.data, 0x00, sizeof(resp.data));
467 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
469 if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
470 && (rt != SIM_ACCESS_SUCCESS)) {
471 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
477 if (rt == SIM_ACCESS_SUCCESS) {
478 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
479 /* if (po->language_file == 0x00)
480 po->language_file = SIM_EF_ELP;*/
481 _get_file_data(o, ur, ef, 0, file_meta->data_size);
483 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
484 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
485 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
486 _get_file_info(o, ur, SIM_EF_LP);
487 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
489 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
490 /* EFELPand EFLI not present at this point. */
491 /* po->language.lang_cnt = 0;*/
492 tcore_user_request_send_response(ur, _find_resp_command(ur),
493 sizeof(struct tresp_sim_read), &resp);
499 case SIM_EF_LP: // same with SIM_EF_USIM_LI
500 if (rt == SIM_ACCESS_SUCCESS) {
501 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
502 _get_file_data(o, ur, ef, 0, file_meta->data_size);
504 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
505 tcore_sim_get_type(o));
506 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
507 tcore_user_request_send_response(ur, _find_resp_command(ur),
508 sizeof(struct tresp_sim_read), &resp);
511 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
512 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
513 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
514 _get_file_info(o, ur, SIM_EF_ELP);
520 if (rt == SIM_ACCESS_SUCCESS) {
521 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
522 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
524 /* EFELIand EFPL not present, so set language count as zero and select ECC */
526 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
527 tcore_user_request_send_response(ur, _find_resp_command(ur),
528 sizeof(struct tresp_sim_read), &resp);
534 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
535 _get_file_data(o, ur, ef, 0, file_meta->data_size);
536 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
537 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
538 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
541 file_meta->current_index++;
542 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
551 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
552 case SIM_EF_CPHS_VOICE_MSG_WAITING:
553 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
554 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
555 case SIM_EF_CPHS_DYNAMICFLAGS:
556 case SIM_EF_CPHS_DYNAMIC2FLAG:
557 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
558 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
559 _get_file_data(o, ur, ef, 0, file_meta->data_size);
562 case SIM_EF_CPHS_CPHS_INFO:
563 if (rt == SIM_ACCESS_SUCCESS) {
564 tcore_sim_set_cphs_status(o, TRUE);
565 if (!tcore_user_request_ref_communicator(ur)) {
566 dbg("internal CPHS INFO request before sim status update");
567 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
569 dbg("external CPHS INFO request");
570 _get_file_data(o, ur, ef, 0, file_meta->data_size);
573 tcore_sim_set_cphs_status(o, FALSE);
574 if (!tcore_user_request_ref_communicator(ur)) {
575 dbg("internal CPHS INFO request before sim status update");
576 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
578 dbg("external CPHS INFO request");
579 tcore_user_request_send_response(ur, _find_resp_command(ur),
580 sizeof(struct tresp_sim_read), &resp);
586 case SIM_EF_USIM_CFIS:
587 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
588 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
590 file_meta->current_index++;
591 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
596 case SIM_EF_USIM_MWIS:
597 case SIM_EF_USIM_MBI:
599 case SIM_EF_CPHS_MAILBOX_NUMBERS:
600 case SIM_EF_CPHS_INFORMATION_NUMBERS:
601 file_meta->current_index++;
602 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
606 dbg("error - File id for get file info [0x%x]", ef);
612 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
614 struct s_sim_property *file_meta = NULL;
618 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
619 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
620 switch (file_meta->file_id) {
625 if (decode_ret == TRUE) {
626 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
627 /* po->language_file = SIM_EF_LP;*/
628 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
629 /* po->language_file = SIM_EF_ELP;*/
631 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
634 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
635 - EFELP is not available;
636 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
637 - the ME does not support any of the languages in EFELP.
640 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
641 - if the EFLI has the value 'FFFF' in its highest priority position
642 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
644 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
645 if (file_meta->file_id == SIM_EF_LP) {
646 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
648 _get_file_info(o, ur, SIM_EF_LP);
650 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
651 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
652 _get_file_info(o, ur, SIM_EF_ELP);
654 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
661 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
662 if (file_meta->current_index == file_meta->rec_count) {
663 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
665 file_meta->current_index++;
666 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
668 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
669 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
671 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
676 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
677 _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
681 if (file_meta->current_index == file_meta->rec_count) {
682 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
684 file_meta->current_index++;
685 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
690 if (file_meta->current_index == file_meta->rec_count) {
691 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
693 file_meta->current_index++;
694 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
699 if (file_meta->current_index == file_meta->rec_count) {
700 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
702 file_meta->current_index++;
703 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
707 case SIM_EF_USIM_CFIS:
708 case SIM_EF_USIM_MWIS:
709 case SIM_EF_USIM_MBI:
711 case SIM_EF_CPHS_MAILBOX_NUMBERS:
712 case SIM_EF_CPHS_INFORMATION_NUMBERS:
713 if (file_meta->current_index == file_meta->rec_count) {
714 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
716 file_meta->current_index++;
717 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
721 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
722 file_meta->files.result = rt;
723 if (decode_ret == TRUE && rt == SIM_ACCESS_SUCCESS) {
724 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));
726 _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
729 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
730 if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
731 file_meta->files.result = SIM_ACCESS_SUCCESS;
733 if (strlen((char *) file_meta->files.data.cphs_net.full_name)) {
734 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));
736 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
743 case SIM_EF_OPLMN_ACT:
744 case SIM_EF_CPHS_CPHS_INFO:
745 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
746 case SIM_EF_CPHS_VOICE_MSG_WAITING:
747 case SIM_EF_CPHS_DYNAMICFLAGS:
748 case SIM_EF_CPHS_DYNAMIC2FLAG:
749 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
750 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
751 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
755 dbg("File id not handled [0x%x]", file_meta->file_id);
760 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
762 struct tnoti_sim_status noti_data = {0, };
764 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
765 tcore_sim_set_status(o, sim_status);
766 noti_data.sim_status = sim_status;
767 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
768 sizeof(struct tnoti_sim_status), ¬i_data);
771 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
773 const TcoreATResponse *resp = data;
774 UserRequest *ur = NULL;
775 CoreObject *co_sim = NULL;
776 struct s_sim_property *sp = NULL;
777 GSList *tokens = NULL;
778 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
782 dbg(" Function entry ");
784 co_sim = tcore_pending_ref_core_object(p);
785 sp = tcore_sim_ref_userdata(co_sim);
786 ur = tcore_pending_ref_user_request(p);
788 if (resp->success > 0) {
791 line = (const char *) resp->lines->data;
792 tokens = tcore_at_tok_new(line);
793 if (g_slist_length(tokens) != 1) {
794 msg("invalid message");
795 tcore_at_tok_free(tokens);
799 state = atoi(g_slist_nth_data(tokens, 0));
800 dbg("SIM Type is %d", state);
803 sim_type = SIM_TYPE_GSM;
804 } else if (state == 1) {
805 sim_type = SIM_TYPE_USIM;
807 sim_type = SIM_TYPE_UNKNOWN;
811 sim_type = SIM_TYPE_UNKNOWN;
814 tcore_sim_set_type(co_sim, sim_type);
815 _sim_status_update(co_sim, sp->first_recv_status);
816 tcore_at_tok_free(tokens);
817 dbg(" Function exit");
820 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
822 const TcoreATResponse *resp = data;
823 UserRequest *ur = NULL;
824 CoreObject *co_sim = NULL;
825 struct s_sim_property *file_meta = NULL;
826 GSList *tokens = NULL;
827 enum tel_sim_access_result rt;
828 const char *line = NULL;
832 dbg(" Function entry ");
834 co_sim = tcore_pending_ref_core_object(p);
835 ur = tcore_pending_ref_user_request(p);
836 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
838 if (resp->success > 0) {
841 line = (const char *) resp->lines->data;
842 tokens = tcore_at_tok_new(line);
843 if (g_slist_length(tokens) < 2) {
844 err("invalid message");
845 tcore_at_tok_free(tokens);
849 sw1 = atoi(g_slist_nth_data(tokens, 0));
850 sw2 = atoi(g_slist_nth_data(tokens, 1));
852 /*1. SIM access success case*/
853 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
854 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
855 unsigned short record_len = 0;
856 char num_of_records = 0;
857 unsigned char file_id_len = 0;
858 unsigned short file_id = 0;
859 unsigned short file_size = 0;
860 unsigned short file_type = 0;
861 unsigned short arr_file_id = 0;
862 int arr_file_id_rec_num = 0;
864 /* handling only last 3 bits */
865 unsigned char file_type_tag = 0x07;
866 unsigned char *ptr_data;
870 char *recordData = NULL;
871 hexData = g_slist_nth_data(tokens, 2);
872 dbg("hexData: %s", hexData);
873 dbg("hexData: %s", hexData + 1);
875 tmp = util_removeQuotes(hexData);
876 recordData = util_hexStringToBytes(tmp);
877 util_hex_dump(" ", strlen(hexData) / 2, recordData);
880 ptr_data = (unsigned char *) recordData;
881 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
883 ETSI TS 102 221 v7.9.0
885 '62' FCP template tag
887 '82' M File Descriptor
888 '83' M File Identifier
889 'A5' O Proprietary information
890 '8A' M Life Cycle Status Integer
891 '8B', '8C' or 'AB' C1 Security attributes
893 '81' O Total file size
894 '88' O Short File Identifier (SFI)
897 /* rsim.res_len has complete data length received */
899 /* FCP template tag - File Control Parameters tag*/
900 if (*ptr_data == 0x62) {
901 /* parse complete FCP tag*/
902 /* increment to next byte */
904 tag_len = *ptr_data++;
905 dbg("tag_len: %02x", tag_len);
906 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
907 if (*ptr_data == 0x82) {
908 /* increment to next byte */
912 /* unsigned char file_desc_len = *ptr_data++;*/
913 /* dbg("file descriptor length: [%d]", file_desc_len);*/
914 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
915 /* consider only last 3 bits*/
916 dbg("file_type_tag: %02x", file_type_tag);
917 file_type_tag = file_type_tag & (*ptr_data);
918 dbg("file_type_tag: %02x", file_type_tag);
920 switch (file_type_tag) {
921 /* increment to next byte */
924 dbg("Getting FileType: [Transparent file type]");
925 file_type = SIM_FTYPE_TRANSPARENT;
927 /* increment to next byte */
929 /* increment to next byte */
934 dbg("Getting FileType: [Linear fixed file type]");
935 /* increment to next byte */
937 /* data coding byte - value 21 */
940 memcpy(&record_len, ptr_data, 2);
942 SWAPBYTES16(record_len);
943 ptr_data = ptr_data + 2;
944 num_of_records = *ptr_data++;
945 /* Data lossy conversation from enum (int) to unsigned char */
946 file_type = SIM_FTYPE_LINEAR_FIXED;
950 dbg(" Cyclic fixed file type");
951 /* increment to next byte */
953 /* data coding byte - value 21 */
956 memcpy(&record_len, ptr_data, 2);
958 SWAPBYTES16(record_len);
959 ptr_data = ptr_data + 2;
960 num_of_records = *ptr_data++;
961 file_type = SIM_FTYPE_CYCLIC;
965 dbg("not handled file type [0x%x]", *ptr_data);
969 dbg("INVALID FCP received - DEbug!");
973 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
974 if (*ptr_data == 0x83) {
975 /* increment to next byte */
977 file_id_len = *ptr_data++;
978 dbg("file_id_len: %02x", file_id_len);
980 memcpy(&file_id, ptr_data, file_id_len);
981 dbg("file_id: %x", file_id);
984 SWAPBYTES16(file_id);
985 dbg("file_id: %x", file_id);
987 ptr_data = ptr_data + 2;
988 dbg("Getting FileID=[0x%x]", file_id);
990 dbg("INVALID FCP received - DEbug!");
995 /* proprietary information */
996 if (*ptr_data == 0xA5) {
997 unsigned short prop_len;
998 /* increment to next byte */
1002 prop_len = *ptr_data;
1003 dbg("prop_len: %02x", prop_len);
1006 ptr_data = ptr_data + prop_len + 1;
1008 dbg("INVALID FCP received - DEbug!");
1011 /* life cycle status integer [8A][length:0x01][status]*/
1014 00000000 : No information given
1015 00000001 : creation state
1016 00000011 : initialization state
1017 000001-1 : operation state -activated
1018 000001-0 : operation state -deactivated
1019 000011-- : Termination state
1020 b8~b5 !=0, b4~b1=X : Proprietary
1021 Any other value : RFU
1023 if (*ptr_data == 0x8A) {
1024 /* increment to next byte */
1026 /* length - value 1 */
1029 switch (*ptr_data) {
1032 dbg("<RX> operation state -deactivated");
1038 dbg("<RX> operation state -activated");
1043 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1049 /* related to security attributes : currently not handled*/
1050 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1051 /* increment to next byte */
1053 /* if tag length is 3 */
1054 if (*ptr_data == 0x03) {
1055 /* increment to next byte */
1058 memcpy(&arr_file_id, ptr_data, 2);
1060 SWAPBYTES16(arr_file_id);
1061 ptr_data = ptr_data + 2;
1062 arr_file_id_rec_num = *ptr_data++;
1064 /* if tag length is not 3 */
1065 /* ignoring bytes */
1066 // ptr_data = ptr_data + 4;
1067 dbg("Useless security attributes, so jump to next tag");
1068 ptr_data = ptr_data + (*ptr_data + 1);
1071 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1076 dbg("Current ptr_data value is [%x]", *ptr_data);
1078 /* file size excluding structural info*/
1079 if (*ptr_data == 0x80) {
1080 /* for EF file size is body of file and for Linear or cyclic it is
1081 * number of recXsizeof(one record)
1083 /* increment to next byte */
1085 /* length is 1 byte - value is 2 bytes or more */
1087 memcpy(&file_size, ptr_data, 2);
1089 SWAPBYTES16(file_size);
1090 ptr_data = ptr_data + 2;
1092 dbg("INVALID FCP received - DEbug!");
1097 /* total file size including structural info*/
1098 if (*ptr_data == 0x81) {
1100 /* increment to next byte */
1105 ptr_data = ptr_data + 3;
1107 dbg("INVALID FCP received - DEbug!");
1108 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1111 /*short file identifier ignored*/
1112 if (*ptr_data == 0x88) {
1113 dbg("0x88: Do Nothing");
1117 dbg("INVALID FCP received - DEbug!");
1121 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1122 unsigned char gsm_specific_file_data_len = 0;
1123 /* ignore RFU byte1 and byte2 */
1127 // file_size = p_info->response_len;
1128 memcpy(&file_size, ptr_data, 2);
1130 SWAPBYTES16(file_size);
1131 /* parsed file size */
1132 ptr_data = ptr_data + 2;
1134 memcpy(&file_id, ptr_data, 2);
1135 SWAPBYTES16(file_id);
1136 dbg(" FILE id --> [%x]", file_id);
1137 ptr_data = ptr_data + 2;
1138 /* save file type - transparent, linear fixed or cyclic */
1139 file_type_tag = (*(ptr_data + 7));
1141 switch (*ptr_data) {
1144 dbg(" RFU file type- not handled - Debug!");
1149 dbg(" MF file type - not handled - Debug!");
1154 dbg(" DF file type - not handled - Debug!");
1159 dbg(" EF file type [%d] ", file_type_tag);
1160 /* increment to next byte */
1163 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1164 /* increament to next byte as this byte is RFU */
1167 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1169 /* increment to next byte */
1171 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1172 /* the INCREASE command is allowed on the selected cyclic file. */
1173 file_type = SIM_FTYPE_CYCLIC;
1175 /* bytes 9 to 11 give SIM file access conditions */
1177 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1179 /* byte 11 is invalidate and rehabilate nibbles */
1181 /* byte 12 - file status */
1183 /* byte 13 - GSM specific data */
1184 gsm_specific_file_data_len = *ptr_data;
1186 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1188 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1189 record_len = *ptr_data;
1190 dbg("record length[%d], file size[%d]", record_len, file_size);
1192 if (record_len != 0)
1193 num_of_records = (file_size / record_len);
1195 dbg("Number of records [%d]", num_of_records);
1199 dbg(" not handled file type");
1203 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1206 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1207 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1209 file_meta->file_type = file_type;
1210 file_meta->data_size = file_size;
1211 file_meta->rec_length = record_len;
1212 file_meta->rec_count = num_of_records;
1213 file_meta->current_index = 0; // reset for new record type EF
1214 rt = SIM_ACCESS_SUCCESS;
1217 /*2. SIM access fail case*/
1218 dbg("error to get ef[0x%x]", file_meta->file_id);
1219 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1220 rt = _decode_status_word(sw1, sw2);
1222 ur = tcore_user_request_ref(ur);
1224 dbg("Calling _next_from_get_file_info");
1225 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1226 tcore_at_tok_free(tokens);
1228 dbg("RESPONSE NOK");
1229 dbg("error to get ef[0x%x]", file_meta->file_id);
1230 dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1231 rt = SIM_ACCESS_FAILED;
1233 ur = tcore_user_request_ref(ur);
1234 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1236 dbg(" Function exit");
1239 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1241 const TcoreATResponse *resp = data;
1242 UserRequest *ur = NULL;
1243 CoreObject *co_sim = NULL;
1244 struct s_sim_property *file_meta = NULL;
1245 GSList *tokens = NULL;
1246 enum tel_sim_access_result rt;
1247 struct tel_sim_imsi imsi;
1248 struct tel_sim_ecc ecc;
1249 struct tel_sim_msisdn msisdn;
1250 struct tel_sim_opl opl;
1251 struct tel_sim_pnn pnn;
1252 gboolean dr = FALSE;
1253 const char *line = NULL;
1260 dbg(" Function entry ");
1262 co_sim = tcore_pending_ref_core_object(p);
1263 ur = tcore_pending_ref_user_request(p);
1264 file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
1266 if (resp->success > 0) {
1269 line = (const char *) resp->lines->data;
1270 tokens = tcore_at_tok_new(line);
1271 if (g_slist_length(tokens) != 3) {
1272 msg("invalid message");
1273 tcore_at_tok_free(tokens);
1277 sw1 = atoi(g_slist_nth_data(tokens, 0));
1278 sw2 = atoi(g_slist_nth_data(tokens, 1));
1279 res = g_slist_nth_data(tokens, 2);
1281 tmp = util_removeQuotes(res);
1282 res = util_hexStringToBytes(tmp);
1283 res_len = strlen((const char *) res);
1284 dbg("res: %s res_len: %d", res, res_len);
1286 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1287 rt = SIM_ACCESS_SUCCESS;
1288 file_meta->files.result = rt;
1289 dbg("file_meta->file_id : %x", file_meta->file_id);
1291 switch (file_meta->file_id) {
1294 dbg("res: %s", res);
1295 dr = tcore_sim_decode_imsi(&imsi, (unsigned char *) res, res_len);
1297 dbg("imsi decoding failed");
1299 _sim_check_identity(co_sim, &imsi);
1300 tcore_sim_set_imsi(co_sim, &imsi);
1306 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
1309 case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
1310 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1311 case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
1312 case SIM_EF_LP: /* 1 byte encoding*/
1313 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1314 /*2G LP(0x6F05) has 1 byte for each language*/
1315 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
1317 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1318 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
1323 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
1327 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
1331 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1332 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
1333 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
1334 dbg("decode w/ index [%d]", file_meta->current_index);
1335 memset(&ecc, 0x00, sizeof(struct tel_sim_ecc));
1336 dr = tcore_sim_decode_uecc(&ecc, (unsigned char *) res, res_len);
1338 memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], &ecc, sizeof(struct tel_sim_ecc));
1339 file_meta->files.data.ecc.ecc_count++;
1342 dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
1347 dbg("decode w/ index [%d]", file_meta->current_index);
1348 memset(&msisdn, 0x00, sizeof(struct tel_sim_msisdn));
1349 dr = tcore_sim_decode_msisdn(&msisdn, (unsigned char *) res, res_len);
1351 memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], &msisdn, sizeof(struct tel_sim_msisdn));
1352 file_meta->files.data.msisdn_list.count++;
1357 dbg("decode w/ index [%d]", file_meta->current_index);
1358 memset(&opl, 0x00, sizeof(struct tel_sim_opl));
1359 dr = tcore_sim_decode_opl(&opl, (unsigned char *) res, res_len);
1361 memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], &opl, sizeof(struct tel_sim_opl));
1362 file_meta->files.data.opl.opl_count++;
1367 dbg("decode w/ index [%d]", file_meta->current_index);
1368 memset(&pnn, 0x00, sizeof(struct tel_sim_pnn));
1369 dr = tcore_sim_decode_pnn(&pnn, (unsigned char *) res, res_len);
1371 memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], &opl, sizeof(struct tel_sim_pnn));
1372 file_meta->files.data.pnn.pnn_count++;
1376 case SIM_EF_OPLMN_ACT:
1377 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
1380 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1381 dr = tcore_sim_decode_cff(&file_meta->files.data.cf, (unsigned char *) res, res_len);
1384 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1385 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.mw_data_u.cphs_mw, (unsigned char *) res, res_len);
1388 case SIM_EF_USIM_MWIS:
1389 dr = tcore_sim_decode_mwis(&file_meta->files.data.mw.mw_data_u.mw, (unsigned char *) res, res_len);
1392 case SIM_EF_USIM_CFIS:
1393 dr = tcore_sim_decode_cfis(&file_meta->files.data.cf, (unsigned char *) res, res_len);
1396 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1397 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1400 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1401 dr = tcore_sim_decode_ons((unsigned char *) &file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
1402 dbg(" file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]", file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1405 case SIM_EF_CPHS_CPHS_INFO:
1406 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
1409 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1410 dr = tcore_sim_decode_short_ons((unsigned char *) &file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
1414 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1419 rt = _decode_status_word(sw1, sw2);
1420 file_meta->files.result = rt;
1423 tcore_at_tok_free(tokens);
1425 dbg("RESPONSE NOK");
1426 dbg("error to get ef[0x%x]", file_meta->file_id);
1427 rt = SIM_ACCESS_FAILED;
1429 ur = tcore_user_request_ref(ur);
1431 dbg("Calling _next_from_get_file_data");
1432 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1433 dbg(" Function exit");
1436 static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
1438 const TcoreATResponse *resp = data;
1439 UserRequest *ur = NULL;
1440 CoreObject *co_sim = NULL;
1441 struct s_sim_property *sp = NULL;
1442 GSList *tokens = NULL;
1443 const char *line = NULL;
1444 struct tresp_sim_verify_pins v_pin = {0, };
1445 struct tresp_sim_verify_puks v_puk = {0, };
1446 struct tresp_sim_change_pins change_pin = {0, };
1447 struct tresp_sim_disable_facility dis_facility = {0, };
1448 struct tresp_sim_enable_facility en_facility = {0, };
1450 int attempts_left = 0;
1451 int time_penalty = 0;
1453 dbg(" Function entry ");
1455 co_sim = tcore_pending_ref_core_object(p);
1456 sp = tcore_sim_ref_userdata(co_sim);
1457 ur = tcore_pending_ref_user_request(p);
1459 if (resp->success > 0) {
1462 line = (const char *) resp->lines->data;
1463 tokens = tcore_at_tok_new(line);
1464 if (g_slist_length(tokens) < 3) {
1465 msg("invalid message");
1466 tcore_at_tok_free(tokens);
1470 lock_type = atoi(g_slist_nth_data(tokens, 0));
1471 attempts_left = atoi(g_slist_nth_data(tokens, 1));
1472 time_penalty = atoi(g_slist_nth_data(tokens, 2));
1474 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
1475 lock_type, attempts_left, time_penalty);
1477 switch (sp->current_sec_op) {
1478 case SEC_PIN1_VERIFY:
1479 case SEC_PIN2_VERIFY:
1480 case SEC_SIM_VERIFY:
1481 case SEC_ADM_VERIFY:
1482 v_pin.result = SIM_INCORRECT_PASSWORD;
1483 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1484 v_pin.retry_count = attempts_left;
1485 tcore_user_request_send_response(ur, _find_resp_command(ur),
1486 sizeof(struct tresp_sim_verify_pins), &v_pin);
1489 case SEC_PUK1_VERIFY:
1490 case SEC_PUK2_VERIFY:
1491 v_puk.result = SIM_INCORRECT_PASSWORD;
1492 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1493 v_puk.retry_count = attempts_left;
1494 tcore_user_request_send_response(ur, _find_resp_command(ur),
1495 sizeof(struct tresp_sim_verify_puks), &v_puk);
1498 case SEC_PIN1_CHANGE:
1499 case SEC_PIN2_CHANGE:
1500 change_pin.result = SIM_INCORRECT_PASSWORD;
1501 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1502 change_pin.retry_count = attempts_left;
1503 tcore_user_request_send_response(ur, _find_resp_command(ur),
1504 sizeof(struct tresp_sim_change_pins), &change_pin);
1507 case SEC_PIN1_DISABLE:
1508 case SEC_PIN2_DISABLE:
1509 case SEC_FDN_DISABLE:
1510 case SEC_SIM_DISABLE:
1511 case SEC_NET_DISABLE:
1512 case SEC_NS_DISABLE:
1513 case SEC_SP_DISABLE:
1514 case SEC_CP_DISABLE:
1515 dis_facility.result = SIM_INCORRECT_PASSWORD;
1516 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1517 dis_facility.retry_count = attempts_left;
1518 tcore_user_request_send_response(ur, _find_resp_command(ur),
1519 sizeof(struct tresp_sim_disable_facility), &dis_facility);
1522 case SEC_PIN1_ENABLE:
1523 case SEC_PIN2_ENABLE:
1524 case SEC_FDN_ENABLE:
1525 case SEC_SIM_ENABLE:
1526 case SEC_NET_ENABLE:
1530 en_facility.result = SIM_INCORRECT_PASSWORD;
1531 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
1532 en_facility.retry_count = attempts_left;
1533 tcore_user_request_send_response(ur, _find_resp_command(ur),
1534 sizeof(struct tresp_sim_enable_facility), &en_facility);
1538 dbg("not handled sec op[%d]", sp->current_sec_op);
1541 tcore_at_tok_free(tokens);
1543 dbg(" Function exit");
1546 static gboolean _get_sim_type(CoreObject *o)
1548 TcoreHal *hal = NULL;
1549 TcoreATRequest *req = NULL;
1550 TcorePending *pending = NULL;
1551 UserRequest *ur = NULL;
1552 char *cmd_str = NULL;
1554 dbg(" Function entry ");
1556 hal = tcore_object_get_hal(o);
1557 pending = tcore_pending_new(o, 0);
1559 cmd_str = g_strdup_printf("AT+XUICC?");
1560 req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
1562 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1564 tcore_pending_set_request_data(pending, 0, req);
1565 tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
1566 tcore_pending_link_user_request(pending, ur);
1567 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1568 tcore_hal_send_request(hal, pending);
1571 dbg(" Function exit");
1575 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1577 TcoreHal *hal = NULL;
1578 TcorePending *pending = NULL;
1579 struct s_sim_property file_meta = {0, };
1580 char *cmd_str = NULL;
1583 dbg(" Function entry ");
1585 file_meta.file_id = ef;
1586 dbg("file_meta.file_id: %d", file_meta.file_id);
1587 hal = tcore_object_get_hal(o);
1588 dbg("hal: %x", hal);
1589 pending = tcore_pending_new(o, 0);
1591 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1592 dbg("trt[%d]", trt);
1593 cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
1594 dbg("cmd_str: %x", cmd_str);
1596 pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
1597 tcore_pending_link_user_request(pending, ur);
1598 tcore_hal_send_request(hal, pending);
1601 dbg(" Function exit");
1602 return TCORE_RETURN_SUCCESS;
1605 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1607 TcoreHal *hal = NULL;
1608 TcoreATRequest *req = NULL;
1609 TcorePending *pending = NULL;
1610 char *cmd_str = NULL;
1615 dbg(" Function entry ");
1616 hal = tcore_object_get_hal(o);
1617 pending = tcore_pending_new(o, 0);
1619 dbg("file_id: %x", ef);
1621 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1622 p2 = (unsigned char) offset & 0x00FF; // offset low
1623 p3 = (unsigned char) length;
1625 cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
1627 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1629 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1631 tcore_pending_set_request_data(pending, 0, req);
1632 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1633 tcore_pending_link_user_request(pending, ur);
1634 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1636 tcore_hal_send_request(hal, pending);
1639 dbg(" Function exit");
1643 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1645 TcoreHal *hal = NULL;
1646 TcoreATRequest *req = NULL;
1647 TcorePending *pending = NULL;
1648 char *cmd_str = NULL;
1653 dbg(" Function entry ");
1655 hal = tcore_object_get_hal(o);
1656 pending = tcore_pending_new(o, 0);
1658 p1 = (unsigned char) index;
1659 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1660 p3 = (unsigned char) length;
1662 cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
1664 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
1666 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1668 tcore_pending_set_request_data(pending, 0, req);
1669 tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
1670 tcore_pending_link_user_request(pending, ur);
1671 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1673 tcore_hal_send_request(hal, pending);
1676 dbg(" Function exit");
1680 static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
1682 TcoreHal *hal = NULL;
1683 TcoreATRequest *req = NULL;
1684 TcorePending *pending = NULL;
1685 char *cmd_str = NULL;
1687 struct s_sim_property *sp = NULL;
1688 const struct treq_sim_get_lock_info *req_data = NULL;
1690 dbg(" Function entry ");
1692 hal = tcore_object_get_hal(o);
1693 pending = tcore_pending_new(o, 0);
1694 req_data = tcore_user_request_ref_data(ur, NULL);
1695 sp = tcore_sim_ref_userdata(o);
1697 switch (sp->current_sec_op) {
1698 case SEC_PIN1_VERIFY:
1699 case SEC_PIN1_CHANGE:
1700 case SEC_PIN1_ENABLE:
1701 case SEC_PIN1_DISABLE:
1705 case SEC_PIN2_VERIFY:
1706 case SEC_PIN2_CHANGE:
1707 case SEC_PIN2_ENABLE:
1708 case SEC_PIN2_DISABLE:
1709 case SEC_FDN_ENABLE:
1710 case SEC_FDN_DISABLE:
1714 case SEC_PUK1_VERIFY:
1718 case SEC_PUK2_VERIFY:
1722 case SEC_NET_ENABLE:
1723 case SEC_NET_DISABLE:
1728 case SEC_NS_DISABLE:
1733 case SEC_SP_DISABLE:
1738 case SEC_CP_DISABLE:
1742 case SEC_ADM_VERIFY:
1750 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
1751 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
1752 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1754 tcore_pending_set_request_data(pending, 0, req);
1755 tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
1756 tcore_pending_link_user_request(pending, ur);
1757 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1758 tcore_hal_send_request(hal, pending);
1761 dbg(" Function exit");
1762 return TCORE_RETURN_SUCCESS;
1766 static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
1768 struct s_sim_property *sp = NULL;
1770 GSList *tokens = NULL;
1771 GSList *lines = NULL;
1773 dbg("Function entry");
1776 sp = tcore_sim_ref_userdata(o);
1777 lines = (GSList *) event_info;
1778 if (1 != g_slist_length(lines)) {
1779 dbg("unsolicited msg but multiple line");
1782 line = (char *) (lines->data);
1783 tokens = tcore_at_tok_new(line);
1784 if (g_slist_length(tokens) != 1) {
1785 msg("invalid message");
1786 tcore_at_tok_free(tokens);
1791 dbg(" Function exit");
1793 tcore_at_tok_free(tokens);
1798 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1800 UserRequest *ur = NULL;
1801 struct s_sim_property *sp = NULL;
1802 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1803 GSList *tokens = NULL;
1804 GSList *lines = NULL;
1805 const char *line = NULL;
1808 dbg(" Function entry ");
1810 sp = tcore_sim_ref_userdata(o);
1812 lines = (GSList *) event_info;
1813 if (1 != g_slist_length(lines)) {
1814 dbg("unsolicited msg but multiple line");
1817 line = (char *) (lines->data);
1819 tokens = tcore_at_tok_new(line);
1820 if (g_slist_length(tokens) != 1) {
1821 msg("invalid message");
1822 tcore_at_tok_free(tokens);
1825 sim_state = atoi(g_slist_nth_data(tokens, 0));
1827 switch (sim_state) {
1828 case 0: // sim state = SIM not present
1829 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1833 case 1: // sim state = PIN verification needed
1834 sim_status = SIM_STATUS_PIN_REQUIRED;
1835 dbg(" PIN required");
1838 case 2: // sim state = PIN verification not needed \96 Ready
1839 case 3: // sim state = PIN verified \96 Ready
1840 sim_status = SIM_STATUS_INITIALIZING;
1841 dbg(" Inside PIN disabled at BOOT UP");
1844 case 4: // sim state = PUK verification needed
1845 sim_status = SIM_STATUS_PUK_REQUIRED;
1846 dbg(" PUK required");
1849 case 5: // sim state = SIM permanently blocked
1850 sim_status = SIM_STATUS_CARD_BLOCKED;
1851 dbg(" Card permanently blocked");
1854 case 6: // sim state = SIM error
1855 sim_status = SIM_STATUS_CARD_ERROR;
1856 dbg("SIM card error ");
1859 case 7: // sim state = ready for attach (+COPS)
1860 sim_status = SIM_STATUS_INIT_COMPLETED;
1861 dbg("Modem init completed");
1864 case 8: // sim state = SIM Technical Problem
1865 sim_status = SIM_STATUS_CARD_ERROR;
1866 dbg("SIM unavailable");
1869 case 9: // sim state = SIM removed
1870 sim_status = SIM_STATUS_CARD_REMOVED;
1874 case 99: // sim state = SIM State Unknown
1875 sim_status = SIM_STATUS_UNKNOWN;
1876 dbg("SIM State Unknown");
1880 dbg("SIM Status : %d", sim_status);
1884 dbg(" not handled SEC lock type ");
1888 switch (sim_status) {
1889 case SIM_STATUS_INIT_COMPLETED:
1890 ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
1891 _get_file_info(o, ur, SIM_EF_IMSI);
1894 case SIM_STATUS_INITIALIZING:
1895 case SIM_STATUS_PIN_REQUIRED:
1896 case SIM_STATUS_PUK_REQUIRED:
1897 case SIM_STATUS_CARD_BLOCKED:
1898 case SIM_STATUS_NCK_REQUIRED:
1899 case SIM_STATUS_NSCK_REQUIRED:
1900 case SIM_STATUS_SPCK_REQUIRED:
1901 case SIM_STATUS_CCK_REQUIRED:
1902 case SIM_STATUS_LOCK_REQUIRED:
1903 if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
1904 dbg("first received sim status[%d]", sim_status);
1905 sp->first_recv_status = sim_status;
1908 dbg("second or later received lock status[%d]", sim_status);
1909 if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
1910 dbg("sim is not init complete in telephony side yet");
1911 _sim_status_update(o, sim_status);
1916 case SIM_STATUS_CARD_REMOVED:
1917 case SIM_STATUS_CARD_NOT_PRESENT:
1918 case SIM_STATUS_CARD_ERROR:
1919 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
1920 dbg("[SIM]SIM CARD REMOVED!!");
1921 sim_status = SIM_STATUS_CARD_REMOVED;
1923 _sim_status_update(o, sim_status);
1927 dbg("not handled status[%d]", sim_status);
1932 dbg(" Function exit");
1934 tcore_at_tok_free(tokens);
1940 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
1942 const TcoreATResponse *resp = data;
1943 UserRequest *ur = NULL;
1944 CoreObject *co_sim = NULL;
1945 struct s_sim_property *sp = NULL;
1946 GSList *tokens = NULL;
1947 struct tresp_sim_verify_pins res;
1948 GQueue *queue = NULL;
1952 dbg(" Function entry ");
1954 co_sim = tcore_pending_ref_core_object(p);
1955 sp = tcore_sim_ref_userdata(co_sim);
1956 ur = tcore_pending_ref_user_request(p);
1958 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
1960 if (resp->success > 0) {
1962 res.result = SIM_PIN_OPERATION_SUCCESS;
1963 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
1964 if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
1965 if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
1966 _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
1968 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &res);
1970 dbg("RESPONSE NOK");
1971 line = (const char *) resp->final_response;
1972 tokens = tcore_at_tok_new(line);
1973 if (g_slist_length(tokens) < 1) {
1974 dbg("err cause not specified or string corrupted");
1975 res.result = TCORE_RETURN_3GPP_ERROR;
1977 err = atoi(g_slist_nth_data(tokens, 0));
1978 dbg("on_response_verify_pins: err = %d", err);
1979 queue = tcore_object_ref_user_data(co_sim);
1980 ur = tcore_user_request_ref(ur);
1981 _get_retry_count(co_sim, ur);
1983 tcore_at_tok_free(tokens);
1985 dbg(" Function exit");
1988 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
1990 const TcoreATResponse *resp = data;
1991 UserRequest *ur = NULL;
1992 CoreObject *co_sim = NULL;
1993 struct s_sim_property *sp = NULL;
1994 GSList *tokens = NULL;
1995 struct tresp_sim_verify_puks res;
1996 GQueue *queue = NULL;
2000 dbg(" Function entry ");
2002 co_sim = tcore_pending_ref_core_object(p);
2003 sp = tcore_sim_ref_userdata(co_sim);
2004 ur = tcore_pending_ref_user_request(p);
2006 memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
2008 if (resp->success > 0) {
2010 res.result = SIM_PIN_OPERATION_SUCCESS;
2011 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2012 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PUKS, sizeof(struct tresp_sim_verify_pins), &res);
2014 dbg("RESPONSE NOK");
2015 line = (const char *) resp->final_response;
2016 tokens = tcore_at_tok_new(line);
2018 if (g_slist_length(tokens) < 1) {
2019 dbg("err cause not specified or string corrupted");
2020 res.result = TCORE_RETURN_3GPP_ERROR;
2022 err = atoi(g_slist_nth_data(tokens, 0));
2023 queue = tcore_object_ref_user_data(co_sim);
2024 ur = tcore_user_request_ref(ur);
2025 _get_retry_count(co_sim, ur);
2027 tcore_at_tok_free(tokens);
2029 dbg(" Function exit");
2032 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2034 const TcoreATResponse *resp = data;
2035 UserRequest *ur = NULL;
2036 CoreObject *co_sim = NULL;
2037 struct s_sim_property *sp = NULL;
2038 GSList *tokens = NULL;
2039 struct tresp_sim_change_pins res;
2044 dbg(" Function entry ");
2046 co_sim = tcore_pending_ref_core_object(p);
2047 sp = tcore_sim_ref_userdata(co_sim);
2048 ur = tcore_pending_ref_user_request(p);
2050 memset(&res, 0, sizeof(struct tresp_sim_change_pins));
2052 if (resp->success > 0) {
2054 res.result = SIM_PIN_OPERATION_SUCCESS;
2055 res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2056 tcore_user_request_send_response(ur, TRESP_SIM_CHANGE_PINS, sizeof(struct tresp_sim_change_pins), &res);
2058 dbg("RESPONSE NOK");
2059 line = (const char *) resp->final_response;
2060 tokens = tcore_at_tok_new(line);
2062 if (g_slist_length(tokens) < 1) {
2063 dbg("err cause not specified or string corrupted");
2064 res.result = TCORE_RETURN_3GPP_ERROR;
2066 err = atoi(g_slist_nth_data(tokens, 0));
2067 queue = tcore_object_ref_user_data(co_sim);
2068 ur = tcore_user_request_ref(ur);
2069 _get_retry_count(co_sim, ur);
2071 tcore_at_tok_free(tokens);
2073 dbg(" Function exit");
2076 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2078 const TcoreATResponse *resp = data;
2079 UserRequest *ur = NULL;
2080 CoreObject *co_sim = NULL;
2081 struct s_sim_property *sp = NULL;
2082 GSList *tokens = NULL;
2083 struct tresp_sim_get_facility_status res;
2086 dbg(" Function entry ");
2088 co_sim = tcore_pending_ref_core_object(p);
2089 sp = tcore_sim_ref_userdata(co_sim);
2090 ur = tcore_pending_ref_user_request(p);
2092 memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
2094 res.result = SIM_PIN_OPERATION_SUCCESS;
2095 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2097 if (resp->success > 0) {
2100 line = (const char *) resp->lines->data;
2101 tokens = tcore_at_tok_new(line);
2102 if (g_slist_length(tokens) != 1) {
2103 msg("invalid message");
2104 tcore_at_tok_free(tokens);
2108 res.b_enable = atoi(g_slist_nth_data(tokens, 0));
2110 dbg("RESPONSE NOK");
2111 res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2115 tcore_user_request_send_response(ur, TRESP_SIM_GET_FACILITY_STATUS,
2116 sizeof(struct tresp_sim_get_facility_status), &res);
2118 tcore_at_tok_free(tokens);
2119 dbg(" Function exit");
2122 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2124 const TcoreATResponse *resp = data;
2125 UserRequest *ur = NULL;
2126 CoreObject *co_sim = NULL;
2127 struct s_sim_property *sp = NULL;
2128 GSList *tokens = NULL;
2129 struct tresp_sim_enable_facility res;
2133 dbg(" Function entry ");
2135 co_sim = tcore_pending_ref_core_object(p);
2136 sp = tcore_sim_ref_userdata(co_sim);
2137 ur = tcore_pending_ref_user_request(p);
2139 memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
2141 res.result = SIM_PIN_OPERATION_SUCCESS;
2142 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2144 if (resp->success > 0) {
2147 line = (const char *) resp->lines->data;
2148 tokens = tcore_at_tok_new(line);
2149 if (g_slist_length(tokens) != 1) {
2150 msg("invalid message");
2151 tcore_at_tok_free(tokens);
2155 res.result = SIM_PIN_OPERATION_SUCCESS;
2157 tcore_user_request_send_response(ur, TRESP_SIM_ENABLE_FACILITY,
2158 sizeof(struct tresp_sim_enable_facility), &res);
2160 tcore_at_tok_free(tokens);
2162 dbg("RESPONSE NOK");
2163 queue = tcore_object_ref_user_data(co_sim);
2164 ur = tcore_user_request_ref(ur);
2165 _get_retry_count(co_sim, ur);
2167 dbg(" Function exit");
2170 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2172 const TcoreATResponse *resp = data;
2173 UserRequest *ur = NULL;
2174 CoreObject *co_sim = NULL;
2175 struct s_sim_property *sp = NULL;
2176 GSList *tokens = NULL;
2177 struct tresp_sim_disable_facility res;
2181 dbg(" Function entry ");
2183 co_sim = tcore_pending_ref_core_object(p);
2184 sp = tcore_sim_ref_userdata(co_sim);
2185 ur = tcore_pending_ref_user_request(p);
2187 memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
2189 res.result = SIM_PIN_OPERATION_SUCCESS;
2190 res.type = _sim_get_current_pin_facility(sp->current_sec_op);
2192 if (resp->success > 0) {
2195 line = (const char *) resp->lines->data;
2196 tokens = tcore_at_tok_new(line);
2197 if (g_slist_length(tokens) != 1) {
2198 msg("invalid message");
2199 tcore_at_tok_free(tokens);
2203 res.result = SIM_PIN_OPERATION_SUCCESS;
2205 tcore_user_request_send_response(ur, TRESP_SIM_DISABLE_FACILITY,
2206 sizeof(struct tresp_sim_disable_facility), &res);
2208 tcore_at_tok_free(tokens);
2210 dbg("RESPONSE NOK");
2211 queue = tcore_object_ref_user_data(co_sim);
2212 ur = tcore_user_request_ref(ur);
2213 _get_retry_count(co_sim, ur);
2215 dbg(" Function exit");
2218 static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
2220 const TcoreATResponse *resp = data;
2221 UserRequest *ur = NULL;
2222 CoreObject *co_sim = NULL;
2223 struct s_sim_property *sp = NULL;
2224 GSList *tokens = NULL;
2226 struct tresp_sim_verify_pins v_pin = {0, };
2227 struct tresp_sim_verify_puks v_puk = {0, };
2228 struct tresp_sim_change_pins change_pin = {0, };
2229 struct tresp_sim_disable_facility dis_facility = {0, };
2230 struct tresp_sim_enable_facility en_facility = {0, };
2232 int attempts_left = 0;
2233 int time_penalty = 0;
2235 dbg(" Function entry ");
2237 co_sim = tcore_pending_ref_core_object(p);
2238 sp = tcore_sim_ref_userdata(co_sim);
2239 ur = tcore_pending_ref_user_request(p);
2241 if (resp->success > 0) {
2244 line = (const char *) resp->lines->data;
2245 tokens = tcore_at_tok_new(line);
2246 if (g_slist_length(tokens) != 3) {
2247 msg("invalid message");
2248 tcore_at_tok_free(tokens);
2252 lock_type = atoi(g_slist_nth_data(tokens, 0));
2253 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2254 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2256 switch (sp->current_sec_op) {
2257 case SEC_PIN1_VERIFY:
2258 case SEC_PIN2_VERIFY:
2259 case SEC_SIM_VERIFY:
2260 case SEC_ADM_VERIFY:
2261 v_pin.result = SIM_INCORRECT_PASSWORD;
2262 v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2263 v_pin.retry_count = attempts_left;
2264 tcore_user_request_send_response(ur, _find_resp_command(ur),
2265 sizeof(struct tresp_sim_verify_pins), &v_pin);
2268 case SEC_PUK1_VERIFY:
2269 case SEC_PUK2_VERIFY:
2270 v_puk.result = SIM_INCORRECT_PASSWORD;
2271 v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2272 v_puk.retry_count = attempts_left;
2273 tcore_user_request_send_response(ur, _find_resp_command(ur),
2274 sizeof(struct tresp_sim_verify_puks), &v_puk);
2277 case SEC_PIN1_CHANGE:
2278 case SEC_PIN2_CHANGE:
2279 change_pin.result = SIM_INCORRECT_PASSWORD;
2280 change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
2281 change_pin.retry_count = attempts_left;
2282 tcore_user_request_send_response(ur, _find_resp_command(ur),
2283 sizeof(struct tresp_sim_change_pins), &change_pin);
2286 case SEC_PIN1_DISABLE:
2287 case SEC_PIN2_DISABLE:
2288 case SEC_FDN_DISABLE:
2289 case SEC_SIM_DISABLE:
2290 case SEC_NET_DISABLE:
2291 case SEC_NS_DISABLE:
2292 case SEC_SP_DISABLE:
2293 case SEC_CP_DISABLE:
2294 dis_facility.result = SIM_INCORRECT_PASSWORD;
2295 dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2296 dis_facility.retry_count = attempts_left;
2297 tcore_user_request_send_response(ur, _find_resp_command(ur),
2298 sizeof(struct tresp_sim_disable_facility), &dis_facility);
2301 case SEC_PIN1_ENABLE:
2302 case SEC_PIN2_ENABLE:
2303 case SEC_FDN_ENABLE:
2304 case SEC_SIM_ENABLE:
2305 case SEC_NET_ENABLE:
2309 en_facility.result = SIM_INCORRECT_PASSWORD;
2310 en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
2311 en_facility.retry_count = attempts_left;
2312 tcore_user_request_send_response(ur, _find_resp_command(ur),
2313 sizeof(struct tresp_sim_enable_facility), &en_facility);
2317 dbg("not handled sec op[%d]", sp->current_sec_op);
2320 tcore_at_tok_free(tokens);
2322 dbg(" Function exit");
2325 static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
2327 const TcoreATResponse *resp = data;
2328 UserRequest *ur = NULL;
2329 CoreObject *co_sim = NULL;
2330 struct tresp_sim_set_callforwarding resp_cf = {0, };
2331 struct tresp_sim_set_language resp_language = {0, };
2332 struct s_sim_property *sp = NULL;
2333 GSList *tokens = NULL;
2334 enum tel_sim_access_result result;
2339 dbg(" Function entry ");
2341 co_sim = tcore_pending_ref_core_object(p);
2342 ur = tcore_pending_ref_user_request(p);
2343 sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
2345 if (resp->success > 0) {
2348 line = (const char *) resp->lines->data;
2349 tokens = tcore_at_tok_new(line);
2350 if (g_slist_length(tokens) != 2) {
2351 msg("invalid message");
2352 tcore_at_tok_free(tokens);
2356 sw1 = atoi(g_slist_nth_data(tokens, 0));
2357 sw2 = atoi(g_slist_nth_data(tokens, 1));
2359 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
2360 result = SIM_ACCESS_SUCCESS;
2362 result = _decode_status_word(sw1, sw2);
2365 dbg("RESPONSE NOK");
2366 result = SIM_ACCESS_FAILED;
2369 switch (sp->file_id) {
2370 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
2371 case SIM_EF_USIM_CFIS:
2372 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_callforwarding), &resp_cf);
2377 case SIM_EF_USIM_LI:
2378 case SIM_EF_USIM_PL:
2379 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_language), &resp_language);
2383 dbg("Invalid File ID - %d", sp->file_id)
2386 tcore_at_tok_free(tokens);
2387 dbg(" Function exit");
2390 static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
2392 const TcoreATResponse *resp = data;
2393 UserRequest *ur = NULL;
2394 CoreObject *co_sim = NULL;
2395 struct s_sim_property *sp = NULL;
2396 GSList *tokens = NULL;
2397 struct tresp_sim_transmit_apdu res;
2400 dbg(" Function entry ");
2402 co_sim = tcore_pending_ref_core_object(p);
2403 sp = tcore_sim_ref_userdata(co_sim);
2404 ur = tcore_pending_ref_user_request(p);
2406 memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
2408 if (resp->success > 0) {
2410 res.result = SIM_ACCESS_SUCCESS;
2412 line = (const char *) resp->lines->data;
2413 tokens = tcore_at_tok_new(line);
2414 if (g_slist_length(tokens) != 2) {
2415 msg("invalid message");
2416 tcore_at_tok_free(tokens);
2420 res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0));
2421 strncpy((char *) res.apdu_resp, (const char *) g_slist_nth_data(tokens, 1), res.apdu_resp_length);
2423 dbg("RESPONSE NOK");
2424 res.result = SIM_ACCESS_FAILED;
2426 ur = tcore_pending_ref_user_request(p);
2428 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
2430 tcore_at_tok_free(tokens);
2431 dbg(" Function exit");
2434 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2436 TcoreHal *hal = NULL;
2437 TcoreATRequest *req = NULL;
2438 TcorePending *pending = NULL;
2439 char *cmd_str = NULL;
2440 const struct treq_sim_verify_pins *req_data = NULL;
2441 struct s_sim_property *sp = NULL;
2443 dbg(" Function entry ");
2445 hal = tcore_object_get_hal(o);
2446 sp = tcore_sim_ref_userdata(o);
2447 pending = tcore_pending_new(o, 0);
2448 req_data = tcore_user_request_ref_data(ur, NULL);
2451 return TCORE_RETURN_EINVAL;
2453 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2454 sp->current_sec_op = SEC_PIN1_VERIFY;
2455 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2456 } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2457 sp->current_sec_op = SEC_PIN2_VERIFY;
2458 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
2459 } else if (req_data->pin_type == SIM_PTYPE_SIM) {
2460 sp->current_sec_op = SEC_SIM_VERIFY;
2461 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2462 } else if (req_data->pin_type == SIM_PTYPE_ADM) {
2463 sp->current_sec_op = SEC_ADM_VERIFY;
2464 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
2466 return TCORE_RETURN_EINVAL;
2469 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2471 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2473 tcore_pending_set_request_data(pending, 0, req);
2474 tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
2475 tcore_pending_link_user_request(pending, ur);
2476 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2477 tcore_hal_send_request(hal, pending);
2480 dbg(" Function exit");
2481 return TCORE_RETURN_SUCCESS;
2484 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2486 TcoreHal *hal = NULL;
2487 TcoreATRequest *req = NULL;
2488 TcorePending *pending = NULL;
2489 char *cmd_str = NULL;
2490 const struct treq_sim_verify_puks *req_data;
2491 struct s_sim_property *sp = NULL;
2493 dbg(" Function entry ");
2495 hal = tcore_object_get_hal(o);
2496 sp = tcore_sim_ref_userdata(o);
2497 pending = tcore_pending_new(o, 0);
2498 req_data = tcore_user_request_ref_data(ur, NULL);
2501 return TCORE_RETURN_EINVAL;
2503 if (req_data->puk_type == SIM_PTYPE_PUK1) {
2504 sp->current_sec_op = SEC_PUK1_VERIFY;
2505 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2506 } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
2507 sp->current_sec_op = SEC_PUK2_VERIFY;
2508 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
2510 return TCORE_RETURN_EINVAL;
2512 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2514 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2516 tcore_pending_set_request_data(pending, 0, req);
2517 tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
2518 tcore_pending_link_user_request(pending, ur);
2519 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2520 tcore_hal_send_request(hal, pending);
2523 dbg(" Function exit");
2524 return TCORE_RETURN_SUCCESS;
2527 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2529 TcoreHal *hal = NULL;
2530 TcoreATRequest *req = NULL;
2531 TcorePending *pending = NULL;
2532 char *cmd_str = NULL;
2533 const struct treq_sim_change_pins *req_data;
2534 struct s_sim_property *sp = NULL;
2538 dbg(" Function entry ");
2540 hal = tcore_object_get_hal(o);
2541 sp = tcore_sim_ref_userdata(o);
2542 pending = tcore_pending_new(o, 0);
2543 req_data = tcore_user_request_ref_data(ur, NULL);
2546 return TCORE_RETURN_EINVAL;
2548 if (req_data->type == SIM_PTYPE_PIN1) {
2549 sp->current_sec_op = SEC_PIN1_CHANGE;
2550 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
2551 } else if (req_data->type == SIM_PTYPE_PIN2) {
2552 sp->current_sec_op = SEC_PIN2_CHANGE;
2553 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
2555 return TCORE_RETURN_EINVAL;
2557 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2559 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2561 tcore_pending_set_request_data(pending, 0, req);
2562 tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
2563 tcore_pending_link_user_request(pending, ur);
2564 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2565 tcore_hal_send_request(hal, pending);
2568 dbg(" Function exit");
2569 return TCORE_RETURN_SUCCESS;
2572 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2574 TcoreHal *hal = NULL;
2575 TcoreATRequest *req = NULL;
2576 TcorePending *pending = NULL;
2577 char *cmd_str = NULL;
2578 const struct treq_sim_get_facility_status *req_data;
2579 struct s_sim_property *sp = NULL;
2581 int mode = 2; /* 0:unlock, 1:lock, 2:query*/
2583 dbg(" Function entry ");
2585 hal = tcore_object_get_hal(o);
2586 sp = tcore_sim_ref_userdata(o);
2587 pending = tcore_pending_new(o, 0);
2588 req_data = tcore_user_request_ref_data(ur, NULL);
2591 return TCORE_RETURN_EINVAL;
2593 if (req_data->type == SIM_FACILITY_PS) {
2594 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2595 } else if (req_data->type == SIM_FACILITY_SC) {
2596 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2597 } else if (req_data->type == SIM_FACILITY_FD) {
2598 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2599 } else if (req_data->type == SIM_FACILITY_PN) {
2600 fac = "PN"; /*Network Personalization*/
2601 } else if (req_data->type == SIM_FACILITY_PU) {
2602 fac = "PU"; /*network sUbset Personalization*/
2603 } else if (req_data->type == SIM_FACILITY_PP) {
2604 fac = "PP"; /*service Provider Personalization*/
2605 } else if (req_data->type == SIM_FACILITY_PC) {
2606 fac = "PC"; /*Corporate Personalization*/
2608 return TCORE_RETURN_EINVAL;
2610 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
2611 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2613 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2615 tcore_pending_set_request_data(pending, 0, req);
2616 tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
2617 tcore_pending_link_user_request(pending, ur);
2618 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2619 tcore_hal_send_request(hal, pending);
2622 dbg(" Function exit");
2623 return TCORE_RETURN_SUCCESS;
2626 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2628 TcoreHal *hal = NULL;
2629 TcoreATRequest *req = NULL;
2630 TcorePending *pending = NULL;
2631 char *cmd_str = NULL;
2632 const struct treq_sim_enable_facility *req_data;
2633 struct s_sim_property *sp = NULL;
2635 int mode = 1; /* 0:unlock, 1:lock, 2:query*/
2637 dbg(" Function entry ");
2639 hal = tcore_object_get_hal(o);
2640 sp = tcore_sim_ref_userdata(o);
2641 pending = tcore_pending_new(o, 0);
2642 req_data = tcore_user_request_ref_data(ur, NULL);
2645 return TCORE_RETURN_EINVAL;
2647 if (req_data->type == SIM_FACILITY_PS) {
2648 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2649 sp->current_sec_op = SEC_SIM_ENABLE;
2650 } else if (req_data->type == SIM_FACILITY_SC) {
2651 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2652 sp->current_sec_op = SEC_PIN1_ENABLE;
2653 } else if (req_data->type == SIM_FACILITY_FD) {
2654 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2655 sp->current_sec_op = SEC_FDN_ENABLE;
2656 } else if (req_data->type == SIM_FACILITY_PN) {
2657 fac = "PN"; /*Network Personalization*/
2658 sp->current_sec_op = SEC_NET_ENABLE;
2659 } else if (req_data->type == SIM_FACILITY_PU) {
2660 fac = "PU"; /*network sUbset Personalization*/
2661 sp->current_sec_op = SEC_NS_ENABLE;
2662 } else if (req_data->type == SIM_FACILITY_PP) {
2663 fac = "PP"; /*service Provider Personalization*/
2664 sp->current_sec_op = SEC_SP_ENABLE;
2665 } else if (req_data->type == SIM_FACILITY_PC) {
2666 fac = "PC"; /*Corporate Personalization*/
2667 sp->current_sec_op = SEC_CP_ENABLE;
2669 return TCORE_RETURN_EINVAL;
2671 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2672 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2674 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2676 tcore_pending_set_request_data(pending, 0, req);
2677 tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
2678 tcore_pending_link_user_request(pending, ur);
2679 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2680 tcore_hal_send_request(hal, pending);
2683 dbg(" Function exit");
2684 return TCORE_RETURN_SUCCESS;
2687 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2690 TcoreATRequest *req;
2691 TcorePending *pending = NULL;
2692 char *cmd_str = NULL;
2693 const struct treq_sim_enable_facility *req_data;
2694 struct s_sim_property *sp = NULL;
2696 int mode = 0; /* 0:unlock, 1:lock, 2:query*/
2698 dbg(" Function entry ");
2700 hal = tcore_object_get_hal(o);
2701 sp = tcore_sim_ref_userdata(o);
2702 pending = tcore_pending_new(o, 0);
2703 req_data = tcore_user_request_ref_data(ur, NULL);
2706 return TCORE_RETURN_EINVAL;
2708 if (req_data->type == SIM_FACILITY_PS) {
2709 fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
2710 sp->current_sec_op = SEC_SIM_DISABLE;
2711 } else if (req_data->type == SIM_FACILITY_SC) {
2712 fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
2713 sp->current_sec_op = SEC_PIN1_DISABLE;
2714 } else if (req_data->type == SIM_FACILITY_FD) {
2715 fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
2716 sp->current_sec_op = SEC_FDN_DISABLE;
2717 } else if (req_data->type == SIM_FACILITY_PN) {
2718 fac = "PN"; /*Network Personalization*/
2719 sp->current_sec_op = SEC_NET_DISABLE;
2720 } else if (req_data->type == SIM_FACILITY_PU) {
2721 fac = "PU"; /*network sUbset Personalization*/
2722 sp->current_sec_op = SEC_NS_DISABLE;
2723 } else if (req_data->type == SIM_FACILITY_PP) {
2724 fac = "PP"; /*service Provider Personalization*/
2725 sp->current_sec_op = SEC_SP_DISABLE;
2726 } else if (req_data->type == SIM_FACILITY_PC) {
2727 fac = "PC"; /*Corporate Personalization*/
2728 sp->current_sec_op = SEC_CP_DISABLE;
2730 return TCORE_RETURN_EINVAL;
2732 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
2733 req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
2735 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2737 tcore_pending_set_request_data(pending, 0, req);
2738 tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
2739 tcore_pending_link_user_request(pending, ur);
2740 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2741 tcore_hal_send_request(hal, pending);
2744 dbg(" Function exit");
2745 return TCORE_RETURN_SUCCESS;
2748 static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
2750 TcoreHal *hal = NULL;
2751 TcoreATRequest *req = NULL;
2752 TcorePending *pending = NULL;
2753 char *cmd_str = NULL;
2754 char *lock_type = NULL;
2755 const struct treq_sim_get_lock_info *req_data;
2756 struct s_sim_property *sp = NULL;
2758 dbg(" Function entry ");
2760 hal = tcore_object_get_hal(o);
2761 sp = tcore_sim_ref_userdata(o);
2762 pending = tcore_pending_new(o, 0);
2763 req_data = tcore_user_request_ref_data(ur, NULL);
2766 return TCORE_RETURN_EINVAL;
2768 switch (req_data->type) {
2769 case SIM_FACILITY_PS:
2773 case SIM_FACILITY_SC:
2777 case SIM_FACILITY_FD:
2781 case SIM_FACILITY_PN:
2785 case SIM_FACILITY_PU:
2789 case SIM_FACILITY_PP:
2793 case SIM_FACILITY_PC:
2800 cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
2801 req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
2803 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2805 tcore_pending_set_request_data(pending, 0, req);
2806 tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
2807 tcore_pending_link_user_request(pending, ur);
2808 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2809 tcore_hal_send_request(hal, pending);
2812 dbg(" Function exit");
2813 return TCORE_RETURN_SUCCESS;
2816 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
2818 TReturn api_ret = TCORE_RETURN_SUCCESS;
2819 enum tcore_request_command command;
2821 command = tcore_user_request_get_command(ur);
2823 dbg(" Function entry ");
2826 return TCORE_RETURN_EINVAL;
2829 case TREQ_SIM_GET_ECC:
2830 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
2833 case TREQ_SIM_GET_LANGUAGE:
2834 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
2835 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
2836 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
2837 api_ret = _get_file_info(o, ur, SIM_EF_LP);
2839 api_ret = TCORE_RETURN_ENOSYS;
2842 case TREQ_SIM_GET_ICCID:
2843 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
2846 case TREQ_SIM_GET_MAILBOX:
2847 if (tcore_sim_get_cphs_status(o))
2848 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
2850 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
2853 case TREQ_SIM_GET_CALLFORWARDING:
2854 if (tcore_sim_get_cphs_status(o))
2855 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
2857 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
2860 case TREQ_SIM_GET_MESSAGEWAITING:
2861 if (tcore_sim_get_cphs_status(o))
2862 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
2864 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
2867 case TREQ_SIM_GET_CPHS_INFO:
2868 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
2871 case TREQ_SIM_GET_MSISDN:
2872 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
2875 case TREQ_SIM_GET_SPN:
2876 dbg("enter case SPN");
2877 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
2880 case TREQ_SIM_GET_SPDI:
2881 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
2884 case TREQ_SIM_GET_OPL:
2885 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
2888 case TREQ_SIM_GET_PNN:
2889 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
2892 case TREQ_SIM_GET_CPHS_NETNAME:
2893 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
2896 case TREQ_SIM_GET_OPLMNWACT:
2897 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
2901 dbg("error - not handled read treq command[%d]", command);
2902 api_ret = TCORE_RETURN_EINVAL;
2905 dbg(" Function exit");
2909 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
2912 TcoreATRequest *req;
2913 TcorePending *pending = NULL;
2914 char *cmd_str = NULL;
2915 TReturn api_ret = TCORE_RETURN_SUCCESS;
2916 char *encoded_data = NULL;
2917 int encoded_len = 0;
2918 enum tcore_request_command command;
2919 enum tel_sim_file_id ef = SIM_EF_INVALID;
2920 const struct treq_sim_set_callforwarding *cf;
2921 const struct treq_sim_set_language *cl;
2922 struct s_sim_property file_meta = {0, };
2929 struct tel_sim_language sim_language;
2933 command = tcore_user_request_get_command(ur);
2935 dbg(" Function entry ");
2937 hal = tcore_object_get_hal(o);
2938 pending = tcore_pending_new(o, 0);
2941 return TCORE_RETURN_EINVAL;
2945 case TREQ_SIM_SET_LANGUAGE:
2946 cl = tcore_user_request_ref_data(ur, NULL);
2947 memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
2950 sim_language.language_count = 1;
2951 sim_language.language[0] = cl->language;
2952 dbg("language %d", cl->language);
2954 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
2957 tmp = tcore_sim_encode_lp(&out_length, &sim_language);
2959 encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
2960 memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
2961 result = util_byte_to_hex(tmp, encoded_data, out_length);
2966 dbg("encoded_data - %s ---", encoded_data);
2967 dbg("out_length - %d ---", out_length);
2968 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
2971 tmp = tcore_sim_encode_li(&out_length, &sim_language);
2973 encoded_data = (char *) malloc(2 * (out_length) + 1);
2974 memset(encoded_data, 0x00, (2 * out_length) + 1);
2975 result = util_byte_to_hex(tmp, encoded_data, out_length);
2980 dbg("encoded_data - %s ---", encoded_data);
2981 dbg("out_length - %d ---", out_length);
2983 api_ret = TCORE_RETURN_ENOSYS;
2987 case TREQ_SIM_SET_CALLFORWARDING:
2988 cf = tcore_user_request_ref_data(ur, NULL);
2989 if (tcore_sim_get_cphs_status(o)) {
2990 tmp = tcore_sim_encode_cff((const struct tel_sim_callforwarding *) cf);
2991 ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
2995 encoded_data = (char *) malloc(2 * (p3) + 1);
2996 memset(encoded_data, 0x00, (2 *p3) + 1);
2997 result = util_byte_to_hex(tmp, encoded_data, p3);
2998 cmd = 214; /*command - 214 : UPDATE BINARY*/
3000 tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_callforwarding *) cf);
3001 ef = SIM_EF_USIM_CFIS;
3005 encoded_data = (char *) malloc(2 * (encoded_len) + 1);
3006 memset(encoded_data, 0x00, (2 * encoded_len) + 1);
3007 result = util_byte_to_hex(tmp, encoded_data, encoded_len);
3008 cmd = 220; /*command - 220 : UPDATE RECORD*/
3013 dbg("error - not handled update treq command[%d]", command);
3014 api_ret = TCORE_RETURN_EINVAL;
3017 file_meta.file_id = ef;
3018 dbg("file_meta.file_id: %d", file_meta.file_id);
3020 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
3021 dbg("trt[%d]", trt);
3023 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
3024 req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
3026 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3028 tcore_pending_set_request_data(pending, 0, req);
3029 tcore_pending_set_response_callback(pending, on_response_update_file, hal);
3030 tcore_pending_link_user_request(pending, ur);
3031 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
3033 tcore_hal_send_request(hal, pending);
3034 if (NULL != encoded_data) {
3035 g_free(encoded_data);
3043 dbg(" Function exit");
3044 return TCORE_RETURN_SUCCESS;
3047 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
3049 TcoreHal *hal = NULL;
3050 TcoreATRequest *req = NULL;
3051 TcorePending *pending = NULL;
3052 char *cmd_str = NULL;
3055 const struct treq_sim_transmit_apdu *req_data;
3057 dbg(" Function entry ");
3059 hal = tcore_object_get_hal(o);
3060 pending = tcore_pending_new(o, 0);
3061 req_data = tcore_user_request_ref_data(ur, NULL);
3064 return TCORE_RETURN_EINVAL;
3066 apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
3067 memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
3068 result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
3070 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", req_data->apdu_length * 2, apdu);
3072 req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
3074 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
3076 tcore_pending_set_request_data(pending, 0, req);
3077 tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
3078 tcore_pending_link_user_request(pending, ur);
3079 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
3080 tcore_hal_send_request(hal, pending);
3084 dbg(" Function exit");
3085 return TCORE_RETURN_SUCCESS;
3088 static struct tcore_sim_operations sim_ops = {
3089 .verify_pins = s_verify_pins,
3090 .verify_puks = s_verify_puks,
3091 .change_pins = s_change_pins,
3092 .get_facility_status = s_get_facility_status,
3093 .enable_facility = s_enable_facility,
3094 .disable_facility = s_disable_facility,
3095 .get_lock_info = s_get_lock_info,
3096 .read_file = s_read_file,
3097 .update_file = s_update_file,
3098 .transmit_apdu = s_transmit_apdu,
3099 /*ToDo - Need to be implemented in Phase-2*/
3100 /*.get_atr = s_get_atr,
3101 .req_authentication = s_req_authentication*/
3104 gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
3107 struct s_sim_property *file_meta = NULL;
3112 o = tcore_sim_new(p, "sim", &sim_ops, h);
3117 file_meta = calloc(sizeof(struct s_sim_property), 1);
3121 work_queue = g_queue_new();
3122 tcore_object_link_user_data(o, work_queue);
3124 file_meta->first_recv_status = SIM_STATUS_UNKNOWN;
3125 tcore_sim_link_userdata(o, file_meta);
3127 tcore_object_add_callback(o, "+XLOCK", on_event_facility_lock_status, NULL);
3128 tcore_object_add_callback(o, "+XSIM", on_event_pin_status, NULL);
3134 void s_sim_exit(TcorePlugin *p)
3138 o = tcore_plugin_ref_core_object(p, "sim");