Smartcard USB driver - Bulk IN message problem

Hello,
Writing a an USB smartcard driver, I choose to start a new thread instead of continue the last thread i ve initiated.
I have written the configuration for the LPC2368. Here the configuration:

const BYTE USB_ConfigDescriptor[] = {

/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,       /* bDescriptorType */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
  WBVAL(                             /* wTotalLength */
    USB_CONFIGUARTION_DESC_SIZE +
    USB_INTERFACE_DESC_SIZE     +
    SMARTCARD_CLASS_DESC_SIZE               +
    3*USB_ENDPOINT_DESC_SIZE
  ),
  0x01,                              /* bNumInterfaces */
  0x01,                              /* bConfigurationValue */
  0x03,                              /* iConfiguration */
  /*USB_CONFIG_BUS_POWERED */       /* bmAttributes */
  0x80,
  USB_CONFIG_POWER_MA(100),          /* bMaxPower */

/* Interface 0, Alternate Setting 0, HID Class */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
  0x00,                              /* bInterfaceNumber */
  0x00,                              /* bAlternateSetting */
  0x03,                              /* bNumEndpoints */
  0x0b,                                                          /* bInterfaceClass */
  //USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
  0x00,                 /* bInterfaceSubClass */
  0x00,                 /* bInterfaceProtocol */
  0x00,                              /* iInterface */
  /* Smartcard Class Descriptor */
  SMARTCARD_CLASS_DESC_SIZE,                     /* bLength */
  SMARTCARD_SMARTCARD_DESCRIPTOR_TYPE,           /* bDescriptorType */
  WBVAL(0x0100), /* 1.00 */             /* bcdCCID */
  0x00,                                                 /* bMaxSlotIndex */
  0x07,                                                         /* bVoltageSupport: 5v, 3v and 1.8v */
  0x03,0x00,0x00,0x00,                                  // dwProtocols: supports T=0 and T=1
  0xF8,0x34,0x00,0x00,                                  // dwDefaultClock: 13,56 Mhz (0x00000FA0)
  0xF8,0x34,0x00,0x00,                                  // dwMaximumClock: 13,56 Mhz (0x00000FA0)
  0x00,                                                                 // bNumClockSupported => no manual setting
  0x00,0x2A,0x00,0x00,                                  // dwDataRate: 10752 bps (0x00002A00)
  0x08,0xF8,0x01,0x00,                                  // dwMaxDataRate: 129032 bps (0x0001F808)
  0x00,                                                                 // bNumDataRatesSupported => no manual setting
  0xFE,0x00,0x00,0x00,                                  /* IFSD */
  0x00,0x00,0x00,0x00,                                  /* Synchron Protocol */
  0x00,0x00,0x00,0x00,                                  /* Mechanical Features, DWORD */
  (0x04 | 0x08 | 0x10 | 0x40 | 0x02),(0x01 | 0x02),0x02,0x00,           /* Features - Automatic activation - clk, baud rate, voltage :automatic - short APDU level exchange*/
  // CCID can set ICC in clock stop mode - Automatic IFSD exchange(for T=1)
  0x0F,0x01,0x00,0x00,                              /* Max CCID Message Length : Maximun block size + header (261 + 10)*/
  0xFF,                                                             /* Class Get Response */
  0XFF,                                                         /* Class enveloppe */
  0x00,0x00,                                                    /* wLayout */
  0x00,                                                                 /* Pin Support */
  0x01,                                                         /* Max CCID Busy Slots */

/* Endpoint, INTERRUPT In */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  0x81,                                          /* bEndpointAddress */
  USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
  WBVAL(0x0008),                     /* wMaxPacketSize */
  0x18,          /* 32ms */          /* bInterval */

/* Endpoint, SMART CARD Bulk In */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  0x82,                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,       /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x00,          /* 32ms */          /* bInterval */

/* Endpoint, SMART CARD BULK Out (from the host to the device) */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  0x02,               /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,       /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x00,          /* 32ms */          /* bInterval */

  /* Terminator */
  0                                  /* bLength */
};


The endpoints seem to be well configured since I can write {50, 03, 00, 00} on the Interrupt EP IN :

