TEE_Result syscall_se_channel_close(unsigned long channel_handle) { TEE_Result ret; struct tee_se_channel *c = tee_svc_uref_to_kaddr(channel_handle); struct tee_ta_session *sess; struct tee_se_session *s; struct tee_se_service *service; ret = tee_ta_get_current_session(&sess); if (ret != TEE_SUCCESS) return ret; service = to_user_ta_ctx(sess->ctx)->se_service; if (!tee_se_service_is_channel_valid(service, c)) return TEE_ERROR_BAD_PARAMETERS; s = tee_se_channel_get_session(c); tee_se_session_close_channel(s, c); return TEE_SUCCESS; }
static TEE_Result internal_select(struct tee_se_channel *c, struct tee_se_aid *aid, int select_ops) { struct cmd_apdu *cmd; struct resp_apdu *resp; struct tee_se_session *s; TEE_Result ret; TEE_SEReaderProperties prop; size_t rx_buf_len = 0; int channel_id; uint8_t cla_channel; assert(c); s = tee_se_channel_get_session(c); channel_id = tee_se_channel_get_id(c); if (channel_id >= MAX_LOGICAL_CHANNEL) panic("invalid channel id"); cla_channel = iso7816_get_cla_channel(channel_id); if (select_ops == FIRST_OR_ONLY_OCCURRENCE) { assert(aid); cmd = alloc_cmd_apdu(ISO7816_CLA | cla_channel, SELECT_CMD, SELECT_BY_AID, select_ops, aid->length, rx_buf_len, aid->aid); } else { cmd = alloc_cmd_apdu(ISO7816_CLA | cla_channel, SELECT_CMD, SELECT_BY_AID, select_ops, 0, rx_buf_len, NULL); } resp = alloc_resp_apdu(rx_buf_len); ret = tee_se_session_transmit(s, cmd, resp); if (ret != TEE_SUCCESS) { EMSG("exchange apdu failed: %d", ret); return ret; } tee_se_reader_get_properties(s->reader_proxy, &prop); if (prop.selectResponseEnable) tee_se_channel_set_select_response(c, resp); if (aid) tee_se_channel_set_aid(c, aid); if (resp->sw1 == CMD_OK_SW1 && resp->sw2 == CMD_OK_SW2) { ret = TEE_SUCCESS; } else { EMSG("operation failed, sw1:%02X, sw2:%02X", resp->sw1, resp->sw2); if (resp->sw1 == 0x6A && resp->sw2 == 0x83) ret = TEE_ERROR_ITEM_NOT_FOUND; else ret = TEE_ERROR_NOT_SUPPORTED; } apdu_release(to_apdu_base(cmd)); apdu_release(to_apdu_base(resp)); return ret; }