tmp = util_removeQuotes(hexData);
recordData = util_hexStringToBytes(tmp);
util_hex_dump(" ", strlen(hexData) / 2, recordData);
- free(tmp);
+ g_free(tmp);
ptr_data = (unsigned char *)recordData;
if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
} else {
dbg("INVALID FCP received - DEbug!");
tcore_at_tok_free(tokens);
- free(recordData);
+ g_free(recordData);
return;
}
} else {
dbg("INVALID FCP received - DEbug!");
tcore_at_tok_free(tokens);
- free(recordData);
+ g_free(recordData);
return;
}
} else {
dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
tcore_at_tok_free(tokens);
- free(recordData);
+ g_free(recordData);
return;
}
} else {
dbg("INVALID FCP received - DEbug!");
tcore_at_tok_free(tokens);
- free(recordData);
+ g_free(recordData);
return;
}
} else {
dbg("INVALID FCP received - DEbug!");
tcore_at_tok_free(tokens);
- free(recordData);
+ g_free(recordData);
return;
}
} else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
file_meta->rec_count = num_of_records;
file_meta->current_index = 0; // reset for new record type EF
rt = SIM_ACCESS_SUCCESS;
- free(recordData);
+ g_free(recordData);
} else {
/*2. SIM access fail case*/
dbg("error to get ef[0x%x]", file_meta->file_id);
tmp = util_removeQuotes(res);
res = util_hexStringToBytes(tmp);
- res_len = strlen((const char *)res);
+ res_len = strlen(tmp) / 2;
dbg("Response: [%s] Response length: [%d]", res, res_len);
if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
return TCORE_RETURN_SUCCESS;
}
-
static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
{
struct s_sim_property *sp = NULL;
return TRUE;
}
+static void notify_sms_state(TcorePlugin *plugin, CoreObject *co_sim,
+ gboolean sms_ready)
+{
+ Server *server = tcore_plugin_ref_server(plugin);
+ struct tnoti_sms_ready_status sms_ready_noti;
+ CoreObject *co_sms;
+
+ dbg("Entry");
+
+ co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+ if (co_sms == NULL) {
+ err("Can't find SMS core object");
+ return;
+ }
+
+ if (tcore_sms_get_ready_status(co_sms) == sms_ready)
+ return;
+
+ tcore_sms_set_ready_status(co_sms, sms_ready);
+
+ if (tcore_sim_get_status(co_sim) == SIM_STATUS_INIT_COMPLETED) {
+ sms_ready_noti.status = sms_ready;
+ tcore_server_send_notification(server, co_sms,
+ TNOTI_SMS_DEVICE_READY,
+ sizeof(sms_ready_noti),
+ &sms_ready_noti);
+ }
+
+ dbg("Exit");
+}
static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
{
- struct s_sim_property *sp = NULL;
+ TcorePlugin *plugin = tcore_object_ref_plugin(o);
enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
GSList *tokens = NULL;
- GSList *lines = NULL;
- const char *line = NULL;
+ GSList *lines;
+ const char *line;
int sim_state = 0;
int sms_state = 0;
dbg("Entry");
- sp = tcore_sim_ref_userdata(o);
-
lines = (GSList *)event_info;
if (g_slist_length(lines) != 1) {
err("Unsolicited message BUT multiple lines");
- goto OUT;
+ goto out;
}
- line = (char *)(lines->data);
+
+ line = lines->data;
/* Create 'tokens' */
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) == 4) {
sim_state = atoi(g_slist_nth_data(tokens, 1));
sms_state = atoi(g_slist_nth_data(tokens, 3));
- } else if (g_slist_length(tokens) == 1)
+ notify_sms_state(plugin, o, (sms_state > 0));
+ } else if (g_slist_length(tokens) == 1) {
sim_state = atoi(g_slist_nth_data(tokens, 0));
- else {
+ } else {
err("Invalid message");
-
- /* Free 'tokens' */
- tcore_at_tok_free(tokens);
- return TRUE;
+ goto out;
}
switch (sim_state) {
- case 0: /* SIM NOT PRESENT */
+ case 0:
sim_status = SIM_STATUS_CARD_NOT_PRESENT;
dbg("NO SIM");
- break;
+ break;
- case 1: /* PIN VERIFICATION NEEDED */
+ case 1:
sim_status = SIM_STATUS_PIN_REQUIRED;
dbg("PIN REQUIRED");
- break;
+ break;
- case 2: /* PIN VERIFICATION NOT NEEDED \96 READY */
+ case 2:
sim_status = SIM_STATUS_INITIALIZING;
dbg("PIN DISABLED AT BOOT UP");
- break;
+ break;
- case 3: /* PIN VERIFIED \96 READY */
+ case 3:
sim_status = SIM_STATUS_INITIALIZING;
dbg("PIN VERIFIED");
- break;
+ break;
- case 4: /* PUK VERIFICATION NEEDED */
+ case 4:
sim_status = SIM_STATUS_PUK_REQUIRED;
- dbg("PUK REQUIED");
- break;
+ dbg("PUK REQUIRED");
+ break;
- case 5: /* SIM PERMANENTLY BLOCKED */
+ case 5:
sim_status = SIM_STATUS_CARD_BLOCKED;
dbg("CARD PERMANENTLY BLOCKED");
- break;
+ break;
- case 6: /* SIM ERROR */
+ case 6:
sim_status = SIM_STATUS_CARD_ERROR;
dbg("SIM CARD ERROR");
break;
- case 7: /* SIM READY FOR ATTACH (+COPS) */
+ case 7:
sim_status = SIM_STATUS_INIT_COMPLETED;
dbg("SIM INIT COMPLETED");
- break;
+ break;
- case 8: /* SIM TECHNICAL PROBLEM */
+ case 8:
sim_status = SIM_STATUS_CARD_ERROR;
dbg("SIM CARD ERROR");
- break;
+ break;
- case 9: /* SIM REMOVED */
+ case 9:
sim_status = SIM_STATUS_CARD_REMOVED;
dbg("SIM REMOVED");
- break;
+ break;
- case 99: /* SIM STATE UNKNOWN */
+ case 12:
+ dbg("SIM SMS Ready");
+ notify_sms_state(plugin, o, TRUE);
+ goto out;
+
+ case 99:
sim_status = SIM_STATUS_UNKNOWN;
dbg("SIM STATE UNKNOWN");
- break;
-
- case 12: /* SIM SMS CACHING COMPLETED */
- {
- struct tnoti_sms_ready_status sms_ready_noti = {0, };
- CoreObject *sms;
- TcorePlugin *plugin;
-
- dbg("SIM State: [%d] - SMS Ready", sim_state);
-
- sms_ready_noti.status = TRUE;
- plugin = tcore_object_ref_plugin(o);
- dbg("Plug-in name: [%s] SMS State: [%s]",
- tcore_plugin_ref_plugin_name(plugin),
- sms_ready_noti.status ? "TRUE" : "FALSE");
-
- /* Set SMS State to Ready */
- sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
- tcore_sms_set_ready_status(sms, sms_ready_noti.status);
-
- /* Send notification - SMS Ready */
- tcore_server_send_notification(tcore_plugin_ref_server(plugin), sms,
- TNOTI_SMS_DEVICE_READY, sizeof(sms_ready_noti), &sms_ready_noti);
-
- goto OUT;
- }
+ break;
default:
err("Unknown/Unsupported SIM state: [%d]", sim_state);
- break;
+ goto out;
}
switch (sim_status) {
case SIM_STATUS_INIT_COMPLETED:
dbg("[SIM] SIM INIT COMPLETED");
if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
- /* Get SIM Type */
_get_sim_type(o);
-
- goto OUT;
+ goto out;
}
- break;
-
- case SIM_STATUS_INITIALIZING:
- dbg("[SIM] SIM CARD INITIALIZING");
- break;
- case SIM_STATUS_PIN_REQUIRED:
- dbg("[SIM] PIN REQUIRED");
- break;
-
- case SIM_STATUS_PUK_REQUIRED:
- dbg("[SIM] PUK REQUIRED");
- break;
-
- case SIM_STATUS_CARD_BLOCKED:
- dbg("[SIM] SIM CARD BLOCKED");
- break;
-
- case SIM_STATUS_NCK_REQUIRED:
- dbg("[SIM] NCK REQUIRED");
- break;
-
- case SIM_STATUS_NSCK_REQUIRED:
- dbg("[SIM] NSCK REQUIRED");
- break;
-
- case SIM_STATUS_SPCK_REQUIRED:
- dbg("[SIM] SPCK REQUIRED");
- break;
-
- case SIM_STATUS_CCK_REQUIRED:
- dbg("[SIM] CCK REQUIRED");
- break;
-
- case SIM_STATUS_LOCK_REQUIRED:
- dbg("[SIM] PHONE-SIM LOCK REQUIRED");
- break;
+ break;
case SIM_STATUS_CARD_REMOVED:
dbg("[SIM] SIM CARD REMOVED");
-
- /* Update SIM Type - UNKNOWN */
tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
+ break;
case SIM_STATUS_CARD_NOT_PRESENT:
dbg("[SIM] SIM CARD NOT PRESENT");
-
- /* Update SIM Type - UNKNOWN */
tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
+ break;
case SIM_STATUS_CARD_ERROR:
dbg("[SIM] SIM CARD ERROR");
-
- /* Update SIM Type - UNKNOWN */
tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
- break;
+ break;
default:
- err("Not handled SIM State: [0x%02x]", sim_status);
- goto OUT;
+ dbg("SIM Status: [0x%02x]", sim_status);
+ break;
}
- /* Update SIM State */
_sim_status_update(o, sim_status);
-OUT:
- /* Free tokens */
+out:
tcore_at_tok_free(tokens);
dbg("Exit");
decoded_data = util_hexStringToBytes(tmp);
memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
- free(tmp);
- free(decoded_data);
+ g_free(tmp);
+ g_free(decoded_data);
res.result = SIM_ACCESS_SUCCESS;
}
} else {
tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
decoded_data = util_hexStringToBytes(tmp);
- res.atr_length = strlen(decoded_data);
+ res.atr_length = strlen(tmp) / 2;
memcpy((char *)res.atr, decoded_data, res.atr_length);
- free(tmp);
- free(decoded_data);
+ g_free(tmp);
+ g_free(decoded_data);
res.result = SIM_ACCESS_SUCCESS;
}
} else {
dbg("Exit");
}
+static void on_response_req_authentication(TcorePending *p, int data_len,
+ const void *data, void *user_data)
+{
+ const TcoreATResponse *at_resp = data;
+ GSList *tokens = NULL;
+ struct tresp_sim_req_authentication resp_auth;
+ const struct treq_sim_req_authentication *req_data;
+ UserRequest *ur = tcore_pending_ref_user_request(p);
+
+ dbg("Entry");
+
+ memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
+
+ if (at_resp == NULL) {
+ err("at_resp is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ if (req_data == NULL) {
+ err("req_data is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ resp_auth.auth_type = req_data->auth_type;
+
+ if (at_resp->success == TRUE) {
+ const char *line;
+ int status;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines != NULL) {
+ line = at_resp->lines->data;
+ dbg("Received data: [%s]", line);
+ } else {
+ err("at_resp->lines is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ status = atoi(g_slist_nth_data(tokens, 0));
+ switch (status) {
+ case 0:
+ dbg("Authentications successful");
+ resp_auth.auth_result = SIM_AUTH_NO_ERROR;
+ break;
+ case 1:
+ err("Synchronize fail");
+ resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
+ goto out;
+ case 2:
+ err("MAC wrong");
+ resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
+ goto out;
+ case 3:
+ err("Does not support security context");
+ resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
+ goto out;
+ default:
+ err("Other failure");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
+ char *kc, *sres;
+ char *convert_kc, *convert_sres;
+
+ kc = g_slist_nth_data(tokens, 1);
+ if (kc != NULL) {
+ kc = tcore_at_tok_extract(kc);
+ dbg("Kc: [%s]", kc);
+ convert_kc = util_hexStringToBytes(kc);
+ if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.authentication_key_length = strlen(convert_kc);
+ memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
+ } else {
+ err("Invalid Kc");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(kc);
+ g_free(convert_kc);
+ } else {
+ err("Invalid Kc");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ sres = g_slist_nth_data(tokens, 2);
+ if (sres != NULL) {
+ sres = tcore_at_tok_extract(sres);
+ dbg("SRES: [%s]", sres);
+ convert_sres = util_hexStringToBytes(sres);
+ if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.resp_length = strlen(convert_sres);
+ memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
+ } else {
+ err("Invalid SRES");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(sres);
+ g_free(convert_sres);
+ } else {
+ err("Invalid SRES");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G) {
+ char *res, *ck, *ik, *kc;
+ char *convert_res, *convert_ck;
+ char *convert_ik, *convert_kc;
+
+ res = g_slist_nth_data(tokens, 1);
+ if (res != NULL) {
+ res = tcore_at_tok_extract(res);
+ dbg("RES/AUTS: [%s]", res);
+ convert_res = util_hexStringToBytes(res);
+ if (convert_ck && strlen(res) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.resp_length = strlen(convert_res);
+ memcpy(resp_auth.resp_data, convert_res, strlen(convert_res));
+ } else {
+ err("Invalid RES/AUTS");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(res);
+ g_free(convert_res);
+ } else {
+ err("Invalid RES/AUTS");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ ck = g_slist_nth_data(tokens, 2);
+ if (ck != NULL) {
+ ck = tcore_at_tok_extract(ck);
+ dbg("CK: [%s]", ck);
+ convert_ck = util_hexStringToBytes(ck);
+ if (convert_ck && strlen(ck) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.cipher_length = strlen(convert_ck);
+ memcpy(&resp_auth.cipher_data, convert_ck, strlen(convert_ck));
+ } else {
+ err("Invalid CK");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(ck);
+ g_free(convert_ck);
+ } else {
+ err("Invalid CK");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ ik = g_slist_nth_data(tokens, 3);
+ if (ik != NULL) {
+ ik = tcore_at_tok_extract(ik);
+ dbg("IK: [%s]", ik);
+ convert_ik = util_hexStringToBytes(ik);
+ if (convert_ik && strlen(ik) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.integrity_length = strlen(convert_ik);
+ memcpy(&resp_auth.integrity_data, convert_ik, strlen(convert_ik));
+ } else {
+ err("Invalid IK");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(ik);
+ g_free(convert_ik);
+ } else {
+ err("Invalid IK");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ kc = g_slist_nth_data(tokens, 4);
+ if (kc != NULL) {
+ kc = tcore_at_tok_extract(kc);
+ dbg("Kc: [%s]", kc);
+ convert_kc = util_hexStringToBytes(kc);
+ if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.authentication_key_length = strlen(convert_kc);
+ memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
+ } else {
+ err("Invalid Kc");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(kc);
+ g_free(convert_kc);
+ } else {
+ err("Invalid Kc");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ } else if (resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
+ err("Not supported");
+ }
+ } else {
+ err("RESPONSE NOK");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+
+out:
+ tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
+ sizeof(struct tresp_sim_req_authentication), &resp_auth);
+
+ tcore_at_tok_free(tokens);
+}
+
static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
{
TcoreHal *hal = NULL;
NULL, NULL);
}
+static TReturn s_req_authentication(CoreObject *co, UserRequest *ur)
+{
+ const struct treq_sim_req_authentication *req_data;
+ char *cmd_str = NULL;
+ enum tel_sim_type sim_type;
+ int session_id;
+ int context_type;
+ TReturn ret = TCORE_RETURN_FAILURE;
+ char *convert_rand = NULL;
+ char *convert_autn = NULL;
+
+ dbg("Entry");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ if (req_data == NULL) {
+ err("req_data is NULL");
+ return ret;
+ }
+
+ if (req_data->rand_data != NULL) {
+ convert_rand = util_hex_to_string(req_data->rand_data,
+ req_data->rand_length);
+ dbg("Convert RAND hex to string: [%s]", convert_rand);
+ } else {
+ err("rand_data is NULL");
+ return ret;
+ }
+
+ sim_type = tcore_sim_get_type(co);
+ switch (sim_type) {
+ case SIM_TYPE_GSM:
+ case SIM_TYPE_USIM:
+ session_id = 0;
+ break;
+ default:
+ err("Not supported");
+ ret = TCORE_RETURN_ENOSYS;
+ goto out;
+ }
+
+ switch (req_data->auth_type) {
+ case SIM_AUTH_TYPE_GSM:
+ context_type = 2;
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"", session_id,
+ context_type, convert_rand);
+ break;
+ case SIM_AUTH_TYPE_3G:
+ context_type = 1;
+ if (req_data->autn_data != NULL) {
+ convert_autn = util_hex_to_string(req_data->autn_data,
+ req_data->autn_length);
+ dbg("Convert AUTN hex to string: [%s]", convert_autn);
+ } else {
+ err("autn_data is NULL");
+ goto out;
+ }
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
+ session_id, context_type,
+ convert_rand, convert_autn);
+ break;
+ default:
+ err("Not supported");
+ ret = TCORE_RETURN_ENOSYS;
+ goto out;
+ }
+
+ ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
+ TCORE_AT_SINGLELINE, ur,
+ on_response_req_authentication, NULL, NULL, NULL);
+
+out:
+ g_free(cmd_str);
+ g_free(convert_rand);
+ g_free(convert_autn);
+
+ return ret;
+}
+
/* SIM Operations */
static struct tcore_sim_operations sim_ops = {
.verify_pins = s_verify_pins,
.update_file = s_update_file,
.transmit_apdu = s_transmit_apdu,
.get_atr = s_get_atr,
- .req_authentication = NULL,
+ .req_authentication = s_req_authentication,
};
gboolean s_sim_init(TcorePlugin *cp, CoreObject *co_sim)