BYTE smcSlotStatusChange (void)
{
        BYTE msg[4];
        msg[0] = RDR_to_PC_NotifySlotChange; //bMessageType : 50
        msg[1] = 0x03;  //bmSlotICCstate 00000011 -  slot 0 status changed and slot 0 current state is ICC present (manual that I linked page 56)

        EP1DataSnd.pData = msg;
        EP1DataSnd.Count = 4;
        USB_DataInStage1(); //write to the EP IN 0x81
        return 0;
}

The host respond successfully with the telegram {63, 00, 00, 00, 00, 00, 01, 00, 00, 00} (PC_to_RDR_ICCPowerOff).

Then I successfully sended the RDR_to_PC_Slotstatus in the Bulk IN (0x82) {81, 00, 00, 00, 00, 00, 01, 01, 00, 01}

The host respond successfully with the telegram {62, 00, 00, 00, 00, 00, 02, 00, 00, 00} (PC_to_RDR_ICCPowerON).

THEN I TRIED TO SEND A RDR_to_PC_Datablock but the host doesn't catch it! I tried with the telegramms:
BYTE FirstDataBlock[14] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xXX, 0x40, 0xFE, 0x00}; //
BYTE FirstDataBlock[14] = {0x80, 0x04, 0x00, 0x00, 0x00, 0xXX, 0xFF, 0x40, 0xFE, 0x00, 0x03, 0x00, 0x00,0x00};

where 0xXX ist the last BULK-OUT received bSeq BYTE
but the Host does'nt take it! I can't see it on the USBLYzer!

Has anybody an Idea about it?

Here the protocol functions:

void smcDispatchMessage()
{
        BYTE ErrorCode;
//Initialize the pointers
        UsbMessageBuffer = EP2DataRcv.pData;
        UsbInMessageBuffer = EP2DataRcv.pData;

        switch (*UsbMessageBuffer)
        {
                case PC_to_RDR_IccPowerOn: //0x62
                        ErrorCode = PC_to_RDR_IccPowerON();
                        smcDataBlock(ErrorCode, FirstDataBlock);
                        break;
                case PC_to_RDR_IccPowerOff: //0x63
                        ErrorCode = PC_to_RDR_IccPowerOFF();
                        smcSlotStatus(ErrorCode, IccPowerON);
                        break;
}
}


Thanks in advance!


