How is interaction with CDC device with no interface endpoints working? I'm working on uploading to Digispark board. It uses micronucleus bootloader and i can see uploader code. I've modified it a bit to see interfaces and endpoints count:

    nucleus-&gt;device = usb_open(dev);

    // added by me - start
    int interfaces, endpoints, j;
    struct usb_interface_descriptor *interface = NULL;

    interfaces = dev-&gt;config-&gt;bNumInterfaces;
    fprintf(stderr, "Found interfaces: %i\n", interfaces);

    interface = &amp;(dev-&gt;config-&gt;interface[0].altsetting[0]);
    fprintf(stderr, "Endpoints: %i\n", interface-&gt;bNumEndpoints);
    // added by me - end

    // get nucleus info
    unsigned char buffer[4];
    int res = usb_control_msg(nucleus-&gt;device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT);


I wonder how it's working because interface #0 has no endpoints:

$./micronucleus --type intel-hex /tmp/Start.ino.hex 
&gt; Please plug in the device ... 
&gt; Press CTRL+C to terminate the program.
Found interfaces: 1
Endpoints: 0
&gt; Device is found!
connecting: 40% complete
&gt; Device has firmware version 1.6
&gt; Available space for user applications: 6012 bytes
&gt; Suggested sleep time between sending pages: 8ms
&gt; Whole page count: 94  page size: 64
&gt; Erase function sleep duration: 752ms
parsing: 60% complete
&gt; Erasing the memory ...
erasing: 80% complete
&gt; Starting to upload ...
writing: 100% complete
&gt;&gt; Micronucleus done. Thank you!


Usually i expect interface to have 2 endpoints (in &amp; out from usb.h):

#define USB_ENDPOINT_IN         0x80
#define USB_ENDPOINT_OUT        0x00


Can anyone explain me how usb_control_msg(nucleus-&gt;device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer, 4, MICRONUCLEUS_USB_TIMEOUT); is working without endpoint?
Micronucleus uses control transfers to upload code (it's not a CDC device). You don't need an endpoint for control transfers - they use the implicit endpoint 0 that is always present whether you define one or not.

You only need to define endpoints for interfaces that want to communicate using bulk, interrupt or isochronous transfers.

Bus 003 Device 073: ID 16d0:0753 MCS Digistump DigiSpark
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x16d0 MCS
  idProduct          0x0753 Digistump DigiSpark
  bcdDevice            1.02
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           18
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         0 (Defined at Interface level)
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
Device Status:     0x18c0
  (Bus Powered)
  Debug Mode