Esempio n. 1
0
/**
  * @brief  Transmission by T=1 Character Mode
  * @param  portno			Indicate which port to open (0:Port0; 1:Port1)
  * @param  pBlockBuffer	Command Data
  * @param  pBlockSize		The size of command data
  * @param  AnswerSize		Expected size of received data
  * @retval Slot Status Error Code
  */
unsigned char Ifd_XfrCharT1(	int32_t portno,
									unsigned char *pBlockBuffer,
									unsigned int *pBlockSize,
									unsigned int AnswerSize	)
{
	int32_t ErrorCode;
	uint8_t rbuf[MIN_BUFFER_SIZE];
	uint32_t idx, rlen;
	S_SC_DEV_T *dev;
	
	dev =  (S_SC_DEV_T *)((uint32_t)&sc_device[portno]);

	ErrorCode = CBRawTransmit( dev, pBlockBuffer, *pBlockSize, AnswerSize, &rbuf[0], &rlen);
	if(ErrorCode != SC_STATUS_SUCCESS)
		return Ifd_SC2CCIDErrorCode(ErrorCode);
	// received data
	for(idx=0; idx<rlen; idx++) 
	{
		*pBlockBuffer = rbuf[idx];
		pBlockBuffer++;
	}
	// length of received data
	*pBlockSize = rlen;

	return SLOT_NO_ERROR;

}
Esempio n. 2
0
NTSTATUS
CBTransmit(
          PSMARTCARD_EXTENSION SmartcardExtension
          )
/*++

CBTransmit:
        callback handler for SMCLIB RDF_TRANSMIT

Arguments:
        SmartcardExtension      context of call

Return Value:
        STATUS_SUCCESS
        STATUS_NO_MEDIA
        STATUS_TIMEOUT
        STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS  NTStatus = STATUS_SUCCESS;

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBTransmit: Enter\n" )
                  );

        //      dispatch on the selected protocol
    switch ( SmartcardExtension->CardCapabilities.Protocol.Selected ) {
    case SCARD_PROTOCOL_T0:
        NTStatus = CBT0Transmit( SmartcardExtension );
        break;

    case SCARD_PROTOCOL_T1:
        NTStatus = CBT1Transmit( SmartcardExtension );
        break;

    case SCARD_PROTOCOL_RAW:
        NTStatus = CBRawTransmit( SmartcardExtension );
        break;

    default:
        NTStatus = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBTransmit: Exit (%lx)\n", NTStatus )
                  );

    return( NTStatus );
}
Esempio n. 3
0
/**
  * @brief  Transmission by T=0 Extend APDU Mode
  * @param  portno			Indicate which port to open (0:Port0; 1:Port1)
  * @param  pBlockBuffer	Command Data
  * @param  pBlockSize		The size of command data
  * @retval Slot Status Error Code
  */
