iso7816_4.c: GetChar returns status

This commit is contained in:
Christina Quast 2015-04-07 13:49:26 +02:00
parent b2d5aeb850
commit 73c2b6498b
3 changed files with 76 additions and 37 deletions

View File

@ -69,9 +69,10 @@
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern void ISO7816_Init( const Pin *pPinIso7816RstMC ); extern void ISO7816_Init( const Pin *pPinIso7816RstMC );
extern void ISO7816_IccPowerOff(void); extern void ISO7816_IccPowerOff(void);
extern uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, extern uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
uint8_t *pMessage, uint8_t *pMessage,
uint16_t wLength ); uint16_t wLength,
uint16_t *retlen);
extern void ISO7816_Escape( void ); extern void ISO7816_Escape( void );
extern void ISO7816_RestartClock(void); extern void ISO7816_RestartClock(void);
extern void ISO7816_StopClock( void ); extern void ISO7816_StopClock( void );

View File

@ -184,22 +184,25 @@ void ISO7816_IccPowerOff( void )
} }
/** /**
* Transfert Block TPDU T=0 * Transfert Block TPDU T=0
* \param pAPDU APDU buffer * \param pAPDU APDU buffer
* \param pMessage Message buffer * \param pMessage Message buffer
* \param wLength Block length * \param wLength Block length
* \return Message index * \param indexMsg Message index
* \return 0 on success, content of US_CSR otherwise
*/ */
uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU, uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
uint8_t *pMessage, uint8_t *pMessage,
uint16_t wLength ) uint16_t wLength,
uint16_t *retlen )
{ {
uint16_t NeNc; uint16_t NeNc;
uint16_t indexApdu = 4; uint16_t indexApdu = 4;
uint16_t indexMessage = 0; uint16_t indexMsg = 0;
uint8_t SW1 = 0; uint8_t SW1 = 0;
uint8_t procByte; uint8_t procByte;
uint8_t cmdCase; uint8_t cmdCase;
uint32_t status = 0;
TRACE_INFO("pAPDU[0]=0x%X\n\r",pAPDU[0]); TRACE_INFO("pAPDU[0]=0x%X\n\r",pAPDU[0]);
TRACE_INFO("pAPDU[1]=0x%X\n\r",pAPDU[1]); TRACE_INFO("pAPDU[1]=0x%X\n\r",pAPDU[1]);
@ -258,7 +261,10 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
/* Handle Procedure Bytes */ /* Handle Procedure Bytes */
do { do {
ISO7816_GetChar(&procByte); status = ISO7816_GetChar(&procByte);
if (status != 0) {
return status;
}
TRACE_INFO("procByte: 0x%X\n\r", procByte); TRACE_INFO("procByte: 0x%X\n\r", procByte);
/* Handle NULL */ /* Handle NULL */
if ( procByte == ISO_NULL_VAL ) { if ( procByte == ISO_NULL_VAL ) {
@ -276,8 +282,11 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
if (cmdCase == CASE2) { if (cmdCase == CASE2) {
/* receive data from card */ /* receive data from card */
do { do {
ISO7816_GetChar(&pMessage[indexMessage++]); status = ISO7816_GetChar(&pMessage[indexMsg++]);
} while( 0 != --NeNc ); } while(( 0 != --NeNc) && (status == 0) );
if (status != 0) {
return status;
}
} }
else { else {
/* Send data */ /* Send data */
@ -292,11 +301,17 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
TRACE_INFO("HdlINS+\n\r"); TRACE_INFO("HdlINS+\n\r");
if (cmdCase == CASE2) { if (cmdCase == CASE2) {
/* receive data from card */ /* receive data from card */
ISO7816_GetChar(&pMessage[indexMessage++]); status = ISO7816_GetChar(&pMessage[indexMsg++]);
TRACE_INFO("Rcv: 0x%X\n\r", pMessage[indexMessage-1]); if (status != 0) {
return status;
}
TRACE_INFO("Rcv: 0x%X\n\r", pMessage[indexMsg-1]);
} }
else { else {
ISO7816_SendChar(pAPDU[indexApdu++]); status = ISO7816_SendChar(pAPDU[indexApdu++]);
if (status != 0) {
return status;
}
} }
NeNc--; NeNc--;
} }
@ -309,16 +324,23 @@ uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
/* Status Bytes */ /* Status Bytes */
if (SW1 == 0) { if (SW1 == 0) {
ISO7816_GetChar(&pMessage[indexMessage++]); /* SW1 */ status = ISO7816_GetChar(&pMessage[indexMsg++]); /* SW1 */
if (status != 0) {
return status;
}
} }
else { else {
pMessage[indexMessage++] = procByte; pMessage[indexMsg++] = procByte;
}
status = ISO7816_GetChar(&pMessage[indexMsg++]); /* SW2 */
if (status != 0) {
return status;
} }
ISO7816_GetChar(&pMessage[indexMessage++]); /* SW2 */
TRACE_WARNING("SW1=0x%X, SW2=0x%X\n\r", pMessage[indexMessage-2], pMessage[indexMessage-1]); TRACE_WARNING("SW1=0x%X, SW2=0x%X\n\r", pMessage[indexMsg-2], pMessage[indexMsg-1]);
return( indexMessage ); *retlen = indexMsg;
return status;
} }
@ -375,44 +397,54 @@ uint32_t ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength )
/* Read ATR TS */ /* Read ATR TS */
// FIXME: There should always be a check for the GetChar return value..0 means timeout // FIXME: There should always be a check for the GetChar return value..0 means timeout
status = ISO7816_GetChar(&pAtr[0]); status = ISO7816_GetChar(&pAtr[0]);
/* if (status == 0) { if (status != 0) {
return status; return status;
}*/ }
/* Read ATR T0 */ /* Read ATR T0 */
ISO7816_GetChar(&pAtr[1]); status = ISO7816_GetChar(&pAtr[1]);
if (status != 0) {
return status;
}
y = pAtr[1] & 0xF0; y = pAtr[1] & 0xF0;
i = 2; i = 2;
/* Read ATR Ti */ /* Read ATR Ti */
while (y) { while (y && (status == 0)) {
if (y & 0x10) { /* TA[i] */ if (y & 0x10) { /* TA[i] */
ISO7816_GetChar(&pAtr[i++]); status = ISO7816_GetChar(&pAtr[i++]);
} }
if (y & 0x20) { /* TB[i] */ if (y & 0x20) { /* TB[i] */
ISO7816_GetChar(&pAtr[i++]); status = ISO7816_GetChar(&pAtr[i++]);
} }
if (y & 0x40) { /* TC[i] */ if (y & 0x40) { /* TC[i] */
ISO7816_GetChar(&pAtr[i++]); status = ISO7816_GetChar(&pAtr[i++]);
} }
if (y & 0x80) { /* TD[i] */ if (y & 0x80) { /* TD[i] */
ISO7816_GetChar(&pAtr[i]); status = ISO7816_GetChar(&pAtr[i]);
y = pAtr[i++] & 0xF0; y = pAtr[i++] & 0xF0;
} }
else { else {
y = 0; y = 0;
} }
} }
if (status != 0) {
return status;
}
/* Historical Bytes */ /* Historical Bytes */
y = pAtr[1] & 0x0F; y = pAtr[1] & 0x0F;
for( j=0; j < y; j++ ) { for( j=0; (j < y) && (status == 0); j++ ) {
ISO7816_GetChar(&pAtr[i++]); status = ISO7816_GetChar(&pAtr[i++]);
}
if (status != 0) {
return status;
} }
*pLength = i; *pLength = i;
return status;
} }
/** /**

View File

@ -421,7 +421,8 @@ static void PCtoRDRGetSlotStatus( void )
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void PCtoRDRXfrBlock( void ) static void PCtoRDRXfrBlock( void )
{ {
unsigned char indexMessage = 0; uint16_t msglen = 0;
uint32_t ret;
//TRACE_DEBUG("."); //TRACE_DEBUG(".");
@ -447,9 +448,14 @@ static void PCtoRDRXfrBlock( void )
TRACE_INFO("APDU cmd: %x %x %x ..", ccidDriver.sCcidCommand.APDU[0], ccidDriver.sCcidCommand.APDU[1],ccidDriver.sCcidCommand.APDU[2] ); TRACE_INFO("APDU cmd: %x %x %x ..", ccidDriver.sCcidCommand.APDU[0], ccidDriver.sCcidCommand.APDU[1],ccidDriver.sCcidCommand.APDU[2] );
// Send commande APDU // Send commande APDU
indexMessage = ISO7816_XfrBlockTPDU_T0( ccidDriver.sCcidCommand.APDU , ret = ISO7816_XfrBlockTPDU_T0( ccidDriver.sCcidCommand.APDU ,
ccidDriver.sCcidMessage.abData, ccidDriver.sCcidMessage.abData,
ccidDriver.sCcidCommand.wLength ); ccidDriver.sCcidCommand.wLength,
&msglen );
if (ret != 0) {
TRACE_ERROR("APDU could not be sent: (US_CSR = 0x%x)", ret);
return;
}
} }
else { else {
if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_T1) { if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_T1) {
@ -471,7 +477,7 @@ static void PCtoRDRXfrBlock( void )
} }
ccidDriver.sCcidMessage.wLength = indexMessage; ccidDriver.sCcidMessage.wLength = msglen;
TRACE_DEBUG("USB: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n\r", ccidDriver.sCcidMessage.abData[0], TRACE_DEBUG("USB: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n\r", ccidDriver.sCcidMessage.abData[0],
ccidDriver.sCcidMessage.abData[1], ccidDriver.sCcidMessage.abData[1],
ccidDriver.sCcidMessage.abData[2], ccidDriver.sCcidMessage.abData[2],