Parents
  • Here the functions:

    void smcSlotStatus(BYTE Err, BYTE* Mess)         //cnt = 10
    {
        *(UsbInMessageBuffer+OFFSET_BMESSAGETYPE) = Mess[0];
            *(UsbInMessageBuffer+OFFSET_BSTATUS) = CRD_GetSlotStatus();     //0x00
            *(UsbInMessageBuffer+OFFSET_BERROR) = Mess[OFFSET_BERROR];
            if(Err != SLOT_NO_ERROR)
            {
            *(UsbInMessageBuffer+OFFSET_BSTATUS) += 0x40;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+1) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+2) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+3) = 0x00;
            *(UsbInMessageBuffer+OFFSET_BERROR) = Err;
            };
            *(UsbInMessageBuffer+OFFSET_BSEQ)   =  *(UsbMessageBuffer+OFFSET_BSEQ);
            *(UsbInMessageBuffer+OFFSET_BSEQ+1) = Mess[OFFSET_BSEQ+1];
            *(UsbInMessageBuffer+OFFSET_BCLOCKSTATUS) = Mess[OFFSET_BCLOCKSTATUS];
            //UsbInMessageBuffer[OFFSET_BCLOCKSTATUS] = CRD_GetClockStatus();       */
            /* Copy the bytes and the size to the send buffer */
            EP2DataSnd.pData = UsbInMessageBuffer;
            EP2DataSnd.Count = OFFSET_BCLOCKSTATUS + 1;
            USB_DataInStage2();
            //Put the pointer to the start position
            UsbInMessageBuffer -= OFFSET_BCLOCKSTATUS;
    }
    
    void smcDataBlock(BYTE Err, BYTE* Mess)
    {
            *(UsbInMessageBuffer+OFFSET_BMESSAGETYPE) = Mess[0];
            *(UsbInMessageBuffer+OFFSET_BSTATUS) = CRD_GetSlotStatus();
            *(UsbInMessageBuffer+OFFSET_DWLENGTH) = Mess[OFFSET_DWLENGTH];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+1) = Mess[OFFSET_DWLENGTH+1];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+2) = Mess[OFFSET_DWLENGTH+2];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+3) = Mess[OFFSET_DWLENGTH+3];
            *(UsbInMessageBuffer+OFFSET_BSEQ)   =  *(UsbMessageBuffer+OFFSET_BSEQ);
            *(UsbInMessageBuffer+OFFSET_BSEQ+1) = Mess[OFFSET_BSEQ+1];
            *(UsbInMessageBuffer+OFFSET_BSEQ+2) = Mess[OFFSET_BSEQ+2];
            *(UsbInMessageBuffer+OFFSET_BCHAINPARAMETER) = Mess[OFFSET_BCHAINPARAMETER];
    
            for(index = 0; index<10; index++)
                    Result[index] = *(UsbInMessageBuffer+index);
            /* Copy the bytes and the size to the send buffer */
            EP2DataSnd.pData = UsbInMessageBuffer;
            EP2DataSnd.Count = OFFSET_BCHAINPARAMETER + 5;
            USB_DataInStage2();
    
            //Put the pointer to the start position
            UsbInMessageBuffer += OFFSET_BCHAINPARAMETER;
    }
    
    BYTE PC_to_RDR_IccPowerOFF(void)
    {
            if(*(UsbMessageBuffer+OFFSET_BSLOT) != 0)
                    return SLOTERROR_BAD_SLOT;
            if(*(UsbMessageBuffer+OFFSET_DWLENGTH) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+1) != 0
                    || *(UsbMessageBuffer+OFFSET_DWLENGTH+2) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+3) != 0)
                    return SLOTERROR_BAD_LENTGH;
            if( *(UsbMessageBuffer+OFFSET_ABRFU_3B) != 0 || *(UsbMessageBuffer+OFFSET_ABRFU_3B+1) != 0
                    ||*(UsbMessageBuffer+OFFSET_ABRFU_3B+2) != 0)
                    return SLOTERROR_BAD_ABRFU_3B;
    
      return SLOT_NO_ERROR;
    }
    
    BYTE PC_to_RDR_IccPowerON (void)
    {
            //BYTE ErrorCode;
    //      BYTE Voltage;
    
            if(*(UsbMessageBuffer+OFFSET_BSLOT) != 0)
                    return SLOTERROR_BAD_SLOT;
            if(*(UsbMessageBuffer+OFFSET_DWLENGTH) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+1) != 0
               || *(UsbMessageBuffer+OFFSET_DWLENGTH+2) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+3) != 0)
                    return SLOTERROR_BAD_LENTGH;
            if(*(UsbMessageBuffer+OFFSET_BPOWERSELECT) >= 0x04)
                    return SLOTERROR_BAD_POWERSELECT;
            if(*(UsbMessageBuffer+OFFSET_ABRFU_3B) != 0 || *(UsbMessageBuffer+OFFSET_ABRFU_3B+1) != 0)
                    return SLOTERROR_BAD_ABRFU_2B;
    
            return SLOT_NO_ERROR;
    }
    

    Thanks

