예제 #1
0
/**
 * CT-BCS Request ICC command
 *
 * @param ctx Reader context
 * @param lc Length of command
 * @param cmd Command
 * @param lr Length of response
 * @param rsp Response buffer
 * @return \ref OK, \ref ERR_CT, \ref ERR_MEMORY
 */
int RequestICC(struct scr *ctx, unsigned int lc, unsigned char *cmd,
			   unsigned int *lr, unsigned char *rsp)
{
	int status, timeout;

	if ((lc > 4) && (cmd[4] == 1)) {
		timeout = cmd[5];
	} else {
		timeout = 0;
	}

	status = PC_to_RDR_GetSlotStatus(ctx);

	if (status < 0) {
		rsp[0] = HIGH(NOT_SUCCESSFUL);
		rsp[1] = LOW(NOT_SUCCESSFUL);
		*lr = 2;
		return ERR_CT;
	}

	timeout *= 4;

	do {

		status = PC_to_RDR_GetSlotStatus(ctx);

		if (status < 0) {
			rsp[0] = HIGH(NOT_SUCCESSFUL);
			rsp[1] = LOW(NOT_SUCCESSFUL);
			*lr = 2;
			return ERR_CT;
		}

		if ((status == ICC_PRESENT_AND_INACTIVE) || !timeout) {
			break;
		}

		usleep(250000);
		timeout--;
	} while (timeout);

	if (!timeout && (status == NO_ICC_PRESENT)) {
		rsp[0] = HIGH(W_NO_CARD_PRESENTED);
		rsp[1] = LOW(W_NO_CARD_PRESENTED);
		*lr = 2;
		return OK;
	}

	if ((status = ResetCard(ctx, lc, cmd, lr, rsp)) < 0) {
		return status;
	}

	return OK;
}
예제 #2
0
/**
 * Get ICC status
 *
 * @param ctx Reader context
 * @param lr Length of response
 * @param rsp Response buffer
 * @return \ref OK, \ref ERR_CT, \ref ERR_MEMORY
 */
int GetICCStatus(struct scr *ctx, unsigned int *lr, unsigned char *rsp)
{
	int status;

	status = PC_to_RDR_GetSlotStatus(ctx);

	if (status < 0) {
		rsp[0] = HIGH(NOT_SUCCESSFUL);
		rsp[1] = LOW(NOT_SUCCESSFUL);
		*lr = 2;
		return ERR_CT;
	}

	if (*lr < 5) {
		return ERR_MEMORY;
	}

	rsp[0] = 0x80;
	rsp[1] = 0x01;
	rsp[2] = 0x00; /* Set ICC Status DO - default is no ICC present */

	if (status == ICC_PRESENT_AND_INACTIVE) {
		rsp[2] |= 0x03; /* card in, no CVCC                  */
	}

	if (status == ICC_PRESENT_AND_ACTIVE) {
		rsp[2] |= 0x05; /* card in, CVCC on                  */
	}

	rsp[3] = HIGH(SMARTCARD_SUCCESS);
	rsp[4] = LOW(SMARTCARD_SUCCESS);
	*lr = 5;

	return OK;
}
예제 #3
0
void CCID_DispatchMessage(void)
{
    uint8_t ErrorCode;

    if(gu8IsBulkOutReady)
    {
        switch(UsbMessageBuffer[OFFSET_BMESSAGETYPE])
        {
        case PC_TO_RDR_ICCPOWERON:
            ErrorCode = PC_to_RDR_IccPowerOn();
            RDR_to_PC_DataBlock(ErrorCode);
            break;
        case PC_TO_RDR_ICCPOWEROFF:
            ErrorCode = PC_to_RDR_IccPowerOff();
            RDR_to_PC_SlotStatus(ErrorCode);
            break;
        case PC_TO_RDR_GETSLOTSTATUS:
            ErrorCode = PC_to_RDR_GetSlotStatus();
            RDR_to_PC_SlotStatus(ErrorCode);
            break;
        case PC_TO_RDR_XFRBLOCK:
            ErrorCode = PC_to_RDR_XfrBlock();
            RDR_to_PC_DataBlock(ErrorCode);
            break;
        case PC_TO_RDR_GETPARAMETERS:
            ErrorCode = PC_to_RDR_GetParameters();
            RDR_to_PC_Parameters(ErrorCode);
            break;
        case PC_TO_RDR_RESETPARAMETERS:
            ErrorCode = PC_to_RDR_ResetParameters();
            RDR_to_PC_Parameters(ErrorCode);
            break;
        case PC_TO_RDR_SETPARAMETERS:
            ErrorCode = PC_to_RDR_SetParameters();
            RDR_to_PC_Parameters(ErrorCode);
            break;
        case PC_TO_RDR_ESCAPE:
            ErrorCode = PC_to_RDR_Escape();
            RDR_to_PC_Escape(ErrorCode);
            break;
        case PC_TO_RDR_ICCCLOCK:
            ErrorCode = PC_to_RDR_IccClock();
            RDR_to_PC_SlotStatus(ErrorCode);
            break;
        case PC_TO_RDR_ABORT:
            ErrorCode = PC_to_RDR_Abort();
            RDR_to_PC_SlotStatus(ErrorCode);
            break;
        case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
        case PC_TO_RDR_SECURE:
        case PC_TO_RDR_T0APDU:
        case PC_TO_RDR_MECHANICAL:
        default:
            CmdNotSupported();
            break;
        }

        CCID_BulkInMessage();
        gu8IsBulkOutReady = 0;
    }
}
예제 #4
0
/**
 * CT-BCS Eject ICC command
 *
 * @param ctx Reader context
 * @param lc Length of command
 * @param cmd Command
 * @param lr Length of response
 * @param rsp Response buffer
 * @return \ref OK, \ref ERR_CT
 */