unsigned char Ifd_XfrExtendApduT0(	int32_t portno,
												unsigned char *pBlockBuffer,
												unsigned int *pBlockSize	)
{
	int32_t ErrorCode, idx;
	uint8_t rbuf[MIN_BUFFER_SIZE];
	uint32_t datalength, rlen;
	S_SC_DEV_T *dev;
	unsigned char getresponsebuf[5];
	unsigned char envelopebuf[300];	// 255 bytes + 5 command data
	dev =  (S_SC_DEV_T *)((uint32_t)&sc_device[portno]);


	if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x01)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;

		while(datalength)
		{
			envelopebuf[0] = USB_ConfigDescriptor[49+18];		// CLA = bClassEnvelope field
			envelopebuf[1] = 0xC2;							// 0xC2 = Envelope command
			envelopebuf[2] = 0x00;							// 0x00
			envelopebuf[3] = 0x00;							// 0x00
			if(datalength >= 0xFF)
				envelopebuf[4] = 0xFF;						// APDU length > buffer length
			else
				envelopebuf[4] = datalength;					// APDU length > buffer length

			if(datalength >= 0xFF) {
				for(idx=0; idx < 0xFF; idx++)
					envelopebuf[idx + 5] = pBlockBuffer[idx];
			} else {
				for(idx=0; idx < datalength; idx++)
					envelopebuf[idx + 5] = pBlockBuffer[idx];
			}

			if(datalength >= 0xFF)
				ErrorCode = CBT0Transmit( dev, &envelopebuf[0], 0x5+0xFF, &rbuf[0], &rlen);
			else
				ErrorCode = CBT0Transmit( dev, &envelopebuf[0], 0x5+datalength, &rbuf[0], &rlen);
			if(ErrorCode != SC_STATUS_SUCCESS)
				return Ifd_SC2CCIDErrorCode(ErrorCode);

			if(datalength >= 0xFF) {
				pBlockBuffer+=0xFF;
				datalength-=0xFF;
			} else
				datalength-=datalength;

		}
		
		// length of received data
		*pBlockSize = 0;

		// Chain Parameter Setting
		g_ChainParameter = 0x10;
	}
	
	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x02)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;
		
		envelopebuf[0] = USB_ConfigDescriptor[49+18];		// CLA = bClassEnvelope field
		envelopebuf[1] = 0xC2;							// 0xC2 = Envelope command
		envelopebuf[2] = 0x00;							// 0x00
		envelopebuf[3] = 0x00;							// 0x00
		envelopebuf[4] = datalength;						// last part of APDU command
		for(idx=0; idx < datalength; idx++)
			envelopebuf[idx + 5] = pBlockBuffer[idx];
		
		ErrorCode = CBT0Transmit( dev, &envelopebuf[0], 0x5+envelopebuf[4], &rbuf[0], &rlen);
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);

		// get response command
		getresponsebuf[0] = USB_ConfigDescriptor[48+18];	// CLA = bClassGetResponse field
		getresponsebuf[1] = 0xC0;							// 0xC0 = Get response command
		getresponsebuf[2] = 0x00;							// 0x00
		getresponsebuf[3] = 0x00;							// 0x00
		getresponsebuf[4] = 0x00;							// 0x00
		
		ErrorCode = CBT0Transmit( dev, &getresponsebuf[0], 0x5, &rbuf[0], &rlen);
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);
		// check if data bytes still available, max. size of buffer is 500 bytes
		//while(1)
		//{
			if((rlen==2) && (rbuf[0]==0x61))
			{
				getresponsebuf[0] = USB_ConfigDescriptor[48+18];	// CLA = bClassGetResponse field
				getresponsebuf[1] = 0xC0;							// 0xC0 == Get response command
				getresponsebuf[2] = 0x00;							// 0x00
				getresponsebuf[3] = 0x00;							// 0x00
				getresponsebuf[4] = rbuf[1];			// Licc = how many data bytes still available
				if(getresponsebuf[4]==0xFF) // TODO: care this point. NOT sure how to handle this
					ErrorCode = CBRawTransmit( dev, &getresponsebuf[0], 0x5, 0xFF, &rbuf[0], &rlen);
				else {
					ErrorCode = CBT0Transmit( dev, &getresponsebuf[0], 0x5, &rbuf[0], &rlen);
					printf("why available data is less than 0xff \n");
				}
				if(ErrorCode != SC_STATUS_SUCCESS)
					return Ifd_SC2CCIDErrorCode(ErrorCode);
			}
			
		//}

		// store received data
		pBlockBuffer = pBlockBuffer - 7;
		for(idx=0; idx<rlen; idx++)
			pBlockBuffer[idx] = rbuf[idx];
		
		// length of received data
		*pBlockSize = getresponsebuf[4];

		// Chain Parameter Setting
		g_ChainParameter = 0x01;
	}
	
	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x03)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;

		while(datalength)
		{
			envelopebuf[0] = USB_ConfigDescriptor[49+18];		// CLA = bClassEnvelope field
			envelopebuf[1] = 0xC2;							// 0xC2 = Envelope command
			envelopebuf[2] = 0x00;							// 0x00
			envelopebuf[3] = 0x00;							// 0x00
			if(datalength >= 0xFF)
				envelopebuf[4] = 0xFF;						// APDU length > buffer length
			else
				envelopebuf[4] = datalength;					// APDU length > buffer length

			if(datalength >= 0xFF) {
				for(idx=0; idx < 0xFF; idx++)
					envelopebuf[idx + 5] = pBlockBuffer[idx];
			} else {
				for(idx=0; idx < datalength; idx++)
					envelopebuf[idx + 5] = pBlockBuffer[idx];
			}

			if(datalength >= 0xFF)
				ErrorCode = CBT0Transmit( dev, &envelopebuf[0], 0x5+0xFF, &rbuf[0], &rlen);
			else
				ErrorCode = CBT0Transmit( dev, &envelopebuf[0], 0x5+datalength, &rbuf[0], &rlen);
			if(ErrorCode != SC_STATUS_SUCCESS)
				return Ifd_SC2CCIDErrorCode(ErrorCode);

			if(datalength >= 0xFF) {
				pBlockBuffer+=0xFF;
				datalength-=0xFF;
			} else
				datalength-=datalength;

		}
		
		// length of received data
		*pBlockSize = 0;

		// Chain Parameter Setting
		g_ChainParameter = 0x10;
	}

	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x10)
	{
		// get response command
		getresponsebuf[0] = USB_ConfigDescriptor[48+18];	// CLA = bClassGetResponse field
		getresponsebuf[1] = 0xC0;							// 0xC0 = Get response command
		getresponsebuf[2] = 0x00;							// 0x00
		getresponsebuf[3] = 0x00;							// 0x00
		getresponsebuf[4] = 0x00;							// 0x00
		
		ErrorCode = CBT0Transmit( dev, &getresponsebuf[0], 0x5, &rbuf[0], &rlen);
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);
		// check if data bytes still available, max. size of buffer is 500 bytes
		if((rlen==2) && (rbuf[0]==0x61))
		{
			getresponsebuf[0] = USB_ConfigDescriptor[48+18];	// CLA = bClassGetResponse field
			getresponsebuf[1] = 0xC0;							// 0xC0 == Get response command
			getresponsebuf[2] = 0x00;							// 0x00
			getresponsebuf[3] = 0x00;							// 0x00
			getresponsebuf[4] = rbuf[1];			// Licc = how many data bytes still available
			if(getresponsebuf[4]==0xFF)
				ErrorCode = CBRawTransmit( dev, &getresponsebuf[0], 0x5, 0xFF, &rbuf[0], &rlen);
			else
				ErrorCode = CBT0Transmit( dev, &getresponsebuf[0], 0x5, &rbuf[0], &rlen);
			if(ErrorCode != SC_STATUS_SUCCESS)
				return Ifd_SC2CCIDErrorCode(ErrorCode);
		}		

		// store received data
		for(idx=0; idx<rlen; idx++)
			pBlockBuffer[idx] = rbuf[idx];
		
		// length of received data
		if(getresponsebuf[4]==0xFF)
			*pBlockSize = getresponsebuf[4];
		else
			*pBlockSize = rlen;

		// Chain Parameter Setting
		if(getresponsebuf[4]==0xFF)
			g_ChainParameter = 0x03;
		else
			g_ChainParameter = 0x02;
	}

	return SLOT_NO_ERROR;

}
Esempio n. 4
0
/**
  * @brief  Transmission by T=1 TPDU Mode
  * @param  portno			Indicate which port to open (0:Port0; 1:Port1)
  * @param  pBlockBuffer	Command Data
  * @param  pBlockSize		The size of command data
  * @retval Slot Status Error Code
  */
