/*
 * Copyright(C) 2000 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/*!
 * \file $RCSfile$
 * \version $Revision: 150304 $
 * \date $Date:: 2016-12-16 17:05:23 +0300#$
 * \author $Author: sagafyin $
 * \brief Функция выбора файла.
 */

#include "ric_prj.h"
#include "limits.h" 

static const unsigned char OSCAR2_FILE_COMMON[2] = { 3, 6 };

/*!
 * \brief Функция выбора файла.
 */
DWORD ric_select_file( 
    TRICContext *ctx,
    unsigned char file_id, 
    size_t *length )
{
    BYTE apdu_sel[] = { 0, 0xA4, 00, 0x04 };
    TSCardInfoBerTLVSearch search = { 0x3, 0x2, 0x80, {0,0}, {0,0} };
    unsigned char data[2];
    unsigned char simple[2];
    DWORD code;
    size_t tmp_out_len = MAX_APDU_LEN;
    search.class_tag = ctx->class_tag;
    *length = 0xffff;
    if (ctx->card_type == CardType_OSCAR2) {
	unsigned char file_id_new = 0;
	if( file_id > 6 || file_id == 0 )
	    return (DWORD)ERROR_FILE_NOT_FOUND;
	file_id_new = OSCAR2_FILE_COMMON[OSCAR2_FILE_INDEX[file_id - 1]];

	data[0] = (unsigned char)(( file_id_new + ctx->application ) >> 8 );
	data[1] = (unsigned char)(( file_id_new + ctx->application ) &0xff );
    }
    else if (ctx->card_type == CardType_RIC) {
	data[0] = (unsigned char)(( file_id + ctx->application ) >> 8 );
	data[1] = (unsigned char)(( file_id + ctx->application ) &0xff );
    }
    search.input.info = malloc(tmp_out_len);
    if (!search.input.info)
	return (DWORD)NTE_NO_MEMORY;
    code = send_apdu(ctx, apdu_sel, data, sizeof (data), search.input.info, &tmp_out_len);
    if (code)
    {
	free(search.input.info);
	return code;
    }
    search.input.length = tmp_out_len;
    search.output.length = 2;
    search.output.info = simple;
    code = ctx->ber_tlv_search( &search );
    free( search.input.info );
    if( code )
	return (DWORD)SCARD_W_UNSUPPORTED_CARD;
    if( search.output.length > 2 || !search.output.length )
	return (DWORD)SCARD_W_UNSUPPORTED_CARD;
    *length = *search.output.info;
    if( search.output.length == 2 )
	*length = ( *length << 8 ) + search.output.info[1];
    if (ctx->card_type == CardType_OSCAR2) {
	code = oscar2_file_length(file_id, length, ctx->connect_name);
	if(code)
	    return code;
    }
    return ERROR_SUCCESS;
}
/* end of file: $Id: ricsf.c 150304 2016-12-16 14:05:23Z sagafyin $ */