int EjectICC(struct scr *ctx, unsigned int lc, unsigned char *cmd,
			 unsigned int *lr, unsigned char *rsp)
{
	int status;
	unsigned char save_timeout;
	unsigned char timeout;

	/* Reader has no display or other goodies, so check for correct P2 parameter */
	/* Unmask bit 3, because we can always keep the card in the slot               */

	if ((cmd[3] & 0xFB) != 0x00) {
		rsp[0] = HIGH(WRONG_PARAMETERS_P1_P2);
		rsp[1] = LOW(WRONG_PARAMETERS_P1_P2);
		*lr = 2;
		return OK;
	}

	if ((lc > 4) && (cmd[4] > 0)) {
		timeout = cmd[5];
	} else {
		timeout = 0;
	}

	save_timeout = timeout;

	status = PC_to_RDR_IccPowerOff(ctx);

	if (status < 0) {
		rsp[0] = HIGH(NOT_SUCCESSFUL);
		rsp[1] = LOW(NOT_SUCCESSFUL);
		*lr = 2;
		return ERR_CT;
	}

	ctx->CTModFunc = NULL;
	ctx->LenOfATR = 0;
	ctx->NumOfHB = 0;

	save_timeout *= 4;

	if (save_timeout > 0) {
		do {

			status = PC_to_RDR_GetSlotStatus(ctx);

			if (status < 0) {
				rsp[0] = HIGH(NOT_SUCCESSFUL);
				rsp[1] = LOW(NOT_SUCCESSFUL);
				*lr = 2;
				return ERR_CT;
			}

			if (status == ICC_PRESENT_AND_INACTIVE || status == NO_ICC_PRESENT) {
				break;
			}

			usleep(250000);

		} while (--save_timeout);

	} else { /* Command OK,no timeout specified   */
		rsp[0] = HIGH(SMARTCARD_SUCCESS);
		rsp[1] = LOW(SMARTCARD_SUCCESS);
		*lr = 2;
		return OK;
	}

	if (save_timeout) { /* Command OK, card removed          */
		rsp[0] = HIGH(SMARTCARD_SUCCESS);
		rsp[1] = LOW(SMARTCARD_SUCCESS);
		*lr = 2;
		return OK;
	}

	if ((!save_timeout) && (timeout > 0)) { /* warning: card not removed */
		rsp[0] = HIGH(W_NO_CARD_PRESENTED);
		rsp[1] = LOW(W_NO_CARD_PRESENTED);
		*lr = 2;
	}

	return OK;
}
예제 #5
-1
파일: usbd_ccid_if.c 프로젝트: caozoux/arm
/**
  * @brief  CCID_CmdDecode
  *         Parse the commands and Proccess command
  * @param  pdev: device instance
  * @retval None
  */
void CCID_CmdDecode(USB_CORE_HANDLE  *pdev)
{
  uint8_t errorCode;
  
  switch (Ccid_bulkout_data.bMessageType)
  {
  case PC_TO_RDR_ICCPOWERON:
    errorCode = PC_to_RDR_IccPowerOn();
    RDR_to_PC_DataBlock(errorCode);
    break;
  case PC_TO_RDR_ICCPOWEROFF:
    errorCode = PC_to_RDR_IccPowerOff();
    RDR_to_PC_SlotStatus(errorCode);
    break;
  case PC_TO_RDR_GETSLOTSTATUS:
    errorCode = PC_to_RDR_GetSlotStatus();
    RDR_to_PC_SlotStatus(errorCode);
    break;
  case PC_TO_RDR_XFRBLOCK:
    errorCode = PC_to_RDR_XfrBlock();
    RDR_to_PC_DataBlock(errorCode);
    break;
  case PC_TO_RDR_GETPARAMETERS:
    errorCode = PC_to_RDR_GetParameters();
    RDR_to_PC_Parameters(errorCode);
    break;
  case PC_TO_RDR_RESETPARAMETERS:
    errorCode = PC_to_RDR_ResetParameters();
    RDR_to_PC_Parameters(errorCode);
    break;
  case PC_TO_RDR_SETPARAMETERS:
    errorCode = PC_to_RDR_SetParameters();
    RDR_to_PC_Parameters(errorCode);
    break;
  case PC_TO_RDR_ESCAPE:
    errorCode = PC_to_RDR_Escape();
    RDR_to_PC_Escape(errorCode);
    break;
  case PC_TO_RDR_ICCCLOCK:
    errorCode = PC_to_RDR_IccClock();
    RDR_to_PC_SlotStatus(errorCode);
    break;
  case PC_TO_RDR_ABORT:
    errorCode = PC_to_RDR_Abort();
    RDR_to_PC_SlotStatus(errorCode);
    break;
  case PC_TO_RDR_T0APDU:
    errorCode = PC_TO_RDR_T0Apdu();
    RDR_to_PC_SlotStatus(errorCode);
    break;
  case PC_TO_RDR_MECHANICAL:
    errorCode = PC_TO_RDR_Mechanical();
    RDR_to_PC_SlotStatus(errorCode);
    break;   
  case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
    errorCode = PC_TO_RDR_SetDataRateAndClockFrequency();
    RDR_to_PC_DataRateAndClockFrequency(errorCode);
    break;
  case PC_TO_RDR_SECURE:
    errorCode = PC_TO_RDR_Secure();
    RDR_to_PC_DataBlock(errorCode);
    break;
  default:
    RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED);
    break;
  }
  
     /********** Decide for all commands ***************/ 
  if (Ccid_BulkState == CCID_STATE_SEND_RESP)
  {
    CCID_Response_SendData(pdev, (uint8_t*)&Ccid_bulkin_data, 
                                  Ccid_bulkin_data.u16SizeToSend);
  }
}