Release v2.9.0

This commit is contained in:
slimih
2021-09-09 10:10:00 +01:00
parent 5af065de85
commit 06808a92fe
80 changed files with 10318 additions and 2098 deletions

View File

@@ -0,0 +1,482 @@
/**
******************************************************************************
* @file usbd_ccid_smartcard_template.c
* @author MCD Application Team
* @brief This file provides all the Smartcard firmware functions.
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup usbd_ccid_Smartcard
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid_smartcard_template.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Directories & Files ID */
/*The following Directories & Files ID can take any of following Values and can
be used in the smartcard application */
/*
const uint8_t MasterRoot[2] = {0x3F, 0x00};
const uint8_t GSMDir[2] = {0x7F, 0x20};
const uint8_t ICCID[2] = {0x2F, 0xE2};
const uint8_t IMSI[2] = {0x6F, 0x07};
__IO uint8_t ICCID_Content[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint32_t CHV1Status = 0U;
uint8_t CHV1[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
__IO uint8_t IMSI_Content[9] = {0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
*/
/* F Table: Clock Rate Conversion Table from ISO/IEC 7816-3 */
/* static uint32_t F_Table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768,
1024, 1536, 2048, 0, 0
}; */
/* D Table: Baud Rate Adjustment Factor Table from ISO/IEC 7816-3 */
static uint32_t D_Table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0};
/* Global variables definition and initialization ----------------------------*/
SC_ATR SC_A2R;
uint8_t SC_ATR_Table[40];
uint8_t ProtocolNUM_OUT;
/* Private function prototypes -----------------------------------------------*/
static void SC_Init(void);
static void SC_DeInit(void);
static void SC_AnswerReq(SC_State *SC_state, uint8_t *card, uint8_t length); /* Ask ATR */
static uint8_t SC_decode_Answer2reset(uint8_t *card); /* Decode ATR */
static void SC_SendData(SC_ADPU_Commands *SCADPU, SC_ADPU_Response *SC_ResponseStatus);
/* static void SC_Reset(GPIO_PinState ResetState); */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Handles all Smartcard states and serves to send and receive all
* communication data between Smartcard and reader.
* @param SCState: pointer to an SC_State enumeration that will contain the
* Smartcard state.
* @param SC_ADPU: pointer to an SC_ADPU_Commands structure that will be initialized.
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
* @retval None
*/
void SC_Handler(SC_State *SCState, SC_ADPU_Commands *SC_ADPU, SC_ADPU_Response *SC_Response)
{
uint32_t i, j;
switch (*SCState)
{
case SC_POWER_ON:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
/* Smartcard initialization */
SC_Init();
/* Reset Data from SC buffer */
for (i = 0U; i < 40U; i++)
{
SC_ATR_Table[i] = 0;
}
/* Reset SC_A2R Structure */
SC_A2R.TS = 0U;
SC_A2R.T0 = 0U;
for (i = 0U; i < MAX_PROTOCOLLEVEL; i++)
{
for (j = 0U; j < MAX_INTERFACEBYTE; j++)
{
SC_A2R.T[i].InterfaceByte[j].Status = 0U;
SC_A2R.T[i].InterfaceByte[j].Value = 0U;
}
}
for (i = 0U; i < HIST_LENGTH; i++)
{
SC_A2R.H[i] = 0U;
}
SC_A2R.Tlength = 0U;
SC_A2R.Hlength = 0U;
/* Next State */
*SCState = SC_RESET_LOW;
}
break;
case SC_RESET_LOW:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
/* If card is detected then Power ON, Card Reset and wait for an answer) */
if (SC_Detect() != 0U)
{
while (((*SCState) != SC_POWER_OFF) && ((*SCState) != SC_ACTIVE))
{
SC_AnswerReq(SCState, &SC_ATR_Table[0], 40U); /* Check for answer to reset */
}
}
else
{
(*SCState) = SC_POWER_OFF;
}
}
break;
case SC_ACTIVE:
if (SC_ADPU->Header.INS == SC_GET_A2R)
{
uint8_t protocol = SC_decode_Answer2reset(&SC_ATR_Table[0]);
if (protocol == T0_PROTOCOL)
{
(*SCState) = SC_ACTIVE_ON_T0;
ProtocolNUM_OUT = T0_PROTOCOL;
}
else if (protocol == T1_PROTOCOL)
{
(*SCState) = SC_ACTIVE_ON_T1;
ProtocolNUM_OUT = T1_PROTOCOL;
}
else
{
(*SCState) = SC_POWER_OFF;
}
}
break;
case SC_ACTIVE_ON_T0:
/* process commands other than ATR */
SC_SendData(SC_ADPU, SC_Response);
break;
case SC_ACTIVE_ON_T1:
/* process commands other than ATR */
SC_SendData(SC_ADPU, SC_Response);
break;
case SC_POWER_OFF:
SC_DeInit(); /* Disable Smartcard interface */
break;
default:
(*SCState) = SC_POWER_OFF;
break;
}
}
/**
* @brief Enables or disables the power to the Smartcard.
* @param NewState: new state of the Smartcard power supply.
* This parameter can be: SC_ENABLED or SC_DISABLED.
* @retval None
*/
void SC_PowerCmd(SCPowerState NewState)
{
UNUSED(NewState);
/* enable or disable smartcard pin */
return;
}
/**
* @brief Sets or clears the Smartcard reset pin.
* @param ResetState: this parameter specifies the state of the Smartcard
* reset pin. BitVal must be one of the BitAction enum values:
* @arg Bit_RESET: to clear the port pin.
* @arg Bit_SET: to set the port pin.
* @retval None
*/
/* static void SC_Reset(GPIO_PinState ResetState)
{
UNUSED(ResetState);
return;
}
*/
/**
* @brief Resends the byte that failed to be received (by the Smartcard) correctly.
* @param None
* @retval None
*/
void SC_ParityErrorHandler(void)
{
/* Add your code here */
return;
}
/**
* @brief Configures the IO speed (BaudRate) communication.
* @param None
* @retval None
*/
void SC_PTSConfig(void)
{
/* Add your code here */
return;
}
/**
* @brief Manages the Smartcard transport layer: send APDU commands and receives
* the APDU response.
* @param SC_ADPU: pointer to a SC_ADPU_Commands structure which will be initialized.
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
* @retval None
*/
static void SC_SendData(SC_ADPU_Commands *SCADPU, SC_ADPU_Response *SC_ResponseStatus)
{
uint8_t i;
uint8_t SC_Command[5];
uint8_t SC_DATA[LC_MAX];
UNUSED(SCADPU);
/* Reset response buffer */
for (i = 0U; i < LC_MAX; i++)
{
SC_ResponseStatus->Data[i] = 0U;
SC_DATA[i] = 0U;
}
/* User to add code here */
/* send command to ICC and get response status */
USBD_CCID_If_fops.Send_Process((uint8_t *)&SC_Command, (uint8_t *)&SC_DATA);
}
/**
* @brief SC_AnswerReq
Requests the reset answer from card.
* @param SC_state: pointer to an SC_State enumeration that will contain the Smartcard state.
* @param atr_buffer: pointer to a buffer which will contain the card ATR.
* @param length: maximum ATR length
* @retval None
*/
static void SC_AnswerReq(SC_State *SC_state, uint8_t *atr_buffer, uint8_t length)
{
UNUSED(length);
UNUSED(atr_buffer);
/* to be implemented by USER */
switch (*SC_state)
{
case SC_RESET_LOW:
/* Check response with reset low */
(*SC_state) = SC_ACTIVE;
break;
case SC_ACTIVE:
break;
case SC_RESET_HIGH:
/* Check response with reset high */
break;
case SC_POWER_OFF:
/* Close Connection if no answer received */
break;
default:
(*SC_state) = SC_RESET_LOW;
break;
}
return;
}
/**
* @brief SC_decode_Answer2reset
Decodes the Answer to reset received from card.
* @param card: pointer to the buffer containing the card ATR.
* @retval None
*/
static uint8_t SC_decode_Answer2reset(uint8_t *card)
{
uint32_t i, flag = 0U, protocol;
uint8_t index = 0U, level = 0U;
/******************************TS/T0 Decode************************************/
index++;
SC_A2R.TS = card[index]; /* Initial character */
index++;
SC_A2R.T0 = card[index]; /* Format character */
/*************************Historical Table Length Decode***********************/
SC_A2R.Hlength = SC_A2R.T0 & 0x0FU;
/******************************Protocol Level(1) Decode************************/
/* Check TD(1) if present */
if ((SC_A2R.T0 & 0x80U) == 0x80U)
{
flag = 1U;
}
/* Each bits in the T0 high nibble(b8 to b5) equal to 1 indicates the presence
of a further interface byte */
for (i = 0U; i < 4U; i++)
{
if ((((SC_A2R.T0 & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
{
SC_A2R.T[level].InterfaceByte[i].Status = 1U;
index++;
SC_A2R.T[level].InterfaceByte[i].Value = card[index];
SC_A2R.Tlength++;
}
}
/*****************************T Decode*****************************************/
if (SC_A2R.T[level].InterfaceByte[3].Status == 1U)
{
/* Only the protocol(parameter T) present in TD(1) is detected
if two or more values of parameter T are present in TD(1), TD(2)..., so the
firmware should be updated to support them */
protocol = (uint8_t)(SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x0FU);
}
else
{
protocol = 0U;
}
/* Protocol Level Increment */
/******************************Protocol Level(n>1) Decode**********************/
while (flag != 0U)
{
if ((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x80U) == 0x80U)
{
flag = 1U;
}
else
{
flag = 0U;
}
/* Each bits in the high nibble(b8 to b5) for the TD(i) equal to 1 indicates
the presence of a further interface byte */
for (i = 0U; i < 4U; i++)
{
if ((((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
{
SC_A2R.T[level + 1U].InterfaceByte[i].Status = 1U;
index++;
SC_A2R.T[level + 1U].InterfaceByte[i].Value = card[index];
SC_A2R.Tlength++;
}
}
level++;
}
for (i = 0U; i < SC_A2R.Hlength; i++)
{
SC_A2R.H[i] = card[i + 2U + SC_A2R.Tlength];
}
/*************************************TCK Decode*******************************/
SC_A2R.TCK = card[SC_A2R.Hlength + 2U + SC_A2R.Tlength];
return (uint8_t)protocol;
}
/**
* @brief Initializes all peripheral used for Smartcard interface.
* @param None
* @retval None
*/
static void SC_Init(void)
{
/*
Add your initialization code here
*/
return;
}
/**
* @brief Deinitializes all resources used by the Smartcard interface.
* @param None
* @retval None
*/
static void SC_DeInit(void)
{
/*
Add your deinitialization code here
*/
return;
}
/**
* @brief Configures the card power voltage.
* @param SC_Voltage: specifies the card power voltage.
* This parameter can be one of the following values:
* @arg SC_VOLTAGE_5V: 5V cards.
* @arg SC_VOLTAGE_3V: 3V cards.
* @retval None
*/
void SC_VoltageConfig(uint32_t SC_Voltage)
{
UNUSED(SC_Voltage);
/* Add your code here */
return;
}
/**
* @brief Configures GPIO hardware resources used for Samrtcard.
* @param None
* @retval None
*/
void SC_IOConfig(void)
{
/* Add your code here */
return;
}
/**
* @brief Detects whether the Smartcard is present or not.
* @param None.
* @retval 1 - Smartcard inserted
* 0 - Smartcard not inserted
*/
uint8_t SC_Detect(void)
{
uint8_t PIN_State = 0U;
/* Add your code here */
return PIN_State;
}
/**
* @brief Get the Right Value from the D_Table Index
* @param idx : Index to Read from the Table
* @retval Value read from the Table
*/
uint32_t SC_GetDTableValue(uint32_t idx)
{
return D_Table[idx];
}