Exemple #1
0
int
usbGetLanguage (
  UsbDevice *device,
  uint16_t *language,
  int timeout
) {
  UsbDescriptor descriptor;
  ssize_t size = usbGetDescriptor(device, UsbDescriptorType_String,
                              0, 0, &descriptor, timeout);

  if (size != -1) {
    if (size >= 4) {
      *language = getLittleEndian16(descriptor.string.wData[0]);
      logMessage(LOG_CATEGORY(USB_IO), "USB language: %02X", *language);
      return 1;
    } else {
      logMessage(LOG_ERR, "USB language code string too short: %"PRIssize, size);
      errno = EIO;
    }
  } else {
    logMessage(LOG_ERR, "USB language code string read error");
  }

  return 0;
}
Exemple #2
0
const UsbConfigurationDescriptor *
usbConfigurationDescriptor (
  UsbDevice *device
) {
  if (!device->configuration) {
    unsigned char current;

    if (device->descriptor.bNumConfigurations < 2) {
      current = 1;
    } else if (!usbGetConfiguration(device, &current)) {
      current = 0;
    }

    if (current) {
      UsbDescriptor descriptor;
      unsigned char number;

      for (number=0; number<device->descriptor.bNumConfigurations; number++) {
        int size = usbGetDescriptor(device, UsbDescriptorType_Configuration,
                                    number, 0, &descriptor, 1000);
        if (size == -1) {
          logMessage(LOG_WARNING, "USB configuration descriptor not readable: %d", number);
        } else if (descriptor.configuration.bConfigurationValue == current) {
          break;
        }
      }

      if (number < device->descriptor.bNumConfigurations) {
        int length = getLittleEndian16(descriptor.configuration.wTotalLength);
        UsbDescriptor *descriptors;

        if ((descriptors = malloc(length))) {
          ssize_t size;

          if (length > sizeof(descriptor)) {
            size = usbControlRead(device, UsbControlRecipient_Device, UsbControlType_Standard,
                                  UsbStandardRequest_GetDescriptor,
                                  (UsbDescriptorType_Configuration << 8) | number,
                                  0, descriptors, length, 1000);
          } else {
            memcpy(descriptors, &descriptor, (size = length));
          }

          if (size != -1) {
            device->configuration = &descriptors->configuration;
          } else {
            free(descriptors);
          }
        } else {
          logSystemError("USB configuration descriptor allocate");
        }
      } else {
        logMessage(LOG_ERR, "USB configuration descriptor not found: %d", current);
      }
    }
  }

  return device->configuration;
}
Exemple #3
0
int
usbGetDeviceDescriptor (
  UsbDevice *device,
  UsbDeviceDescriptor *descriptor
) {
  UsbDescriptor desc;
  int size = usbGetDescriptor(device, UsbDescriptorType_Device, 0, 0, &desc, 1000);

  if (size != -1) {
    *descriptor = desc.device;
  }

  return size;
}
Exemple #4
0
int
usbGetLanguage (
  UsbDevice *device,
  uint16_t *language,
  int timeout
) {
  UsbDescriptor descriptor;
  int size = usbGetDescriptor(device, UsbDescriptorType_String,
                              0, 0, &descriptor, timeout);
  if (size != -1) {
    if (size >= 4) {
      *language = getLittleEndian16(descriptor.string.wData[0]);
      logMessage(LOG_DEBUG, "USB Language: %02X", *language);
      return 1;
    }
    errno = EIO;
  }
  return 0;
}
Exemple #5
0
char *
usbGetString (
  UsbDevice *device,
  unsigned char number,
  int timeout
) {
  UsbDescriptor descriptor;

  if (!device->language)
    if (!usbGetLanguage(device, &device->language, timeout))
      return NULL;

  if (usbGetDescriptor(device, UsbDescriptorType_String,
                       number, device->language,
                       &descriptor, timeout) == -1)
    return NULL;

  return usbDecodeString(&descriptor.string);
}
Exemple #6
0
void usbStdInterfaceRequest(void)
{
	uint8_t bRequest = usbRequest.bRequest;
	
	if (bRequest == USB_REQ_GET_STATUS)
	{
		if (usb_state == CONFIGURED)
		{
			// all values are reserved for interfaces
			in0buf[0] = 0x00;
			in0buf[1] = 0x00;
			in0bc = 0x02;
		}
	} else if (bRequest == USB_REQ_GET_DESCRIPTOR) {
		// this requests the HID report descriptor
		usbGetDescriptor();
	} else {
		USB_EP0_STALL();
	}
}
Exemple #7
0
char *
usbGetString (
  UsbDevice *device,
  unsigned char number,
  int timeout
) {
  UsbDescriptor descriptor;

  if (!device->language) {
    if (!usbGetLanguage(device, &device->language, timeout)) {
      return NULL;
    }
  }

  if (usbGetDescriptor(device, UsbDescriptorType_String,
                       number, device->language,
                       &descriptor, timeout) == -1) {
    logMessage(LOG_ERR, "USB string read error: %u", number);
    return NULL;
  }

  return usbDecodeString(&descriptor.string);
}
Exemple #8
0
void usbStdDeviceRequest(void)
{
	switch (usbRequest.bRequest)
	{
	case USB_REQ_GET_STATUS:
		// We must be in ADDRESSED or CONFIGURED state, and wIndex must be 0
		if ((usb_state == ADDRESSED || usb_state == CONFIGURED)  &&  usbRequest.wIndexLSB == 0x00)
		{
			// We aren't self-powered and we don't support remote wakeup
			in0buf[0] = 0x00;
			in0buf[1] = 0x00;
			in0bc = 0x02;
		} else {
			// Stall for invalid requests
			USB_EP0_STALL();
		}
		break;

	case USB_REQ_SET_ADDRESS:
		// USB controller takes care of setting our address
		usb_state = ADDRESSED;
		break;

	case USB_REQ_GET_DESCRIPTOR:
		usbGetDescriptor();
		break;

	case USB_REQ_GET_CONFIGURATION:
	
		if (usb_state == ADDRESSED)
		{
			in0buf[0] = 0x00;
			in0bc = 0x01;
		} else if (usb_state == CONFIGURED) {
			in0buf[0] = usb_current_config;
			in0bc = 0x01;
		} else {
			// Behavior not specified in other states, so STALL
			USB_EP0_STALL();
		}

		break;

	case USB_REQ_SET_CONFIGURATION:

		if (usbRequest.wValueLSB == 0x00)
		{
			usb_state = ADDRESSED;
			usb_current_config = 0x00;
			// Since there isn't a data stage for this request,
			//   we have to explicitly clear the NAK bit
			USB_EP0_HSNAK();
		} else if (usbRequest.wValueLSB == 0x01) {
			usb_state = CONFIGURED;
			usb_current_config = 0x01;
			// Since there isn't a data stage for this request,
			//   we have to explicitly clear the NAK bit
			USB_EP0_HSNAK();
		} else {
			// Stall for invalid config values
			USB_EP0_STALL();
		}
		break;
	}
}