Reply
  • Here the functions:

    void smcSlotStatus(BYTE Err, BYTE* Mess)         //cnt = 10
    {
        *(UsbInMessageBuffer+OFFSET_BMESSAGETYPE) = Mess[0];
            *(UsbInMessageBuffer+OFFSET_BSTATUS) = CRD_GetSlotStatus();     //0x00
            *(UsbInMessageBuffer+OFFSET_BERROR) = Mess[OFFSET_BERROR];
            if(Err != SLOT_NO_ERROR)
            {
            *(UsbInMessageBuffer+OFFSET_BSTATUS) += 0x40;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+1) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+2) = 0x00;
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+3) = 0x00;
            *(UsbInMessageBuffer+OFFSET_BERROR) = Err;
            };
            *(UsbInMessageBuffer+OFFSET_BSEQ)   =  *(UsbMessageBuffer+OFFSET_BSEQ);
            *(UsbInMessageBuffer+OFFSET_BSEQ+1) = Mess[OFFSET_BSEQ+1];
            *(UsbInMessageBuffer+OFFSET_BCLOCKSTATUS) = Mess[OFFSET_BCLOCKSTATUS];
            //UsbInMessageBuffer[OFFSET_BCLOCKSTATUS] = CRD_GetClockStatus();       */
            /* Copy the bytes and the size to the send buffer */
            EP2DataSnd.pData = UsbInMessageBuffer;
            EP2DataSnd.Count = OFFSET_BCLOCKSTATUS + 1;
            USB_DataInStage2();
            //Put the pointer to the start position
            UsbInMessageBuffer -= OFFSET_BCLOCKSTATUS;
    }
    
    void smcDataBlock(BYTE Err, BYTE* Mess)
    {
            *(UsbInMessageBuffer+OFFSET_BMESSAGETYPE) = Mess[0];
            *(UsbInMessageBuffer+OFFSET_BSTATUS) = CRD_GetSlotStatus();
            *(UsbInMessageBuffer+OFFSET_DWLENGTH) = Mess[OFFSET_DWLENGTH];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+1) = Mess[OFFSET_DWLENGTH+1];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+2) = Mess[OFFSET_DWLENGTH+2];
            *(UsbInMessageBuffer+OFFSET_DWLENGTH+3) = Mess[OFFSET_DWLENGTH+3];
            *(UsbInMessageBuffer+OFFSET_BSEQ)   =  *(UsbMessageBuffer+OFFSET_BSEQ);
            *(UsbInMessageBuffer+OFFSET_BSEQ+1) = Mess[OFFSET_BSEQ+1];
            *(UsbInMessageBuffer+OFFSET_BSEQ+2) = Mess[OFFSET_BSEQ+2];
            *(UsbInMessageBuffer+OFFSET_BCHAINPARAMETER) = Mess[OFFSET_BCHAINPARAMETER];
    
            for(index = 0; index<10; index++)
                    Result[index] = *(UsbInMessageBuffer+index);
            /* Copy the bytes and the size to the send buffer */
            EP2DataSnd.pData = UsbInMessageBuffer;
            EP2DataSnd.Count = OFFSET_BCHAINPARAMETER + 5;
            USB_DataInStage2();
    
            //Put the pointer to the start position
            UsbInMessageBuffer += OFFSET_BCHAINPARAMETER;
    }
    
    BYTE PC_to_RDR_IccPowerOFF(void)
    {
            if(*(UsbMessageBuffer+OFFSET_BSLOT) != 0)
                    return SLOTERROR_BAD_SLOT;
            if(*(UsbMessageBuffer+OFFSET_DWLENGTH) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+1) != 0
                    || *(UsbMessageBuffer+OFFSET_DWLENGTH+2) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+3) != 0)
                    return SLOTERROR_BAD_LENTGH;
            if( *(UsbMessageBuffer+OFFSET_ABRFU_3B) != 0 || *(UsbMessageBuffer+OFFSET_ABRFU_3B+1) != 0
                    ||*(UsbMessageBuffer+OFFSET_ABRFU_3B+2) != 0)
                    return SLOTERROR_BAD_ABRFU_3B;
    
      return SLOT_NO_ERROR;
    }
    
    BYTE PC_to_RDR_IccPowerON (void)
    {
            //BYTE ErrorCode;
    //      BYTE Voltage;
    
            if(*(UsbMessageBuffer+OFFSET_BSLOT) != 0)
                    return SLOTERROR_BAD_SLOT;
            if(*(UsbMessageBuffer+OFFSET_DWLENGTH) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+1) != 0
               || *(UsbMessageBuffer+OFFSET_DWLENGTH+2) != 0 || *(UsbMessageBuffer+OFFSET_DWLENGTH+3) != 0)
                    return SLOTERROR_BAD_LENTGH;
            if(*(UsbMessageBuffer+OFFSET_BPOWERSELECT) >= 0x04)
                    return SLOTERROR_BAD_POWERSELECT;
            if(*(UsbMessageBuffer+OFFSET_ABRFU_3B) != 0 || *(UsbMessageBuffer+OFFSET_ABRFU_3B+1) != 0)
                    return SLOTERROR_BAD_ABRFU_2B;
    
            return SLOT_NO_ERROR;
    }
    

    Thanks

Children
More questions in this forum