mirror of https://gerrit.osmocom.org/simtrace2
iso7816_4.c: GetChar returns status
This commit is contained in:
parent
b2d5aeb850
commit
73c2b6498b
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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],
|
||||||
|
|
Loading…
Reference in New Issue