/*
 *  $Id: GCUSBTransport.c,v 1.6 2012/04/08 19:09:46 rousseau Exp $
 *  ifd-GemPC
 *
 *  Created by JL Giraud <jl.giraud@free.fr> on Sun Nov 19 2000.
 *  Updated by Ludovic Rousseau <ludovic.rousseau@free.fr>, Oct 2001
 *
 *  Transport level for the GemPC430 of Gemplus.
 *
 *  License:   See file COPYING
 *
 */

#include <string.h>

#include "gempc_ifdhandler.h"
#include "Config.h"
#include "GCTransport.h"
#include "usbserial.h"


status_t GCSendCommand(DWORD Lun, DWORD nLengthIn,
	const UCHAR pcBufferCmd[], PDWORD pnLengthOut, UCHAR pcBufferOut[])
{
    UCHAR pctr_to_card_buffer[GC_TR_BUF_SIZE];
    status_t creturn_value;
    DWORD nlength;

    creturn_value = STATUS_SUCCESS;

    if (GC_TR_BUF_SIZE <= nLengthIn)
    {
        /* Buffer is too small (should not happen) */
        creturn_value = STATUS_DEVICE_PROTOCOL_ERROR;
        goto finally;
    }

    memcpy(pctr_to_card_buffer+1, pcBufferCmd, nLengthIn);
    pctr_to_card_buffer[TR_OFFSET_LNG] = nLengthIn;
    if (WriteUSB(Lun, nLengthIn+1, pctr_to_card_buffer) != STATUS_SUCCESS)
    {
        creturn_value = STATUS_DEVICE_PROTOCOL_ERROR;
        goto finally;
    }

    nlength = sizeof(pctr_to_card_buffer);
    if (ReadUSB(Lun, &nlength, pctr_to_card_buffer) != STATUS_SUCCESS)
    {
        creturn_value = STATUS_DEVICE_PROTOCOL_ERROR;
        goto finally;
    }
    if ( nlength < 1 )
    {
        /* length byte not received */
        creturn_value = STATUS_DEVICE_PROTOCOL_ERROR;
        goto finally;
    }
    nlength--;
    *pnLengthOut = (*pnLengthOut<nlength) ? *pnLengthOut : nlength;
    memcpy(pcBufferOut, pctr_to_card_buffer+1, *pnLengthOut);

finally:
    if ( creturn_value != STATUS_SUCCESS )
        *pnLengthOut = 0;

    /* Clear buffer */
    bzero(pctr_to_card_buffer, sizeof(pctr_to_card_buffer));

    return creturn_value;
} /* GCSendCommand */