unsigned char Ifd_XfrTpduT1(	int32_t portno,
										unsigned char *pBlockBuffer,
										unsigned int *pBlockSize	)
{
	int32_t ErrorCode, origBwt=0;
	uint8_t rbuf[MIN_BUFFER_SIZE];
	uint32_t idx, XfrWaitingTime = 0, rlen;
	S_SC_DEV_T *dev;	
	dev =  (S_SC_DEV_T *)((uint32_t)&sc_device[portno]);

	// if not equal to zero, change BWT according to BWI
	if(UsbMessageBuffer[OFFSET_BBWI] != 0)	
	{
		origBwt = dev->CardCapabilities.T1.BWT; 
		dev->CardCapabilities.T1.BWT *= UsbMessageBuffer[OFFSET_BBWI];    // how to integrate into BWT??????
	}

	// Sending procedure
	ErrorCode = CBRawTransmit( dev, pBlockBuffer, *pBlockSize, 0, &rbuf[0], &rlen);
	if(ErrorCode != SC_STATUS_SUCCESS)
		return Ifd_SC2CCIDErrorCode(ErrorCode);
	
	// Receiving procedure
	/* [EMV 2000] */
	XfrWaitingTime = (dev->CardCapabilities.T1.BWT / dev->CardCapabilities.etu) + (BitRateAdjustment[dev->CardCapabilities.Dl].DNumerator * 4700) + 1;

	SMARTCARD_TimerCountSet(dev, SC_TIMER0, SC_TMR_MODE_DC_RELOAD_S_S, XfrWaitingTime);
	SMARTCARD_TimerStart(dev, SC_TIMER0);

    dev->errno = PROTOCOL_T1_OK;
	dev->rcv_buf = pBlockBuffer;
	dev->rcv_len = 3;	// Prologue field length
	dev->rcv_cnt = 0;
   	dev->rcv_pos = 0;
	dev->op_state = SC_OP_READ;
	SMARTCARD_WaitFirstReceivedData(dev, SC_TIMER2, SC_TMR_MODE_DC, XfrWaitingTime);
	
	while(dev->op_state == SC_OP_READ && !(dev->errno)) ;
	if(dev->errno < 0)
		return Ifd_SC2CCIDErrorCode(dev->errno);

	dev->rcv_len = dev->rcv_buf[2] + (dev->CardCapabilities.T1.EDC?2:1);
	dev->rcv_cnt = 0;
   	dev->rcv_pos = 3;
	dev->op_state = SC_OP_READ;
	while(dev->op_state == SC_OP_READ && !(dev->errno)) ;
	if(dev->errno < 0)
		return Ifd_SC2CCIDErrorCode(dev->errno);

	SMARTCARD_TimerStop(dev, SC_TIMER0);	// stop timer

	// restore the original BWT value
	if(UsbMessageBuffer[OFFSET_BBWI] != 0)
		dev->CardCapabilities.T1.BWT = origBwt;
	
	// received data
	for(idx=0; idx<(dev->rcv_buf[2]+3+(dev->CardCapabilities.T1.EDC?2:1)); idx++) 
	{
		CCIDSCDEBUG("Received Data: Data[%d]=0x%02x \n", idx, dev->rcv_buf[idx]);
		*pBlockBuffer = dev->rcv_buf[idx];
		pBlockBuffer++;
	}
	// length of received data
	*pBlockSize = dev->rcv_buf[2]+3+(dev->CardCapabilities.T1.EDC?2:1);

	return SLOT_NO_ERROR;

}