ISO7816_XfrBlockTPDU_T0
Default mainpageat91libcomponentsiso7816ISO7816_XfrBlockTPDU_T0
Description Source Call Graph
Start Line: 192
unsigned short ISO7816_XfrBlockTPDU_T0(const unsigned char *pAPDU, unsigned char *pMessage, unsigned short wLength)
{
    unsigned short NeNc;
    unsigned short indexApdu = 4;
    unsigned short indexMessage = 0;
    unsigned char SW1 = 0;
    unsigned char procByte;
    unsigned char cmdCase;

    TRACE_DEBUG("pAPDU[0]=0x%X\n\r",pAPDU[0]);
    TRACE_DEBUG("pAPDU[1]=0x%X\n\r",pAPDU[1]);
    TRACE_DEBUG("pAPDU[2]=0x%X\n\r",pAPDU[2]);
    TRACE_DEBUG("pAPDU[3]=0x%X\n\r",pAPDU[3]);
    TRACE_DEBUG("pAPDU[4]=0x%X\n\r",pAPDU[4]);
    TRACE_DEBUG("pAPDU[5]=0x%X\n\r",pAPDU[5]);
    TRACE_DEBUG("wlength=%d\n\r",wLength);

    ISO7816_SendChar( pAPDU[0] ); // CLA
    ISO7816_SendChar( pAPDU[1] ); // INS
    ISO7816_SendChar( pAPDU[2] ); // P1
    ISO7816_SendChar( pAPDU[3] ); // P2
    ISO7816_SendChar( pAPDU[4] ); // P3

    // Handle the four structures of command APDU
    indexApdu = 4;

    if( wLength == 4 ) {
        cmdCase = CASE1;
        NeNc = 0;
    }
    else if( wLength == 5) {
        cmdCase = CASE2;
        NeNc = pAPDU[4]; // C5
        if (NeNc == 0) {
            NeNc = 256;
        }
    }
    else if( wLength == 6) {
        NeNc = pAPDU[4]; // C5
        cmdCase = CASE3;
    }
    else if( wLength == 7) {
        NeNc = pAPDU[4]; // C5
        if( NeNc == 0 ) {
            cmdCase = CASE2;
            NeNc = (pAPDU[5]<<8)+pAPDU[6];
        }
        else {
            cmdCase = CASE3;
        }
    }
    else {
        NeNc = pAPDU[4]; // C5
        if( NeNc == 0 ) {
            cmdCase = CASE3;
            NeNc = (pAPDU[5]<<8)+pAPDU[6];
        }
        else {
            cmdCase = CASE3;
        }
    }

    TRACE_DEBUG("CASE=0x%X NeNc=0x%X\n\r", cmdCase, NeNc);

    // Handle Procedure Bytes
    do {
        ISO7816_GetChar(&procByte);
        // Handle NULL
        if ( procByte == ISO_NULL_VAL ) {
            TRACE_DEBUG("INS\n\r");
            continue;
        }
        // Handle SW1
        else if ( ((procByte & 0xF0) ==0x60) || ((procByte & 0xF0) ==0x90) ) {
            TRACE_DEBUG("SW1\n\r");
            SW1 = 1;
        }
        // Handle INS
        else if ( pAPDU[1] == procByte) {
            TRACE_DEBUG("HdlINS\n\r");
            if (cmdCase == CASE2) {
                // receive data from card
                do {
                    ISO7816_GetChar(&pMessage[indexMessage++]);
                } while( 0 != --NeNc );
            }
            else {
                 // Send data
                do {
                    ISO7816_SendChar(pAPDU[indexApdu++]);
                } while( 0 != --NeNc );
            }
        }
        // Handle INS ^ 0xff
        else if ( pAPDU[1] == (procByte ^ 0xff)) {
            TRACE_DEBUG("HdlINS+\n\r");
            if (cmdCase == CASE2) {
                // receive data from card
                ISO7816_GetChar(&pMessage[indexMessage++]);
            }
            else {
                ISO7816_SendChar(pAPDU[indexApdu++]);
            }
            NeNc--;
        }
        else {
            // ??
            TRACE_DEBUG("procByte=0x%X\n\r", procByte);
            break;
        }
    } while (NeNc != 0);

    // Status Bytes
    if (SW1 == 0) {
        ISO7816_GetChar(&pMessage[indexMessage++]); // SW1
    }
    else {
        pMessage[indexMessage++] = procByte;
    }
    ISO7816_GetChar(&pMessage[indexMessage++]); // SW2

    return( indexMessage );
    
}