2 * tel-plugin-samsung-atmodem
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hayoon Ko <hayoon.ko@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.
30 #include <core_object.h>
36 #include <user_request.h>
41 #include "atchannel.h"
44 extern struct ATResponse *sp_response;
45 extern char *s_responsePrefix;
46 extern enum ATCommandType s_type;
48 #define SWAPBYTES16(x) \
50 unsigned short int data = *(unsigned short int*)&(x); \
51 data = ((data & 0xff00) >> 8) | \
52 ((data & 0x00ff) << 8); \
53 *(unsigned short int*)&(x) = data ; \
56 enum s_sim_file_type_e {
57 SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
58 SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
59 SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
60 SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
61 SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
76 SEC_PIN2_DISABLE, //10
99 struct s_sim_property {
100 gboolean b_valid; /**< Valid or not */
101 enum tel_sim_file_id file_id; /**< File identifier */
102 enum s_sim_file_type_e file_type; /**< File type and structure */
103 int rec_length; /**< Length of one record in file */
104 int rec_count; /**< Number of records in file */
105 int data_size; /**< File size */
106 int current_index; /**< current index to read */
107 enum tel_sim_status first_recv_status;
108 enum s_sim_sec_op_e current_sec_op; /**< current index to read */
109 struct tresp_sim_read files;
110 struct ATReqMetaInfo metainfo;
113 enum s_sim_sec_locktype_e{
114 SEC_LOCK_TYPE_NONE =0,
115 SEC_LOCK_TYPE_READY, /* ME is not locked */
116 SEC_LOCK_TYPE_PS, /* PH-SIM, Lock Phone to SIM/UICC card(MT asks password when other than current SIM/UICC card inserted; MT may remember certain amount of
117 previously used cards thus not requiring password when they are inserted ) */
118 SEC_LOCK_TYPE_PF, /* PH-FSIM, Lock Phone to the very First inserted SIM/UICC card ( MT asks password when other than the first SIM/UICC card is inserted ) */
119 SEC_LOCK_TYPE_SC, /*Lock SIM/UICC card ( SIM asks password in ME power-up and when this command is issued ) */
120 SEC_LOCK_TYPE_FD, /* SIM card or active application in the UICC(GSM or USIM) fixed dialing memory feature */
121 SEC_LOCK_TYPE_PN, /* Network Personalization */
122 SEC_LOCK_TYPE_PU, /* Network subset Personalization */
123 SEC_LOCK_TYPE_PP, /* Service Provider Personalization */
124 SEC_LOCK_TYPE_PC, /* Corporate Personalization */
125 SEC_LOCK_TYPE_SC2, /* Lock PIN2 ( ... ) */
126 SEC_LOCL_TYPE_PUK2, /* Lock PUK2 (... ) */
127 SEC_LOCK_TYPE_ACL, /* ACL */
129 SEC_LOCK_TYPE_NO_SIM, /* SIM is not inserted */
130 SEC_LOCK_TYPE_UNAVAIL, /* SIM is inserted but can not communicate with SIM ( SIM interface error ) */
131 SEC_SIM_INIT_COMPLETED, /* SIM Initialize Completed */
132 SEC_PB_INIT_COMPLETED, /* Phonebook Initialize Completed*/
133 SEC_SIM_INIT_CRASH, /* SIM Crash request from SMC lab*/
138 enum s_sim_sec_lockkey_e{
140 SEC_LOCK_KEY_UNLOCKED, /* Not necessary */
141 SEC_LOCK_KEY_PIN, /* PIN required as a password */
142 SEC_LOCK_KEY_PUK, /* 0PUK required as a password */
143 SEC_LOCK_KEY_PIN2, /* PIN2 required as a password */
144 SEC_LOCK_KEY_PUK2, /* PUK2 required as a password */
145 SEC_LOCK_KEY_PERM_BLOCKED, /* PIN Permanent Blocked */
146 SEC_LOCK_KEY_PIN2_DISABLE, /* PIN2 Lock Disabled*/
152 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
153 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
154 static gboolean _get_sim_type(CoreObject *o);
155 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
156 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
157 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
158 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
160 static gboolean _convert_SCPIN_noti(char* line, enum s_sim_sec_locktype_e* lock_type, enum s_sim_sec_lockkey_e* lock_key);
162 static gboolean _convert_SCPIN_noti(char* line, enum s_sim_sec_locktype_e* lock_type, enum s_sim_sec_lockkey_e* lock_key)
164 char *type =NULL, *key = NULL;
169 dbg("incoming string : %s\n", line);
174 // 1. find type string
175 err = at_tok_nextstr(&line, &type);
177 // no type string found.
181 // 2. find key string
182 err = at_tok_nextstr(&line, &key);
189 dbg("type : %s, key : %s\n", type, key);
191 // 3. convert string into enum
194 if(strStartsWith (type, "NO_SIM"))
195 *lock_type = SEC_LOCK_TYPE_NO_SIM;
196 else if(strStartsWith (type, "UNAVAIL"))
197 *lock_type = SEC_LOCK_TYPE_UNAVAIL;
198 else if(strStartsWith (type, "NO_LOCK"))
199 *lock_type = SEC_LOCK_TYPE_READY;
200 else if(strStartsWith (type, "LOCK_PS"))
201 *lock_type = SEC_LOCK_TYPE_PS;
202 else if(strStartsWith (type, "LOCK_PF"))
203 *lock_type = SEC_LOCK_TYPE_PF ;
204 else if(strStartsWith (type, "LOCK_SC"))
205 *lock_type = SEC_LOCK_TYPE_SC;
206 else if(strStartsWith (type, "LOCK_FD"))
207 *lock_type = SEC_LOCK_TYPE_FD;
208 else if(strStartsWith (type, "LOCK_PN"))
209 *lock_type = SEC_LOCK_TYPE_PN ;
210 else if(strStartsWith (type, "LOCK_PU"))
211 *lock_type = SEC_LOCK_TYPE_PU ;
212 else if(strStartsWith (type, "LOCK_PP"))
213 *lock_type = SEC_LOCK_TYPE_PP;
214 else if(strStartsWith (type, "LOCK_PC"))
215 *lock_type = SEC_LOCK_TYPE_PC;
216 else if(strStartsWith (type, "LOCK_SC2"))
217 *lock_type = SEC_LOCK_TYPE_SC2 ;
218 else if(strStartsWith (type, "LOCK_ACL"))
219 *lock_type = SEC_LOCK_TYPE_ACL;
220 else if(strStartsWith (type, "LOCK_PUK2"))
221 *lock_type = SEC_LOCL_TYPE_PUK2;
222 else if(strStartsWith (type, "INIT_COMP"))
223 *lock_type = SEC_SIM_INIT_COMPLETED;
224 else if(strStartsWith (type, "INIT_ERROR"))
225 *lock_type = SEC_SIM_INIT_CRASH;
227 *lock_type = SEC_LOCK_TYPE_NONE;
230 type = SEC_LOCK_TYPE_NONE;
234 if(strStartsWith (type, "PIN"))
235 *lock_key = SEC_LOCK_KEY_PIN;
236 else if(strStartsWith (type, "PUK"))
237 *lock_key = SEC_LOCK_KEY_PUK;
238 else if(strStartsWith (type, "PIN2"))
239 *lock_key = SEC_LOCK_KEY_PIN2;
240 else if(strStartsWith (type, "PUK2"))
241 *lock_key = SEC_LOCK_KEY_PUK2;
242 else if(strStartsWith (type, "BLOCKED"))
243 *lock_key = SEC_LOCK_KEY_PERM_BLOCKED ;
244 else if(strStartsWith (type, "UNLOCKED"))
245 *lock_key = SEC_LOCK_KEY_UNLOCKED ;
246 else if(strStartsWith (type, "PIN2_DISABLE"))
247 *lock_key = SEC_LOCK_KEY_PIN2_DISABLE;
249 *lock_key = SEC_LOCK_KEY_NONE;
252 *lock_key = SEC_LOCK_KEY_NONE;
255 // 4. apply exceptional case.
256 //if type is READY, key has no meanig
257 if(*lock_type == SEC_LOCK_TYPE_READY)
258 *lock_key = SEC_LOCK_KEY_UNLOCKED;
260 // no sim, unvail, init_comp, init_error have no key info
261 if((*lock_type == SEC_LOCK_TYPE_NO_SIM)||(*lock_type == SEC_LOCK_TYPE_UNAVAIL)||
262 (*lock_type == SEC_SIM_INIT_COMPLETED)||(*lock_type == SEC_SIM_INIT_CRASH))
263 *lock_key = SEC_LOCK_KEY_NONE;
265 dbg("type : %d, key : %d\n", *lock_type, *lock_key);
270 static enum tcore_response_command _find_resp_command(UserRequest *ur)
272 enum tcore_request_command command;
273 command = tcore_user_request_get_command(ur);
275 case TREQ_SIM_VERIFY_PINS:
276 return TRESP_SIM_VERIFY_PINS;
278 case TREQ_SIM_VERIFY_PUKS:
279 return TRESP_SIM_VERIFY_PUKS;
281 case TREQ_SIM_CHANGE_PINS:
282 return TRESP_SIM_CHANGE_PINS;
284 case TREQ_SIM_GET_FACILITY_STATUS:
285 return TRESP_SIM_GET_FACILITY_STATUS;
287 case TREQ_SIM_DISABLE_FACILITY:
288 return TRESP_SIM_DISABLE_FACILITY;
290 case TREQ_SIM_ENABLE_FACILITY:
291 return TRESP_SIM_ENABLE_FACILITY;
293 case TREQ_SIM_TRANSMIT_APDU:
294 return TRESP_SIM_TRANSMIT_APDU;
296 case TREQ_SIM_GET_ATR:
297 return TRESP_SIM_GET_ATR;
299 case TREQ_SIM_GET_ECC:
300 return TRESP_SIM_GET_ECC;
302 case TREQ_SIM_GET_LANGUAGE:
303 return TRESP_SIM_GET_LANGUAGE;
305 case TREQ_SIM_SET_LANGUAGE:
306 return TRESP_SIM_SET_LANGUAGE;
308 case TREQ_SIM_GET_ICCID:
309 return TRESP_SIM_GET_ICCID;
311 case TREQ_SIM_GET_MAILBOX:
312 return TRESP_SIM_GET_MAILBOX;
314 case TREQ_SIM_GET_CALLFORWARDING:
315 return TRESP_SIM_GET_CALLFORWARDING;
317 case TREQ_SIM_GET_MESSAGEWAITING:
318 return TRESP_SIM_GET_MESSAGEWAITING;
320 case TREQ_SIM_GET_CPHS_INFO:
321 return TRESP_SIM_GET_CPHS_INFO;
323 case TREQ_SIM_GET_MSISDN:
324 return TRESP_SIM_GET_MSISDN;
326 case TREQ_SIM_GET_SPN:
327 return TRESP_SIM_GET_SPN;
329 case TREQ_SIM_GET_SPDI:
330 return TRESP_SIM_GET_SPDI;
332 case TREQ_SIM_GET_OPL:
333 return TRESP_SIM_GET_OPL;
335 case TREQ_SIM_GET_PNN:
336 return TRESP_SIM_GET_PNN;
338 case TREQ_SIM_GET_CPHS_NETNAME:
339 return TRESP_SIM_GET_CPHS_NETNAME;
341 case TREQ_SIM_GET_OPLMNWACT:
342 return TRESP_SIM_GET_OPLMNWACT;
344 case TREQ_SIM_REQ_AUTHENTICATION:
345 return TRESP_SIM_REQ_AUTHENTICATION;
350 return TRESP_UNKNOWN;
353 static int _sim_get_current_pin_facility(struct s_sim_property *sp)
356 dbg("current sp->current_sec_op[%d]", sp->current_sec_op);
357 switch(sp->current_sec_op){
358 case SEC_PIN1_VERIFY :
359 case SEC_PIN1_CHANGE :
360 ret_type = SIM_PTYPE_PIN1;
362 case SEC_PIN2_VERIFY :
363 case SEC_PIN2_CHANGE :
364 ret_type = SIM_PTYPE_PIN2;
366 case SEC_PUK1_VERIFY :
367 ret_type = SIM_PTYPE_PUK1;
369 case SEC_PUK2_VERIFY :
370 ret_type = SIM_PTYPE_PUK2;
372 case SEC_SIM_VERIFY :
373 ret_type = SIM_PTYPE_SIM;
375 case SEC_ADM_VERIFY :
376 ret_type = SIM_PTYPE_ADM;
379 case SEC_PIN1_ENABLE :
380 case SEC_PIN1_DISABLE :
381 case SEC_PIN1_STATUS :
382 ret_type = SIM_FACILITY_SC;
384 case SEC_SIM_ENABLE :
385 case SEC_SIM_DISABLE :
386 case SEC_SIM_STATUS :
387 ret_type = SIM_FACILITY_PS;
389 case SEC_NET_ENABLE :
390 case SEC_NET_DISABLE :
391 case SEC_NET_STATUS :
392 ret_type = SIM_FACILITY_PN;
395 case SEC_NS_DISABLE :
397 ret_type = SIM_FACILITY_PU;
400 case SEC_SP_DISABLE :
402 ret_type = SIM_FACILITY_PP;
405 case SEC_CP_DISABLE :
407 ret_type = SIM_FACILITY_PC;
409 case SEC_FDN_ENABLE :
410 case SEC_FDN_DISABLE :
411 case SEC_FDN_STATUS :
412 ret_type = SIM_FACILITY_FD;
416 dbg("not handled current op[%d]",sp->current_sec_op )
422 static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
424 enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
426 if (status_word1 == 0x93 && status_word2 == 0x00) {
427 rst = SIM_ACCESS_FAILED;
428 /*Failed SIM request command*/
429 dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
431 else if (status_word1 == 0x94 && status_word2 == 0x00) {
432 rst = SIM_ACCESS_FAILED;
433 /*Failed SIM request command*/
434 dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
436 else if (status_word1 == 0x94 && status_word2 == 0x02) {
437 rst = SIM_ACCESS_FAILED;
438 /*Failed SIM request command*/
439 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
440 status_word1, status_word2);
442 else if (status_word1 == 0x94 && status_word2 == 0x04) {
443 rst = SIM_ACCESS_FILE_NOT_FOUND;
444 /*Failed SIM request command*/
445 dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
447 else if (status_word1 == 0x94 && status_word2 == 0x08) {
448 rst = SIM_ACCESS_FAILED; /* MOdem not support */
449 /*Failed SIM request command*/
450 dbg(" error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
451 status_word1, status_word2);
453 else if (status_word1 == 0x98 && status_word2 == 0x02) {
454 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
455 /*Failed SIM request command*/
456 dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
458 else if (status_word1 == 0x98 && status_word2 == 0x04) {
459 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
460 /*Failed SIM request command*/
461 dbg(" error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
462 dbg(" error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
463 status_word1, status_word2);
464 dbg(" error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
465 status_word1, status_word2);
466 dbg(" error - Authentication failure [%x][%x]", status_word1, status_word2);
468 else if (status_word1 == 0x98 && status_word2 == 0x08) {
469 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
470 /*Failed SIM request command*/
471 dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
473 else if (status_word1 == 0x98 && status_word2 == 0x10) {
474 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
475 /*Failed SIM request command*/
476 dbg(" error - Contradiction with invalidation status [%x][%x]",
477 status_word1, status_word2);
479 else if (status_word1 == 0x98 && status_word2 == 0x40) {
480 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
481 /*Failed SIM request command*/
482 dbg(" error -Unsuccessful CHV verification - no attempt left [%x][%x]",
483 status_word1, status_word2);
484 dbg(" error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
485 status_word1, status_word2);
486 dbg(" error - CHV blocked [%x][%x]", status_word1, status_word2);
488 else if (status_word1 == 0x67 && status_word2 == 0x00) {
489 rst = SIM_ACCESS_FAILED;
490 dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
492 else if (status_word1 == 0x6B && status_word2 == 0x00) {
493 rst = SIM_ACCESS_FAILED;
494 dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
496 else if (status_word1 == 0x6D && status_word2 == 0x00) {
497 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
498 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
500 else if (status_word1 == 0x6E && status_word2 == 0x00) {
501 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
502 dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
504 else if (status_word1 == 0x69 && status_word2 == 0x82) {
505 rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
506 dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
508 else if (status_word1 == 0x6A && status_word2 == 0x87) {
509 rst = SIM_ACCESS_FAILED;
510 dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
512 else if (status_word1 == 0x6A && status_word2 == 0x82) {
513 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
514 dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
516 else if (status_word1 == 0x6A && status_word2 == 0x83) {
517 rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
518 dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
521 rst = SIM_ACCESS_CARD_ERROR;
522 dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
527 static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
530 Storage *strg = NULL;
531 char* old_imsi = NULL;
532 char new_imsi[15+1] = {0,};
534 s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
536 dbg("there is no valid server at this point");
540 strg = (Storage*)tcore_server_find_storage(s, "vconf");
542 dbg("there is no valid storage plugin");
546 memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
547 memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
548 new_imsi[strlen(imsi->plmn)+strlen(imsi->msin)] = '\0';
550 old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
551 dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
553 if (old_imsi != NULL) {
554 if (strncmp(old_imsi, new_imsi, 15) != 0) {
556 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char*) &new_imsi) == FALSE )
557 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
558 tcore_sim_set_identification(o, TRUE);
562 tcore_sim_set_identification(o, FALSE);
566 dbg("OLD SIM VALUE IS NULL. NEW SIM");
567 if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char*) &new_imsi) == FALSE)
568 dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
569 tcore_sim_set_identification(o, TRUE);
574 static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt )
576 struct tresp_sim_read resp = {0,};
577 struct s_sim_property *file_meta = NULL;
579 dbg("EF[0x%x] access Result[%d]", ef, rt);
582 memset(&resp.data, 0x00, sizeof(resp.data));
584 if ((ef != SIM_EF_ELP || ef != SIM_EF_LP || ef != SIM_EF_USIM_PL)
585 && (rt != SIM_ACCESS_SUCCESS)) {
586 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read),
591 file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
595 if (rt == SIM_ACCESS_SUCCESS) {
596 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
597 /* if (po->language_file == 0x00)
598 po->language_file = SIM_EF_ELP;*/
599 _get_file_data(o, ur, ef, 0, file_meta->data_size);
602 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
603 dbg(" [SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
604 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
605 _get_file_info(o, ur, SIM_EF_LP);
607 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
609 " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
610 /* EFELPand EFLI not present at this point. */
611 /* po->language.lang_cnt = 0;*/
612 tcore_user_request_send_response(ur, _find_resp_command(ur),
613 sizeof(struct tresp_sim_read), &resp);
619 case SIM_EF_LP: //same with SIM_EF_USIM_LI
620 if (rt == SIM_ACCESS_SUCCESS) {
621 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
622 /* if (po->language_file == 0x00)
623 po->language_file = SIM_EF_LP;*/
624 _get_file_data(o, ur, ef, 0, file_meta->data_size);
627 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
628 tcore_sim_get_type(o));
629 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
630 /* EFELPand EFLP not present at this point.*/
631 /* po->language.lang_cnt = 0;*/
632 tcore_user_request_send_response(ur, _find_resp_command(ur),
633 sizeof(struct tresp_sim_read), &resp);
636 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
637 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
638 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
639 _get_file_info(o, ur, SIM_EF_ELP);
645 if (rt == SIM_ACCESS_SUCCESS) {
646 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
647 /* if (po->language_file == 0x00)
648 po->language_file = SIM_EF_ELP;*/
649 _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
652 /* EFELIand EFPL not present, so set language count as zero and select ECC */
654 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
655 /* po->language.lang_cnt = 0;*/
656 tcore_user_request_send_response(ur, _find_resp_command(ur),
657 sizeof(struct tresp_sim_read), &resp);
663 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
664 _get_file_data(o, ur, ef, 0, file_meta->data_size);
666 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
667 if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX)
668 file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
670 file_meta->current_index++;
671 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
680 case SIM_EF_CPHS_CPHS_INFO:
681 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
682 case SIM_EF_CPHS_VOICE_MSG_WAITING:
683 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
684 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
685 case SIM_EF_CPHS_DYNAMICFLAGS:
686 case SIM_EF_CPHS_DYNAMIC2FLAG:
687 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
688 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
689 _get_file_data(o, ur, ef, 0, file_meta->data_size);
692 case SIM_EF_USIM_CFIS:
693 if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX)
694 file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
695 file_meta->current_index++;
696 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
701 case SIM_EF_USIM_MWIS:
702 case SIM_EF_USIM_MBI:
704 case SIM_EF_CPHS_MAILBOX_NUMBERS:
705 case SIM_EF_CPHS_INFORMATION_NUMBERS:
706 file_meta->current_index++;
707 _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
711 dbg( "error - File id for get file info [0x%x]", ef);
717 static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
719 struct s_sim_property *file_meta = NULL;
720 file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
722 dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
724 switch (file_meta->file_id) {
729 if (decode_ret == TRUE) {
730 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
731 /* po->language_file = SIM_EF_LP;*/
732 } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
733 /* po->language_file = SIM_EF_ELP;*/
735 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
738 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
739 - EFELP is not available;
740 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
741 - the ME does not support any of the languages in EFELP.
744 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
745 - if the EFLI has the value 'FFFF' in its highest priority position
746 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
748 if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
749 if (file_meta->file_id == SIM_EF_LP)
750 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
752 _get_file_info(o, ur, SIM_EF_LP);
753 } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
754 if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI)
755 _get_file_info(o, ur, SIM_EF_ELP);
757 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
763 if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
764 file_meta->files.data.ecc.ecc_count++;
765 if (file_meta->current_index == file_meta->rec_count) {
766 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
768 file_meta->current_index++;
769 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
771 } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
772 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
774 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
779 _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
783 file_meta->files.data.opl.opl_count++;
784 dbg("file_meta->files.data.opl.opl_count[%d], current index[%d], rec_cnt[%d]",
785 file_meta->files.data.opl.opl_count, file_meta->current_index,file_meta->rec_count);
786 if (file_meta->current_index == file_meta->rec_count) {
787 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
789 file_meta->current_index++;
790 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
794 file_meta->files.data.pnn.pnn_count++;
795 if (file_meta->current_index == file_meta->rec_count) {
796 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
798 file_meta->current_index++;
799 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
802 case SIM_EF_USIM_CFIS:
803 case SIM_EF_USIM_MWIS:
804 case SIM_EF_USIM_MBI:
806 case SIM_EF_CPHS_MAILBOX_NUMBERS:
807 case SIM_EF_CPHS_INFORMATION_NUMBERS:
808 if (file_meta->current_index == file_meta->rec_count) {
809 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
811 file_meta->current_index++;
812 _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length );
820 case SIM_EF_CPHS_CPHS_INFO:
821 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
822 case SIM_EF_CPHS_VOICE_MSG_WAITING:
823 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
824 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
825 case SIM_EF_CPHS_DYNAMICFLAGS:
826 case SIM_EF_CPHS_DYNAMIC2FLAG:
827 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
828 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
829 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
833 dbg("File id not handled [0x%x]", file_meta->file_id);
838 static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
840 struct tnoti_sim_status noti_data = {0,};
842 dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
843 tcore_sim_set_status(o, sim_status);
844 noti_data.sim_status = sim_status;
845 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
846 sizeof(struct tnoti_sim_status), ¬i_data);
849 static void on_confirmation_sim_message_send( TcorePending *p, gboolean result, void *user_data )
851 UserRequest* ur = NULL;
852 struct ATReqMetaInfo* metainfo = NULL;
853 unsigned int info_len =0;
854 struct s_sim_property *file_meta = NULL;
855 dbg("on_confirmation_sim_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
857 //alloc new sp_response
858 ReleaseResponse(); //release leftover
859 //alloc new sp_response
861 sp_response = at_response_new();
863 ur = tcore_pending_ref_user_request(p);
865 dbg("********************************tcore_user_request_get_command[0x%x]", tcore_user_request_get_command(ur));
867 file_meta = (struct s_sim_property *)tcore_user_request_ref_metainfo(ur,&info_len);
868 metainfo = &(file_meta->metainfo);
870 dbg("file_meta->type[%d]", file_meta->metainfo.type);
871 dbg("metainfo->type[%d]", metainfo->type);
873 if((metainfo->type == SINGLELINE)||
874 (metainfo->type == MULTILINE))
877 s_responsePrefix = strdup(metainfo->responsePrefix);
878 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
882 s_responsePrefix = NULL;
885 //set atcmd type into s_type
886 s_type = metainfo->type;
888 if (result == FALSE) {
897 static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
899 struct s_sim_property *sp = NULL;
900 CoreObject *co_sim = NULL;
901 enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
905 if(sp_response->success > 0)
907 line = sp_response->p_intermediates->line;
909 ret = at_tok_start(&line);
913 ret = at_tok_nextint(&line,(int *)&sim_type);
919 sim_type = SIM_TYPE_UNKNOWN;
922 dbg("resp sim type[%d]", sim_type);
926 co_sim = tcore_pending_ref_core_object(p);
927 tcore_sim_set_type(co_sim, sim_type);
928 sp = tcore_sim_ref_userdata(co_sim);
929 _sim_status_update(co_sim, sp->first_recv_status);
932 static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
934 CoreObject *co_sim = NULL;
935 UserRequest *ur = NULL;
936 struct s_sim_property *file_meta = NULL;
937 enum tel_sim_access_result rt;
946 co_sim = tcore_pending_ref_core_object(p);
948 dbg("error - core object is null");
951 ur = tcore_pending_ref_user_request(p);
952 file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
954 if(sp_response->success > 0)
956 line = sp_response->p_intermediates->line;
957 ret = at_tok_start(&line);
961 ret = at_tok_nextint(&line,&sw1);
964 ret = at_tok_nextint(&line,&sw2);
968 /*1. SIM access success case*/
969 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
970 unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
971 unsigned short record_len = 0;
972 char num_of_records = 0;
973 unsigned char file_id_len = 0;
974 unsigned short file_id = 0;
975 unsigned short file_size = 0;
976 unsigned short file_type = 0;
977 unsigned short arr_file_id = 0;
978 int arr_file_id_rec_num = 0;
980 /* handling only last 3 bits */
981 unsigned char file_type_tag = 0x07;
982 unsigned char *ptr_data;
986 ret = at_tok_nextstr(&line,&hexData);
990 recordData = util_hexStringToBytes(hexData);
991 util_hex_dump(" ", strlen(hexData)/2, recordData);
993 ptr_data = (unsigned char *)recordData;
994 if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
996 ETSI TS 102 221 v7.9.0
998 '62' FCP template tag
1000 '82' M File Descriptor
1001 '83' M File Identifier
1002 'A5' O Proprietary information
1003 '8A' M Life Cycle Status Integer
1004 '8B', '8C' or 'AB' C1 Security attributes
1006 '81' O Total file size
1007 '88' O Short File Identifier (SFI)
1010 /* rsim.res_len has complete data length received */
1012 /* FCP template tag - File Control Parameters tag*/
1013 if (*ptr_data == 0x62) {
1014 /* parse complete FCP tag*/
1015 /* increment to next byte */
1017 tag_len = *ptr_data++;
1018 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1019 if (*ptr_data == 0x82) {
1020 /* increment to next byte */
1024 /* unsigned char file_desc_len = *ptr_data++;*/
1025 /* dbg("file descriptor length: [%d]", file_desc_len);*/
1026 /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
1027 /* consider only last 3 bits*/
1028 file_type_tag = file_type_tag & (*ptr_data);
1030 switch (file_type_tag) {
1031 /* increment to next byte */
1034 dbg("Getting FileType: [Transparent file type]");
1035 /* increment to next byte */
1037 file_type = SIM_FTYPE_TRANSPARENT;
1038 /* data coding byte - value 21 */
1043 dbg("Getting FileType: [Linear fixed file type]");
1044 /* increment to next byte */
1046 /* data coding byte - value 21 */
1049 memcpy(&record_len, ptr_data, 2);
1051 SWAPBYTES16(record_len);
1052 ptr_data = ptr_data + 2;
1053 num_of_records = *ptr_data++;
1054 /* Data lossy conversation from enum (int) to unsigned char */
1055 file_type = SIM_FTYPE_LINEAR_FIXED;
1059 dbg(" Cyclic fixed file type");
1060 /* increment to next byte */
1062 /* data coding byte - value 21 */
1065 memcpy(&record_len, ptr_data, 2);
1067 SWAPBYTES16(record_len);
1068 ptr_data = ptr_data + 2;
1069 num_of_records = *ptr_data++;
1070 file_type = SIM_FTYPE_CYCLIC;
1074 dbg("not handled file type [0x%x]", *ptr_data);
1078 dbg("INVALID FCP received - DEbug!");
1082 /*File identifier - file id?? */ // 0x84,0x85,0x86 etc are currently ignored and not handled
1083 if (*ptr_data == 0x83) {
1084 /* increment to next byte */
1086 file_id_len = *ptr_data++;
1087 memcpy(&file_id, ptr_data, file_id_len);
1089 SWAPBYTES16(file_id);
1090 ptr_data = ptr_data + 2;
1091 dbg("Getting FileID=[0x%x]", file_id);
1093 dbg("INVALID FCP received - DEbug!");
1099 /* proprietary information */
1100 if (*ptr_data == 0xA5) {
1101 unsigned short prop_len;
1102 /* increment to next byte */
1105 prop_len = *ptr_data;
1107 ptr_data = ptr_data + prop_len + 1;
1109 dbg("INVALID FCP received - DEbug!");
1112 /* life cycle status integer [8A][length:0x01][status]*/
1115 00000000 : No information given
1116 00000001 : creation state
1117 00000011 : initialization state
1118 000001-1 : operation state -activated
1119 000001-0 : operation state -deactivated
1120 000011-- : Termination state
1121 b8~b5 !=0, b4~b1=X : Proprietary
1122 Any other value : RFU
1124 if (*ptr_data == 0x8A) {
1125 /* increment to next byte */
1127 /* length - value 1 */
1130 switch (*ptr_data) {
1133 dbg("<IPC_RX> operation state -deactivated");
1138 dbg("<IPC_RX> operation state -activated");
1142 dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]",*ptr_data);
1148 /* related to security attributes : currently not handled*/
1149 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1150 /* increment to next byte */
1152 /* if tag length is 3 */
1153 if (*ptr_data == 0x03) {
1154 /* increment to next byte */
1157 memcpy(&arr_file_id, ptr_data, 2);
1159 SWAPBYTES16(arr_file_id);
1160 ptr_data = ptr_data + 2;
1161 arr_file_id_rec_num = *ptr_data++;
1163 /* if tag length is not 3 */
1164 /* ignoring bytes */
1165 // ptr_data = ptr_data + 4;
1166 dbg("Useless security attributes, so jump to next tag");
1167 ptr_data = ptr_data + (*ptr_data + 1);
1170 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1176 dbg("Current ptr_data value is [%x]", *ptr_data);
1178 /* file size excluding structural info*/
1179 if (*ptr_data == 0x80) {
1180 /* for EF file size is body of file and for Linear or cyclic it is
1181 * number of recXsizeof(one record)
1183 /* increment to next byte */
1185 /* length is 1 byte - value is 2 bytes or more */
1187 memcpy(&file_size, ptr_data, 2);
1189 SWAPBYTES16(file_size);
1190 ptr_data = ptr_data + 2;
1192 dbg("INVALID FCP received - DEbug!");
1198 /* total file size including structural info*/
1199 if (*ptr_data == 0x81) {
1201 /* increment to next byte */
1206 ptr_data = ptr_data + 3;
1208 dbg("INVALID FCP received - DEbug!");
1209 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1212 /*short file identifier ignored*/
1213 if (*ptr_data == 0x88) {
1214 dbg("0x88: Do Nothing");
1218 dbg("INVALID FCP received - DEbug!");
1223 } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1224 unsigned char gsm_specific_file_data_len = 0;
1225 /* ignore RFU byte1 and byte2 */
1229 //file_size = p_info->response_len;
1230 memcpy(&file_size, ptr_data, 2);
1232 SWAPBYTES16(file_size);
1233 /* parsed file size */
1234 ptr_data = ptr_data + 2;
1236 memcpy(&file_id, ptr_data, 2);
1237 SWAPBYTES16(file_id);
1238 dbg(" FILE id --> [%x]", file_id);
1239 ptr_data = ptr_data + 2;
1240 /* save file type - transparent, linear fixed or cyclic */
1241 file_type_tag = (*(ptr_data + 7));
1243 switch (*ptr_data) {
1246 dbg(" RFU file type- not handled - Debug!");
1250 dbg(" MF file type - not handled - Debug!");
1254 dbg(" DF file type - not handled - Debug!");
1258 dbg(" EF file type [%d] ", file_type_tag);
1259 /* increment to next byte */
1262 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1263 /* increament to next byte as this byte is RFU */
1266 (file_type_tag == 0x00) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_LINEAR_FIXED;
1268 /* increment to next byte */
1270 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1271 /* the INCREASE command is allowed on the selected cyclic file. */
1272 file_type = SIM_FTYPE_CYCLIC;
1274 /* bytes 9 to 11 give SIM file access conditions */
1276 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1278 /* byte 11 is invalidate and rehabilate nibbles */
1280 /* byte 12 - file status */
1282 /* byte 13 - GSM specific data */
1283 gsm_specific_file_data_len = *ptr_data;
1285 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1287 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1288 record_len = *ptr_data;
1289 dbg("record length[%d], file size[%d]", record_len, file_size);
1291 if (record_len != 0)
1292 num_of_records = (file_size / record_len);
1294 dbg("Number of records [%d]", num_of_records);
1298 dbg(" not handled file type");
1304 dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
1307 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1308 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1310 file_meta->file_type = file_type;
1311 file_meta->data_size = file_size;
1312 file_meta->rec_length = record_len;
1313 file_meta->rec_count = num_of_records;
1314 file_meta->current_index = 0; //reset for new record type EF
1315 rt = SIM_ACCESS_SUCCESS;
1320 /*2. SIM access fail case*/
1321 dbg("error to get ef[0x%x]", file_meta->file_id);
1322 rt = _decode_status_word(sw1, sw2);
1327 ur = tcore_user_request_ref(ur);
1328 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1333 dbg("error to get ef[0x%x]", file_meta->file_id);
1334 rt = SIM_ACCESS_FAILED;;
1336 ur = tcore_user_request_ref(ur);
1337 _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
1341 static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
1343 UserRequest *ur = NULL;
1344 CoreObject *co_sim = NULL;
1345 enum tel_sim_access_result rt;
1346 struct tel_sim_imsi imsi;
1347 struct s_sim_property *file_meta = NULL;
1348 gboolean dr = FALSE;
1355 dbg("[SIM_READ_BINARY] or [SIM_READ_RECORD]");
1357 dbg("sizeof struct tresp_sim_read = [%d]", sizeof(struct tresp_sim_read));
1359 co_sim = tcore_pending_ref_core_object(p);
1361 dbg("error - core object is null");
1364 ur = tcore_pending_ref_user_request(p);
1365 file_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
1367 if(sp_response->success > 0)
1369 line = sp_response->p_intermediates->line;
1371 ret = at_tok_start(&line);
1375 ret = at_tok_nextint(&line,&sw1);
1378 ret = at_tok_nextint(&line,&sw2);
1382 if((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1386 ret = at_tok_nextstr(&line,&hexStr);
1390 fileData = util_hexStringToBytes(hexStr);
1391 util_hex_dump(" ", strlen(hexStr)/2, fileData);
1393 rt = SIM_ACCESS_SUCCESS;
1394 file_meta->files.result = rt;
1396 switch (file_meta->file_id)
1399 dr = tcore_sim_decode_imsi(&imsi, (unsigned char *)fileData, strlen(fileData));
1401 dbg("imsi decoding failed");
1403 _sim_check_identity(co_sim,&imsi);
1404 tcore_sim_set_imsi(co_sim,&imsi);
1409 dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *)fileData, strlen(fileData));
1412 case SIM_EF_ELP:/* 2G EF - 2 bytes decoding*/
1413 case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
1414 case SIM_EF_USIM_PL:/* 3G EF - same as EFELP, so 2 byte decoding*/
1415 case SIM_EF_LP:/* 1 byte encoding*/
1416 if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
1417 /*2G LP(0x6F05) has 1 byte for each language*/
1418 dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *)fileData, strlen(fileData));
1420 /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
1421 dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *)fileData, strlen(fileData));
1426 dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *)fileData, strlen(fileData));
1430 dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *)fileData, strlen(fileData));
1434 /* if(tcore_sim_get_type(o) == SIM_TYPE_GSM)
1435 dr = tcore_sim_decode_sst(&file_meta->files.data , fileData, response_len);
1436 else if(tcore_sim_get_type(o) == SIM_TYPE_USIM)
1437 dr = tcore_sim_decode_ust(&po->st_u.ust, fileData, response_len);
1439 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(o));
1444 /* dr = tcore_sim_decode_xdn(&file_meta->files.data.mailbox, fileData, strlen(fileData));*/
1448 if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
1449 dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *)fileData, strlen(fileData));
1450 } else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM){
1451 dr = tcore_sim_decode_uecc(&file_meta->files.data.ecc.ecc[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
1453 dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
1457 case SIM_EF_USIM_MBI:
1458 /* dr = tcore_sim_decode_mbi(&po->mb_u.mailbox.mbi, fileData, strlen(fileData));*/
1462 dr = tcore_sim_decode_opl(&file_meta->files.data.opl.opl[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
1466 dr = tcore_sim_decode_pnn(&file_meta->files.data.pnn.pnn[file_meta->current_index-1], (unsigned char *)fileData, strlen(fileData));
1469 case SIM_EF_OPLMN_ACT:
1470 dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *)fileData, strlen(fileData));
1473 case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1474 dr = tcore_sim_decode_cff(&file_meta->files.data.cf, (unsigned char *)fileData, strlen(fileData));
1477 case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1478 /* dr = tcore_sim_decode_csp(&po->p_cphs->csp, fileData, strlen(fileData));*/
1481 case SIM_EF_CPHS_VOICE_MSG_WAITING:
1482 dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.mw_data_u.cphs_mw, (unsigned char *)fileData, strlen(fileData));
1485 case SIM_EF_CPHS_MAILBOX_NUMBERS:
1486 /* dbg("[CPHS]decoding SIM_EF_CPHS_MAILBOX_NUMBERS");
1487 if (file_meta->current_index == 1)
1488 dr = tcore_sim_decode_xdn(&po->mb_u.mbn.voice_line1, fileData, strlen(fileData));
1489 else if (file_meta->current_index == 2)
1490 dr = tcore_sim_decode_xdn(&po->mb_u.mbn.voice_line2, fileData, strlen(fileData));
1491 else if (file_meta->current_index == 3)
1492 dr = tcore_sim_decode_xdn(&po->mb_u.mbn.video, fileData, strlen(fileData));
1493 else if (file_meta->current_index == 4)
1494 dr = tcore_sim_decode_xdn(&po->mb_u.mbn.fax, fileData, strlen(fileData));
1496 dbg("[CPHS]wrong EF record index[%d] in here", file_meta->current_index);
1500 case SIM_EF_USIM_MWIS:
1501 dr = tcore_sim_decode_mwis(&file_meta->files.data.mw.mw_data_u.mw, (unsigned char *)fileData, strlen(fileData));
1504 case SIM_EF_USIM_CFIS:
1505 dr = tcore_sim_decode_cfis(&file_meta->files.data.cf, (unsigned char *)fileData, strlen(fileData));
1508 case SIM_EF_CPHS_SERVICE_STRING_TABLE:
1509 dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1512 case SIM_EF_CPHS_OPERATOR_NAME_STRING:
1513 dr = tcore_sim_decode_ons((unsigned char*)&file_meta->files.data.cphs_net.full_name, (unsigned char *)fileData, strlen(fileData));
1516 case SIM_EF_CPHS_DYNAMICFLAGS:
1517 /* dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, fileData, strlen(fileData));*/
1520 case SIM_EF_CPHS_DYNAMIC2FLAG:
1521 /* dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, fileData, strlen(fileData));*/
1524 case SIM_EF_CPHS_CPHS_INFO:
1525 dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *)fileData, strlen(fileData));
1528 case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1529 dr = tcore_sim_decode_short_ons((unsigned char*)&file_meta->files.data.cphs_net.short_name, (unsigned char *)fileData, strlen(fileData));
1532 case SIM_EF_CPHS_INFORMATION_NUMBERS:
1533 /* dr = tcore_sim_decode_information_number(&po->p_cphs->infn, fileData, strlen(fileData));*/
1537 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1546 rt = _decode_status_word(sw1, sw2);
1547 file_meta->files.result = rt;
1555 rt = SIM_ACCESS_FAILED;;
1556 file_meta->files.result = rt;
1559 ur = tcore_user_request_ref(ur);
1560 _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
1563 static gboolean _get_sim_type(CoreObject *o)
1565 TcorePlugin *p = NULL;
1567 TcorePending *pending = NULL;
1569 char *cmd_str = NULL;
1570 struct s_sim_property file_meta={0,};
1572 UserRequest *ur = NULL;
1577 p = tcore_object_ref_plugin(o);
1578 h = tcore_object_get_hal(o);
1580 file_meta.metainfo.type = SINGLELINE;
1581 memcpy(file_meta.metainfo.responsePrefix,"%SCCT:",strlen("%SCCT:"));
1583 ur = tcore_user_request_new(NULL, NULL);
1585 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1589 // AT+CPIN=<pin>[,<newpin>]
1590 cmd_str = g_strdup("AT%SCCT\r");
1592 pending = tcore_pending_new(o, ID_RESERVED_AT);
1593 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1594 tcore_pending_set_timeout(pending, 0);
1595 tcore_pending_set_response_callback(pending, _response_get_sim_type, NULL);
1596 tcore_pending_link_user_request(pending, ur);
1598 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1600 tcore_hal_send_request(h, pending);
1607 static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
1609 TcorePlugin *p = NULL;
1611 TcorePending *pending = NULL;
1613 struct s_sim_property file_meta={0,};
1616 char *cmd_str = NULL;
1619 return TCORE_RETURN_EINVAL;
1621 p = tcore_object_ref_plugin(o);
1622 h = tcore_object_get_hal(o);
1624 file_meta.file_id = ef;
1625 file_meta.metainfo.type = SINGLELINE;
1626 memcpy(file_meta.metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1628 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
1631 // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
1632 cmd_str = g_strdup_printf("AT+CRSM=192, %d%s", ef, "\r");
1634 dbg("new pending(IPC_SEC_RSIM_ACCESS GET - SELECT EF[0x%x])",ef);
1635 pending = tcore_pending_new(o, ID_RESERVED_AT);
1636 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1637 tcore_pending_set_timeout(pending, 0);
1638 tcore_pending_set_response_callback(pending, _response_get_file_info, NULL);
1639 tcore_pending_link_user_request(pending, ur);
1641 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1643 tcore_hal_send_request(h, pending);
1646 return TCORE_RETURN_SUCCESS;
1649 static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
1651 TcorePlugin *p = NULL;
1653 TcorePending *pending = NULL;
1656 char *cmd_str = NULL;
1657 struct ATReqMetaInfo metainfo;
1666 dbg("new pending(IPC_SEC_RSIM_ACCESS GET - READ BIN)");
1668 p = tcore_object_ref_plugin(o);
1669 h = tcore_object_get_hal(o);
1671 // offset for reading the TRANSPARENT data
1672 p1 = (unsigned char)(offset & 0xFF00) >> 8;
1673 p2 = (unsigned char)offset & 0x00FF; //offset low
1674 p3 = (unsigned char)length;
1675 dbg("EF[0x%x]", ef);
1677 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1678 metainfo.type = SINGLELINE;
1679 memcpy(metainfo.responsePrefix,"+CRSM:",strlen("+CRSM:"));
1680 info_len = sizeof(struct ATReqMetaInfo);
1682 // AT+CRSM=<command>,<fildid>,<p1>,<p2+C29,<p3>
1683 cmd_str = g_strdup_printf("AT+CRSM=176, %d%s", ef, "\r");
1685 pending = tcore_pending_new(o, ID_RESERVED_AT);
1686 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
1687 tcore_pending_set_timeout(pending, 0);
1688 tcore_pending_set_response_callback(pending, _response_get_file_data, NULL);
1689 tcore_pending_link_user_request(pending, ur);
1691 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
1693 tcore_hal_send_request(h, pending);
1698 static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
1700 dbg("need to be implemented to use ATCMD");
1705 static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
1708 char *line = (char *) event_info;
1709 //struct tnoti_sim_status noti_data;
1710 struct s_sim_property *sp = NULL;
1711 enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
1712 enum s_sim_sec_locktype_e locktype = SEC_LOCK_TYPE_NONE;
1713 enum s_sim_sec_lockkey_e lockkey = SEC_LOCK_KEY_NONE;
1715 dbg("PIN_STATUS NOTI : %s", line);
1717 _convert_SCPIN_noti(line,&locktype, &lockkey);
1719 sp = tcore_sim_ref_userdata(o);
1723 case SEC_LOCK_TYPE_READY:
1724 if (lockkey == SEC_LOCK_KEY_UNLOCKED) {
1725 sim_status = SIM_STATUS_INITIALIZING;
1726 dbg(" Inside PIN disabled at BOOT UP");
1729 dbg(" not handled case p_status->lock_key[%d]", lockkey);
1733 case SEC_LOCK_TYPE_PS:
1734 sim_status = SIM_STATUS_LOCK_REQUIRED;
1735 dbg( " SIM LOCK required");
1738 case SEC_LOCK_TYPE_PF:
1739 sim_status = SIM_STATUS_CARD_ERROR;
1740 dbg( "PF required ");
1743 case SEC_LOCK_TYPE_SC:
1745 case SEC_LOCK_KEY_UNLOCKED:
1747 case SEC_LOCK_KEY_PIN:
1748 sim_status = SIM_STATUS_PIN_REQUIRED;
1749 dbg( " PIN1 required");
1751 case SEC_LOCK_KEY_PUK:
1752 sim_status = SIM_STATUS_PUK_REQUIRED;
1753 dbg( " PUK required");
1755 case SEC_LOCK_KEY_PERM_BLOCKED:
1756 sim_status = SIM_STATUS_CARD_BLOCKED;
1757 dbg( " Card permanently blocked");
1760 dbg(" SEC_SIM_LOCK_SC -not handled SEC Lock key ");
1765 case SEC_LOCK_TYPE_FD:
1766 dbg(" SEC_LOCK_TYPE_FD -not handled Notification");
1769 case SEC_LOCK_TYPE_PN:
1771 case SEC_LOCK_KEY_PIN:
1772 dbg(" ADMIN-NCK required");
1773 sim_status = SIM_STATUS_NCK_REQUIRED;
1776 dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
1782 case SEC_LOCK_TYPE_PU:
1783 dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
1785 case SEC_LOCK_KEY_PIN:
1786 dbg(" ADMIN-NSCK required");
1787 sim_status = SIM_STATUS_NSCK_REQUIRED;
1790 dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
1796 case SEC_LOCK_TYPE_PP:
1798 dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
1799 case SEC_LOCK_KEY_PIN:
1800 dbg(" ADMIN-SPCK required");
1801 sim_status = SIM_STATUS_SPCK_REQUIRED;
1804 dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
1810 case SEC_LOCK_TYPE_PC:
1812 dbg("Lock Personalization p_status->lock_key =[%d]", lockkey);
1813 case SEC_LOCK_KEY_PIN:
1814 dbg(" ADMIN-CCK required");
1815 sim_status = SIM_STATUS_CCK_REQUIRED;
1818 dbg(" SIM_LOCK_PN/PU/PP/PC -not handled SEC Lock key =[%d]",
1824 case SEC_LOCK_TYPE_SC2:
1825 dbg("SEC_LOCK_TYPE_SC2: NOT Handled - Debug");
1828 case SEC_LOCL_TYPE_PUK2:
1829 dbg("SEC_LOCL_TYPE_PUK2: NOT Handled - Debug");
1832 case SEC_LOCK_TYPE_NO_SIM:
1833 sim_status = SIM_STATUS_CARD_NOT_PRESENT;
1837 case SEC_LOCK_TYPE_UNAVAIL:
1838 case SEC_SIM_INIT_CRASH: //SMC Lab requirement
1839 sim_status = SIM_STATUS_CARD_ERROR;
1840 dbg( "SIM unavailable");
1843 case SEC_SIM_INIT_COMPLETED:
1844 dbg( "[SIM DATA] MODEM SIM INIT COMPLETED");
1845 sim_status = SIM_STATUS_INIT_COMPLETED;
1848 case SEC_PB_INIT_COMPLETED:
1849 dbg("[SIM DATA] MODEM SIM PB INIT COMPLETED. not handled here! s_phonebook should handle!");
1854 dbg(" not handled SEC lock type ");
1858 dbg("[SIM]Current co->sim_status[%d] and from modem[0x%x]",tcore_sim_get_status(o), sim_status);
1860 switch (sim_status) {
1861 case SIM_STATUS_INIT_COMPLETED:
1862 ur = tcore_user_request_new(NULL, NULL); //this is for using ur metainfo set/ref functionality.
1863 _get_file_info(o, ur, SIM_EF_IMSI);
1866 case SIM_STATUS_INITIALIZING:
1867 case SIM_STATUS_PIN_REQUIRED:
1868 case SIM_STATUS_PUK_REQUIRED:
1869 case SIM_STATUS_CARD_BLOCKED:
1870 case SIM_STATUS_NCK_REQUIRED:
1871 case SIM_STATUS_NSCK_REQUIRED:
1872 case SIM_STATUS_SPCK_REQUIRED:
1873 case SIM_STATUS_CCK_REQUIRED:
1874 case SIM_STATUS_LOCK_REQUIRED:
1875 if( sp->first_recv_status == SIM_STATUS_UNKNOWN ) {
1876 dbg("first received sim status[%d]",sim_status);
1877 sp->first_recv_status = sim_status;
1882 case SIM_STATUS_CARD_REMOVED:
1883 case SIM_STATUS_CARD_NOT_PRESENT:
1884 case SIM_STATUS_CARD_ERROR:
1885 if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
1886 dbg("[SIM]SIM CARD REMOVED!!");
1887 sim_status = SIM_STATUS_CARD_REMOVED;
1889 _sim_status_update(o,sim_status);
1893 dbg("not handled status[%d]", sim_status);
1900 static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
1902 UserRequest *ur = NULL;
1903 CoreObject *co_sim = NULL;
1904 struct s_sim_property *sp = NULL;
1905 struct tresp_sim_verify_pins resp = {0,};
1911 co_sim = tcore_pending_ref_core_object(p);
1912 sp = tcore_sim_ref_userdata(co_sim);
1914 ur = tcore_pending_ref_user_request(p);
1916 dbg("error - current ur is NULL");
1920 if(sp_response->success > 0)
1924 resp.result = SIM_PIN_OPERATION_SUCCESS;
1925 resp.pin_type = _sim_get_current_pin_facility(sp);
1926 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
1930 //failure case - consider this later
1931 line = sp_response->finalResponse;
1933 ret = at_tok_start(&line);
1937 ret = at_tok_nextint(&line,&error);
1943 // ur = user_request_dup(ur);
1944 // _get_retry_count(co_sim, ur);
1946 resp.result = SIM_INCORRECT_PASSWORD;
1947 resp.pin_type = _sim_get_current_pin_facility(sp);
1948 resp.retry_count = 3;
1949 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
1954 static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
1956 UserRequest *ur = NULL;
1957 CoreObject *co_sim = NULL;
1958 struct s_sim_property *sp = NULL;
1959 struct tresp_sim_verify_puks resp = {0,};
1965 co_sim = tcore_pending_ref_core_object(p);
1966 sp = tcore_sim_ref_userdata(co_sim);
1968 ur = tcore_pending_ref_user_request(p);
1970 dbg("error - current ur is NULL");
1974 if(sp_response->success > 0)
1978 resp.result = SIM_PIN_OPERATION_SUCCESS;
1979 resp.pin_type = _sim_get_current_pin_facility(sp);
1980 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
1984 //failure case - consider this later
1985 line = sp_response->finalResponse;
1987 ret = at_tok_start(&line);
1991 ret = at_tok_nextint(&line,&error);
1997 // ur = user_request_dup(ur);
1998 // _get_retry_count(co_sim, ur);
2000 resp.result = SIM_INCORRECT_PASSWORD;
2001 resp.pin_type = _sim_get_current_pin_facility(sp);
2002 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PUKS, sizeof(struct tresp_sim_verify_puks), &resp);
2007 static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
2009 UserRequest *ur = NULL;
2010 CoreObject *co_sim = NULL;
2011 struct s_sim_property *sp = NULL;
2012 struct tresp_sim_change_pins resp = {0,};
2018 co_sim = tcore_pending_ref_core_object(p);
2019 sp = tcore_sim_ref_userdata(co_sim);
2021 ur = tcore_pending_ref_user_request(p);
2023 dbg("error - current ur is NULL");
2027 if(sp_response->success > 0)
2031 resp.result = SIM_PIN_OPERATION_SUCCESS;
2032 resp.pin_type = _sim_get_current_pin_facility(sp);
2033 tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &resp);
2037 //failure case - consider this later
2038 line = sp_response->finalResponse;
2040 ret = at_tok_start(&line);
2044 ret = at_tok_nextint(&line,&error);
2050 // ur = user_request_dup(ur);
2051 // _get_retry_count(co_sim, ur);
2053 resp.result = SIM_INCORRECT_PASSWORD;
2054 resp.pin_type = _sim_get_current_pin_facility(sp);
2055 tcore_user_request_send_response(ur, TRESP_SIM_CHANGE_PINS, sizeof(struct tresp_sim_change_pins), &resp);
2059 static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
2061 UserRequest *ur = NULL;
2062 CoreObject *co_sim = NULL;
2063 struct s_sim_property *sec_meta = NULL;
2064 struct tresp_sim_get_facility_status resp = {0,};
2069 co_sim = tcore_pending_ref_core_object(p);
2070 ur = tcore_pending_ref_user_request(p);
2071 sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
2073 resp.result = SIM_PIN_OPERATION_SUCCESS;
2074 resp.type = _sim_get_current_pin_facility(sec_meta);
2078 if(sp_response->success > 0)
2080 line = sp_response->p_intermediates->line;
2082 ret = at_tok_start(&line);
2086 ret = at_tok_nextint(&line,(int *)&resp.b_enable);
2092 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2098 tcore_user_request_send_response(ur, TRESP_SIM_GET_FACILITY_STATUS,
2099 sizeof(struct tresp_sim_get_facility_status), &resp);
2103 static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2105 UserRequest *ur = NULL;
2106 CoreObject *co_sim = NULL;
2107 struct s_sim_property *sec_meta = NULL;
2108 struct tresp_sim_enable_facility resp = {0,};
2109 struct s_sim_property *sp = NULL;
2114 co_sim = tcore_pending_ref_core_object(p);
2115 ur = tcore_pending_ref_user_request(p);
2116 sp = tcore_sim_ref_userdata(co_sim);
2117 sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
2119 resp.result = SIM_PIN_OPERATION_SUCCESS;
2120 resp.type = _sim_get_current_pin_facility(sec_meta);
2124 if(sp_response->success > 0)
2126 line = sp_response->p_intermediates->line;
2128 ret = at_tok_start(&line);
2132 ret = at_tok_nextint(&line,(int *)&resp.result);
2138 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2144 resp.type = _sim_get_current_pin_facility(sp);
2145 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_enable_facility), &resp);
2149 static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
2151 UserRequest *ur = NULL;
2152 CoreObject *co_sim = NULL;
2153 struct s_sim_property *sec_meta = NULL;
2154 struct tresp_sim_disable_facility resp = {0,};
2155 struct s_sim_property *sp = NULL;
2160 co_sim = tcore_pending_ref_core_object(p);
2161 ur = tcore_pending_ref_user_request(p);
2162 sp = tcore_sim_ref_userdata(co_sim);
2163 sec_meta = (struct s_sim_property*)tcore_user_request_ref_metainfo(ur, NULL);
2165 resp.result = SIM_PIN_OPERATION_SUCCESS;
2166 resp.type = _sim_get_current_pin_facility(sec_meta);
2170 if(sp_response->success > 0)
2172 line = sp_response->p_intermediates->line;
2174 ret = at_tok_start(&line);
2178 ret = at_tok_nextint(&line,(int *)&resp.result);
2184 resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
2190 resp.type = _sim_get_current_pin_facility(sp);
2191 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_disable_facility), &resp);
2195 static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
2197 TcorePlugin *p = NULL;
2199 TcorePending *pending = NULL;
2201 struct s_sim_property *sp = NULL;
2202 const struct treq_sim_verify_pins *req_data;
2205 char *cmd_str = NULL;
2208 return TCORE_RETURN_EINVAL;
2210 p = tcore_object_ref_plugin(o);
2211 h = tcore_object_get_hal(o);
2212 req_data = tcore_user_request_ref_data(ur, NULL);
2213 sp = tcore_sim_ref_userdata(o);
2215 if (req_data->pin_type == SIM_PTYPE_PIN1) {
2216 sp->current_sec_op = SEC_PIN1_VERIFY;
2218 else if (req_data->pin_type == SIM_PTYPE_PIN2) {
2219 sp->current_sec_op = SEC_PIN2_VERIFY;
2221 else if (req_data->pin_type == SIM_PTYPE_SIM) {
2222 sp->current_sec_op = SEC_SIM_VERIFY;
2224 else if (req_data->pin_type == SIM_PTYPE_ADM) {
2225 sp->current_sec_op = SEC_ADM_VERIFY;
2228 return TCORE_RETURN_EINVAL;
2231 sp->metainfo.type = NO_RESULT;
2232 sp->metainfo.responsePrefix[0] = '\0';
2234 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
2238 // AT+CPIN=<pin>[,<newpin>]
2239 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"%s", req_data->pin, "\r");
2240 dbg("new pending(verify - pins), %s", cmd_str);
2242 pending = tcore_pending_new(o,ID_RESERVED_AT);
2243 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2244 tcore_pending_set_timeout(pending, 0);
2245 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2246 tcore_pending_set_response_callback(pending, on_response_verify_pins, NULL);
2247 tcore_pending_link_user_request(pending, ur);
2249 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2251 tcore_hal_send_request(h, pending);
2255 return TCORE_RETURN_SUCCESS;
2258 static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
2260 TcorePlugin *p = NULL;
2262 TcorePending *pending = NULL;
2264 const struct treq_sim_verify_puks *req_data;
2265 struct s_sim_property *sp = NULL;
2268 char *cmd_str = NULL;
2271 return TCORE_RETURN_EINVAL;
2273 p = tcore_object_ref_plugin(o);
2274 h = tcore_object_get_hal(o);
2275 req_data = tcore_user_request_ref_data(ur, NULL);
2276 sp = tcore_sim_ref_userdata(o);
2279 if(req_data->puk_type == SIM_PTYPE_PUK1){
2280 sp->current_sec_op = SEC_PUK1_VERIFY;
2282 else if(req_data->puk_type == SIM_PTYPE_PUK2){
2283 sp->current_sec_op = SEC_PUK2_VERIFY;
2286 return TCORE_RETURN_EINVAL;
2289 sp->metainfo.type = NO_RESULT;
2290 sp->metainfo.responsePrefix[0] = '\0';
2292 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
2295 // AT+CPIN=<pin>[,<newpin>]
2296 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"%s", req_data->puk, req_data->pin, "\r");
2298 dbg("new pending(IPC_SEC_PIN_STATUS SET - verify puks)");
2299 pending = tcore_pending_new(o, ID_RESERVED_AT);
2300 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2301 tcore_pending_set_timeout(pending, 0);
2302 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2303 tcore_pending_set_response_callback(pending, on_response_verify_puks, NULL);
2304 tcore_pending_link_user_request(pending, ur);
2306 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2308 tcore_hal_send_request(h, pending);
2312 return TCORE_RETURN_SUCCESS;
2315 static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
2317 TcorePlugin *p = NULL;
2319 TcorePending *pending = NULL;
2321 const struct treq_sim_change_pins *req_data;
2322 struct s_sim_property *sp = NULL;
2325 char *cmd_str = NULL;
2328 return TCORE_RETURN_EINVAL;
2330 p = tcore_object_ref_plugin(o);
2331 h = tcore_object_get_hal(o);
2332 req_data = tcore_user_request_ref_data(ur, NULL);
2333 sp = tcore_sim_ref_userdata(o);
2335 if(req_data->type == SIM_PTYPE_PIN1) {
2336 sp->current_sec_op = SEC_PIN1_CHANGE;
2338 else if(req_data->type == SIM_PTYPE_PIN2) {
2339 sp->current_sec_op = SEC_PIN2_CHANGE;
2342 return TCORE_RETURN_EINVAL;
2345 sp->metainfo.type = NO_RESULT;
2346 sp->metainfo.responsePrefix[0] = '\0';
2348 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), sp);
2351 // AT+CPIN=<pin>[,<newpin>]
2352 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"%s", req_data->old_pin, req_data->new_pin, "\r");
2354 dbg("new pending(IPC_SEC_CHANGE_LOCKING_PW SET)");
2355 pending = tcore_pending_new(o, ID_RESERVED_AT);
2356 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2357 tcore_pending_set_timeout(pending, 0);
2358 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2359 tcore_pending_set_response_callback(pending, on_response_change_pins, NULL);
2360 tcore_pending_link_user_request(pending, ur);
2362 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2364 tcore_hal_send_request(h, pending);
2368 return TCORE_RETURN_SUCCESS;
2371 static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
2373 TcorePlugin *p = NULL;
2375 TcorePending *pending = NULL;
2376 struct s_sim_property sec_meta = {0,};
2379 const struct treq_sim_get_facility_status *req_data;
2381 int mode = 2; // 2:query, 0: unlock, 1:lock
2383 char *cmd_str = NULL;
2384 // struct ATReqMetaInfo metainfo;
2387 return TCORE_RETURN_EINVAL;
2389 p = tcore_object_ref_plugin(o);
2390 h = tcore_object_get_hal(o);
2391 req_data = tcore_user_request_ref_data(ur, NULL);
2393 if(req_data->type == SIM_FACILITY_PS)
2395 else if(req_data->type == SIM_FACILITY_SC)
2397 else if(req_data->type == SIM_FACILITY_FD)
2399 else if(req_data->type == SIM_FACILITY_PN)
2401 else if(req_data->type == SIM_FACILITY_PU)
2403 else if(req_data->type == SIM_FACILITY_PP)
2405 else if(req_data->type == SIM_FACILITY_PC)
2408 return TCORE_RETURN_EINVAL;
2410 sec_meta.current_sec_op = req_data->type;
2411 sec_meta.metainfo.type = SINGLELINE;
2412 memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
2414 trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
2417 // AT+CLCK=<fac>,<mode>,<password>
2418 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d%s", fac, mode, "\r");
2420 dbg("new pending(IPC_SEC_PHONE_LOCK GET)");
2421 pending = tcore_pending_new(o, ID_RESERVED_AT);
2422 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2423 tcore_pending_set_timeout(pending, 0);
2424 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2425 tcore_pending_set_response_callback(pending, on_response_get_facility_status, NULL);
2426 tcore_pending_link_user_request(pending, ur);
2428 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2430 tcore_hal_send_request(h, pending);
2434 return TCORE_RETURN_SUCCESS;
2437 static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
2439 TcorePlugin *p = NULL;
2441 TcorePending *pending = NULL;
2442 struct s_sim_property sec_meta = {0,};
2443 const struct treq_sim_enable_facility *req_data;
2444 struct s_sim_property *sp = NULL;
2446 int mode = 1; // 2:query, 0: unlock, 1:lock
2448 char *cmd_str = NULL;
2449 // struct ATReqMetaInfo metainfo;
2452 return TCORE_RETURN_EINVAL;
2454 p = tcore_object_ref_plugin(o);
2455 h = tcore_object_get_hal(o);
2456 req_data = tcore_user_request_ref_data(ur, NULL);
2457 sp = tcore_sim_ref_userdata(o);
2459 if (req_data->type == SIM_FACILITY_PS)
2461 else if (req_data->type == SIM_FACILITY_SC)
2463 else if (req_data->type == SIM_FACILITY_FD)
2465 else if (req_data->type == SIM_FACILITY_PN)
2467 else if (req_data->type == SIM_FACILITY_PU)
2469 else if (req_data->type == SIM_FACILITY_PP)
2471 else if (req_data->type == SIM_FACILITY_PC)
2474 return TCORE_RETURN_EINVAL;
2476 sp->current_sec_op = SEC_SIM_ENABLE;
2478 sec_meta.current_sec_op = req_data->type;
2479 sec_meta.metainfo.type = SINGLELINE;
2480 memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
2482 tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
2484 // AT+CLCK=<fac>,<mode>,<password>
2485 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, %s%s", fac, mode, req_data->password,"\r");
2486 dbg("new pending(enable_facility), %s", cmd_str);
2488 pending = tcore_pending_new(o, ID_RESERVED_AT);
2489 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2490 tcore_pending_set_timeout(pending, 0);
2491 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2492 tcore_pending_set_response_callback(pending, on_response_enable_facility, NULL);
2493 tcore_pending_link_user_request(pending, ur);
2495 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2497 tcore_hal_send_request(h, pending);
2501 return TCORE_RETURN_SUCCESS;
2504 static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
2506 TcorePlugin *p = NULL;
2508 TcorePending *pending = NULL;
2509 struct s_sim_property sec_meta = {0,};
2510 const struct treq_sim_enable_facility *req_data;
2511 struct s_sim_property *sp = NULL;
2513 int mode = 0; // 2:query, 0: unlock, 1:lock
2515 char *cmd_str = NULL;
2516 // struct ATReqMetaInfo metainfo;
2519 return TCORE_RETURN_EINVAL;
2521 p = tcore_object_ref_plugin(o);
2522 h = tcore_object_get_hal(o);
2523 req_data = tcore_user_request_ref_data(ur, NULL);
2524 sp = tcore_sim_ref_userdata(o);
2526 if (req_data->type == SIM_FACILITY_PS)
2528 else if (req_data->type == SIM_FACILITY_SC)
2530 else if (req_data->type == SIM_FACILITY_FD)
2532 else if (req_data->type == SIM_FACILITY_PN)
2534 else if (req_data->type == SIM_FACILITY_PU)
2536 else if (req_data->type == SIM_FACILITY_PP)
2538 else if (req_data->type == SIM_FACILITY_PC)
2541 return TCORE_RETURN_EINVAL;
2543 sp->current_sec_op = SEC_SIM_ENABLE;
2545 sec_meta.current_sec_op = req_data->type;
2546 sec_meta.metainfo.type = SINGLELINE;
2547 memcpy(sec_meta.metainfo.responsePrefix,"+CLCK:",strlen("+CLCK:"));
2549 tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &sec_meta);
2551 // AT+CLCK=<fac>,<mode>,<password>
2552 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, %s%s", fac, mode, req_data->password,"\r");
2553 dbg("new pending(enable_facility), %s", cmd_str);
2555 pending = tcore_pending_new(o, ID_RESERVED_AT);
2556 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
2557 tcore_pending_set_timeout(pending, 0);
2558 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2559 tcore_pending_set_response_callback(pending, on_response_disable_facility, NULL);
2560 tcore_pending_link_user_request(pending, ur);
2562 tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
2564 tcore_hal_send_request(h, pending);
2568 return TCORE_RETURN_SUCCESS;
2571 static TReturn s_read_file(CoreObject *o, UserRequest *ur)
2573 TReturn api_ret = TCORE_RETURN_SUCCESS;
2574 enum tcore_request_command command;
2575 command = tcore_user_request_get_command(ur);
2580 case TREQ_SIM_GET_ECC:
2581 api_ret = _get_file_info(o, ur, SIM_EF_ECC);
2584 case TREQ_SIM_GET_LANGUAGE:
2585 if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
2586 api_ret = _get_file_info(o, ur, SIM_EF_ELP);
2587 else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
2588 api_ret = _get_file_info(o, ur, SIM_EF_LP);
2590 api_ret = TCORE_RETURN_ENOSYS;
2593 case TREQ_SIM_GET_ICCID:
2594 api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
2597 case TREQ_SIM_GET_MAILBOX:
2598 if(tcore_sim_get_cphs_status(o))
2599 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
2601 api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
2604 case TREQ_SIM_GET_CALLFORWARDING:
2605 if(tcore_sim_get_cphs_status(o))
2606 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
2608 api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
2611 case TREQ_SIM_GET_MESSAGEWAITING:
2612 if(tcore_sim_get_cphs_status(o))
2613 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
2615 api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
2618 case TREQ_SIM_GET_CPHS_INFO:
2619 if(tcore_sim_get_cphs_status(o))
2620 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
2622 api_ret = TCORE_RETURN_ENOSYS;
2625 case TREQ_SIM_GET_MSISDN:
2626 api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
2629 case TREQ_SIM_GET_SPN:
2630 dbg("enter case SPN");
2631 api_ret = _get_file_info(o, ur, SIM_EF_SPN);
2634 case TREQ_SIM_GET_SPDI:
2635 api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
2638 case TREQ_SIM_GET_OPL:
2639 api_ret = _get_file_info(o, ur, SIM_EF_OPL);
2642 case TREQ_SIM_GET_PNN:
2643 api_ret = _get_file_info(o, ur, SIM_EF_PNN);
2646 case TREQ_SIM_GET_CPHS_NETNAME:
2647 api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
2650 case TREQ_SIM_GET_OPLMNWACT:
2651 api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
2655 dbg("error - not handled read treq command[%d]", command);
2656 api_ret = TCORE_RETURN_EINVAL;
2662 static TReturn s_update_file(CoreObject *o, UserRequest *ur)
2664 TReturn api_ret = TCORE_RETURN_ENOSYS;
2668 static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
2670 dbg("need to be implemented to use ATCMD");
2672 return TCORE_RETURN_SUCCESS;
2675 static TReturn s_get_atr(CoreObject *o, UserRequest *ur)
2677 dbg("need to be implemented to use ATCMD");
2679 return TCORE_RETURN_SUCCESS;
2682 static TReturn s_req_authentication(CoreObject *o, UserRequest *ur)
2684 return TCORE_RETURN_SUCCESS;
2687 static struct tcore_sim_operations sim_ops =
2689 .verify_pins = s_verify_pins,
2690 .verify_puks = s_verify_puks,
2691 .change_pins = s_change_pins,
2692 .get_facility_status = s_get_facility_status,
2693 .enable_facility = s_enable_facility,
2694 .disable_facility = s_disable_facility,
2695 .read_file = s_read_file,
2696 .update_file = s_update_file,
2697 .transmit_apdu = s_transmit_apdu,
2698 .get_atr = s_get_atr,
2699 .req_authentication = s_req_authentication
2702 gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
2705 struct s_sim_property *sp = NULL;
2707 o = tcore_sim_new(p, "sim", &sim_ops, h);
2711 sp = calloc(sizeof(struct s_sim_property),1);
2715 sp->first_recv_status = SIM_STATUS_UNKNOWN;
2716 tcore_sim_link_userdata(o, sp);
2718 tcore_object_add_callback(o, EVENT_SIM_PIN_STATUS, on_event_pin_status, NULL);
2723 void s_sim_exit(TcorePlugin *p)
2727 o = tcore_plugin_ref_core_object(p, "sim");