This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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
  • Ah after analysing the Sniffer I remark The URB IN at the Bulk IN 0x82 , Its the URB "down" one: "URB Bulk Transfer issued"
    But there is no "Reply" URB to this.

    The particularity is this urb occurs after the host send the bytes {63, 00, 00, 00, 00, 00, 03, 00, 00, 00} (PC_to_RDR_ICCPowerOff).

    So here the explanation of what is been displayed on the sniffer:
    1- The host sends {62, 00, 00, 00, 00, 00, 02, 00, 00, 00} (PC_to_RDR_ICCPowerOn)

    2- Then the device sends a URB "down" with a reply failure (4 bytes datas, nothing inside the data filed) URB Bulk Transfer failed (there is a successfull 74 bytes bulk IN tranfer before)

    3- Then the host send the bytes {63, 00, 00, 00, 00, 00, 03, 00, 00, 00} (PC_to_RDR_ICCPowerOff).

    4- Then I see my 10 bytes BULK IN transfer issue but with no reply URB.

    It seems to be a timing problem maybe!

    Do you have any idea on it?

    Thanks

Reply
  • Ah after analysing the Sniffer I remark The URB IN at the Bulk IN 0x82 , Its the URB "down" one: "URB Bulk Transfer issued"
    But there is no "Reply" URB to this.

    The particularity is this urb occurs after the host send the bytes {63, 00, 00, 00, 00, 00, 03, 00, 00, 00} (PC_to_RDR_ICCPowerOff).

    So here the explanation of what is been displayed on the sniffer:
    1- The host sends {62, 00, 00, 00, 00, 00, 02, 00, 00, 00} (PC_to_RDR_ICCPowerOn)

    2- Then the device sends a URB "down" with a reply failure (4 bytes datas, nothing inside the data filed) URB Bulk Transfer failed (there is a successfull 74 bytes bulk IN tranfer before)

    3- Then the host send the bytes {63, 00, 00, 00, 00, 00, 03, 00, 00, 00} (PC_to_RDR_ICCPowerOff).

    4- Then I see my 10 bytes BULK IN transfer issue but with no reply URB.

    It seems to be a timing problem maybe!

    Do you have any idea on it?

    Thanks

Children
  • In the first place, is smcDispatchMessage() called from the main line (or timered) polling loop?
    Or USB_EndPoint2( USB_EVT_OUT ) (ie. EP2 ISR) calls the routine?

    Either will do,
    But depending on the strategy you apply, the code flow differs significantly.



    This isn't directly concerned to current problem, but this code has another problem.

    void USB_DataInStage2 (void) {
      ...
      if (EP2DataSnd.Count > USB_MAX_PACKET0)
      {
            while(temp>USB_MAX_PACKET0)
            {
                    temp-=USB_MAX_PACKET0;
                    cnt = USB_WriteEP(0x82, EP2DataSnd.pData,USB_MAX_PACKET0);
                    EP2DataSnd.pData += cnt;
            }
            cnt = USB_WriteEP(0x82, EP2DataSnd.pData,temp);
      }
    

    In above code, the large data is split into packets of endpoint wMaxPacketSize.
    So far, so good.
    But USB_WriteEP() is repeatedly called without checking buffer empty.
    It may cause overwrite to the EP buffer.

    When USB_EndPoint2( USB_EVT_IN ) is called, it shows the timing in which the EP2 IN buffer goes empty.
    Raise a flag in USB_EndPoint2(), and poll this flag.

    Tsuneo