IC Card
>w## Notice
> * please include the header file "bwsdk_api.h" when you need to use IC Card
`#include "bwsdk_api.h"`
>i## data structure
```
#define ICC_APDU_LEN_MIN 4 ///< Minimum bytes of C-APDU
#define ICC_APDU_LEN_MAX 260 ///< Maximum bytes of C-APDU
#define ICC_SW_SIZE 2 ///< Bytes of Status-Word
/**
* @brief ICC/PSAM slot number
*/
typedef enum {
ICC_SLOT = 0, ///< ICC usercard slot
PSAM1_SLOT, ///< PSAM1 slot
PSAM2_SLOT, ///< PSAM2 slot
} IccSlot_t;
#define ICC_ISO7816_SLOT_MASK (0<<7) ///< Bitmask of spec ISO7816
#define ICC_EMV_SLOT_MASK (1<<7) ///< Bitmask of spec EMV
#define ICC_CITYCARD_SLOT_MASK (1<<6) ///< Bitmask of spec China City Card
#define ICC_PPS_SUPP_MASK (1<<5) ///< Bitmask of PPS enable/disable
#define ICC_BDR_9600_TLV "\x41\x01\x11" ///< ICC/PSAM baudrate 9600
#define ICC_BDR_19200_TLV "\x41\x01\x12" ///< ICC/PSAM baudrate 19200
#define ICC_BDR_38400_TLV "\x41\x01\x13" ///< ICC/PSAM baudrate 38400
```
>i## IccStatusRev
### Prototype
`int IccStatusRev(void);`
### Function
* Check whether ICC/PSAM is exist or not
### Parameter
|Name|Type|description|
|-|-|-|
|none|||
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success(card exist)|
|<0|int|fail|
>i## IccResetRev
### Prototype
`int IccResetRev(unsigned char *pucATR);`
### Function
* ICC/PSAM reset and get ATR
### Parameter
|Name|Type|description|
|-|-|-|
|pucATR|unsigned char *|[out] pucATR: point of ATR buffer. if NULL, no ATR will be output|
### Retval
|Value|Type|Description|
|-|-|-|
|>=0|int|success(Length of ATR)|
|<0|int|fail|
>i## IccCloseRev
### Prototype
`int IccCloseRev(void);`
### Function
* ICC/PSAM power off
### Parameter
|Name|Type|description|
|-|-|-|
|none|||
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success|
|<0|int|fail|
>i## IccSelectSlotRev
### Prototype
`int IccSelectSlotRev(unsigned char ucSlot);`
### Function
* Select card slot, card specification and PPS feature
### Parameter
|Name|Type|description|
|-|-|-|
|ucSlot|unsigned char|[7:6] spec mask, [5] pps mask, [0:3] slot number; ICC_ISO7816_SLOT_MASK, ICC_EMV_SLOT_MASK, ICC_CITYCARD_SLOT_MASK, ICC_PPS_SUPP_MASK; IccSlot_t|
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success|
|<0|int|fail|
>i## IccSelectSlotByParamterRev
### Prototype
`int IccSelectSlotByParamterRev(unsigned char ucSlot, unsigned char *pucTLVs, unsigned int uiTLVsLen);`
### Function
* Select card slot, card specification and PPS feature and set parameters
### Parameter
|Name|Type|description|
|-|-|-|
|ucSlot|unsigned char|[7:6] spec mask, [5] pps mask, [0:3] slot number; ICC_ISO7816_SLOT_MASK, ICC_EMV_SLOT_MASK, ICC_CITYCARD_SLOT_MASK, ICC_PPS_SUPP_MASK; IccSlot_t|
|pucTLVs|unsigned char *|baudrate and voltage TLV:ICC_BDR_9600_TLV, ICC_BDR_19200_TLV, ICC_BDR_38400_TLV|
|uiTLVsLen|unsigned int|length of TLVs|
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success|
|<0|int|fail|
>i## IccGetResponseEnableRev
### Prototype
`int IccGetResponseEnableRev(unsigned char ucAutoFlag);`
### Function
* Set reponse mode
### Parameter
|Name|Type|description|
|-|-|-|
|ucAutoFlag|unsigned char|0: disable, 1: enable(Default, get response by SP)|
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success|
|<0|int|fail|
>i## IccApduTransmitExt
### Prototype
`int IccApduTransmitExt(unsigned char *pucCmd, unsigned int uiCmdLen, unsigned char *pucRsp, unsigned char *pucSW, unsigned int uiTimeoutMs);`
### Function
* APDU exchange
### Parameter
|Name|Type|description|
|-|-|-|
|pucCmd|unsigned char *|C-APDU|
|uiCmdLen|unsigned int|Length of C-APDU|
|pucRsp|unsigned char *|R-APDU|
|pucSW|unsigned char *|Status-Word(2 bytes)|
|uiTimeoutMs|unsigned int|Command timeout for response|
### Retval
|Value|Type|Description|
|-|-|-|
|>=0|int|success(Length of R-APDU)|
|<0|int|fail|
>s## Example
```
int iRet = 0;
unsigned char pApdu[] = {"\x02...."};
unsigned int uiApdu = 8;
unsigned char pResponse[64] = {0};
unsigned char SW[4] = {0};
iRet = IccStatusRev();
if (!iRet) {
///< card exist
iRet = IccResetRev(NULL);
if (iRet >= 0) {
if (0 == IccGetResponseEnableRev(1)) {
iRet = IccApduTransmitExt(pApdu, (unsigned int)uiApdu, pResponse, SW, 8*1000);
if (iRet >= 0) {
logger_serial_dump_buff("respApdu:", pResponse, iRet);
}
}
}
}
return IccCloseRev();
```