Пример #1
0
// Implements all the control transfers that are required by D1 of the
// ACM descriptor bmCapabilities, (USBPSTN1.20 Table 4).
void usbCallbackSetupHandler()
{
    if ((usbSetupPacket.bmRequestType & 0x7F) != 0x21)   // Require Type==Class and Recipient==Interface.
        return;

    if (!(usbSetupPacket.wIndex == CDC_CONTROL_INTERFACE_NUMBER || usbSetupPacket.wIndex == CDC_DATA_INTERFACE_NUMBER))
        return;

    switch(usbSetupPacket.bRequest)
    {
        case ACM_REQUEST_SET_LINE_CODING:                          // SetLineCoding (USBPSTN1.20 Section 6.3.10 SetLineCoding)
            usbControlWrite(sizeof(usbComLineCoding), (uint8 XDATA *)&usbComLineCoding);
            break;

        case ACM_REQUEST_GET_LINE_CODING:                          // GetLineCoding (USBPSTN1.20 Section 6.3.11 GetLineCoding)
            usbControlRead(sizeof(usbComLineCoding), (uint8 XDATA *)&usbComLineCoding);
            break;

        case ACM_REQUEST_SET_CONTROL_LINE_STATE:                   // SetControlLineState (USBPSTN1.20 Section 6.3.12 SetControlLineState)
            usbComControlLineState = usbSetupPacket.wValue;
            usbControlAcknowledge();

			if(pLineStateChangeCallback)
				pLineStateChangeCallback(usbComControlLineState);

            break;
    }

}
Пример #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;
}
Пример #3
0
static int
usbGetParameters_CDC_ACM (UsbDevice *device, uint8_t request, uint16_t value, void *data, uint16_t size) {
  ssize_t result = usbControlRead(device, UsbControlRecipient_Interface,
                                  UsbControlType_Class, request, value,
                                   device->serial.data->interface->bInterfaceNumber,
                                   data, size, 1000);

  return result != -1;
}
Пример #4
0
static ssize_t
askUsbResource (
  GioHandle *handle, uint8_t recipient, uint8_t type,
  uint8_t request, uint16_t value, uint16_t index,
  void *buffer, uint16_t size, int timeout
) {
  UsbChannel *channel = handle->channel;

  return usbControlRead(channel->device, recipient, type,
                        request, value, index, buffer, size, timeout);
}
Пример #5
0
int
usbGetConfiguration (
  UsbDevice *device,
  unsigned char *configuration
) {
  ssize_t size = usbControlRead(device, UsbControlRecipient_Device, UsbControlType_Standard,
                                UsbStandardRequest_GetConfiguration, 0, 0,
                                configuration, sizeof(*configuration), 1000);
  if (size != -1) return 1;
  logMessage(LOG_WARNING, "USB standard request not supported: get configuration");
  return 0;
}
Пример #6
0
ssize_t
usbGetDescriptor (
  UsbDevice *device,
  unsigned char type,
  unsigned char number,
  unsigned int index,
  UsbDescriptor *descriptor,
  int timeout
) {
  return usbControlRead(device, UsbControlRecipient_Device, UsbControlType_Standard,
                        UsbStandardRequest_GetDescriptor, (type << 8) | number, index,
                        descriptor->bytes, sizeof(descriptor->bytes), timeout);
}
Пример #7
0
ssize_t
usbHidGetFeature (
  UsbDevice *device,
  unsigned char interface,
  unsigned char report,
  void *buffer,
  uint16_t length,
  int timeout
) {
  return usbControlRead(device,
                        UsbControlRecipient_Interface, UsbControlType_Class,
                        UsbHidRequest_GetReport,
                        (UsbHidReportType_Feature << 8) | report, interface,
                        buffer, length, timeout);
}
static FLStatus getStatus(struct FLContext *handle, uint8 *statusBuffer, const char **error) {
	FLStatus retVal = FL_SUCCESS;
	USBStatus uStatus = usbControlRead(
		handle->device,
		CMD_MODE_STATUS,          // bRequest
		0x0000,                   // wValue : off
		0x0000,                   // wMask
		statusBuffer,
		16,                       // wLength
		1000,                     // timeout (ms)
		error
	);
	CHECK_STATUS(uStatus, FL_PROTOCOL_ERR, cleanup, "getStatus()");
cleanup:
	return retVal;
}
Пример #9
0
ssize_t
usbHidGetItems (
  UsbDevice *device,
  unsigned char interface,
  unsigned char number,
  unsigned char **items,
  int timeout
) {
  const UsbHidDescriptor *hid = usbHidDescriptor(device);

  if (hid) {
    if (number < hid->bNumDescriptors) {
      const UsbClassDescriptor *descriptor = &hid->descriptors[number];
      uint16_t length = getLittleEndian16(descriptor->wDescriptorLength);
      void *buffer = malloc(length);

      if (buffer) {
        ssize_t result = usbControlRead(device,
                                        UsbControlRecipient_Interface, UsbControlType_Standard,
                                        UsbStandardRequest_GetDescriptor,
                                        (descriptor->bDescriptorType << 8) | interface,
                                        number, buffer, length, timeout);

        if (result != -1) {
          *items = buffer;
          return result;
        }

        free(buffer);
      } else {
        logMallocError();
      }
    } else {
      logMessage(LOG_WARNING, "USB report descriptor not found: %u[%u]",
                 interface, number);
    }
  }

  return -1;
}
Пример #10
0
// usbStandardDeviceRequestHandler(): Implementation of USB2.0 Section 9.4, Standard Device Requests.
// This function gets called whenever we receive a SETUP packet on endpoint zero with the requestType
// field set to STANDARD.  This function reads the SETUP packet and uses that to set the control
// transfer state variables with all the information needed to respond to the request.
// Assumption: controlTransferState is CONTROL_TRANSFER_STATE_NONE when this function is called.
static void usbStandardDeviceRequestHandler()
{
    // Prepare a convenient two-byte buffer for sending 1 or 2 byte responses.
    static XDATA uint8 response[2];
    response[0] = 0;
    response[1] = 0;

    // Now we decide how to handle the new setup packet.  There are several possibilities:
    // * Invalid: The SETUP packet had a problem with it, or we don't support the feature,
    //     so we need to STALL the next transaction to indicate an request error to the host.
    // * Control Read:  We must send some data to the computer, so we need to decide
    //     where the data is coming from (address, plus RAM/ROM selection)
    // * Control Write with no data phase: We need to prepare for the status phase, where
    //     our device must send a zero-length EP0 IN packet to indicate success.
    // * Control Write with data phase: The computer will send data to us, and we need to
    //     decide where in RAM to put it.  (No standard device requests use this type,
    //     so ignore this case.)

    switch(usbSetupPacket.bRequest)
    {
        case USB_REQUEST_GET_DESCRIPTOR: // USB Spec 9.4.3 Get Descriptor
        {
            switch(usbSetupPacket.wValue >> 8)
            {
                case USB_DESCRIPTOR_TYPE_DEVICE:
                {
                    controlTransferPointer = (uint8 XDATA *)&usbDeviceDescriptor;
                    controlTransferBytesLeft = sizeof(USB_DESCRIPTOR_DEVICE);
                    break;
                }
                case USB_DESCRIPTOR_TYPE_CONFIGURATION:
                {
                    if ((usbSetupPacket.wValue & 0xFF) != 0)
                    {
                        // Invalid configuration index.
                        return;
                    }

                    // The configuration descriptor has an application-dependent size, which
                    // we determine by reading the 3rd and 4th byte.
                    controlTransferPointer = (uint8 XDATA *)usbConfigurationDescriptor;
                    controlTransferBytesLeft = *(uint16 *)&usbConfigurationDescriptor[2];
                    break;
                }
                case USB_DESCRIPTOR_TYPE_STRING:
                {
                    if ((usbSetupPacket.wValue & 0xFF) >= usbStringDescriptorCount)
                    {
                        // This is either an invalid string index or it is 0xEE,
                        // which is defined by Microsoft OS Descriptors 1.0.
                        // This library provides no features for handling such requests,
                        // but we call the user's callback in case they want to.
                        usbCallbackClassDescriptorHandler();
                        return;
                    }

                    controlTransferPointer = (uint8 XDATA *)usbStringDescriptors[usbSetupPacket.wValue & 0xFF];
                    controlTransferBytesLeft = controlTransferPointer[0];
                    break;
                }
                default:
                {
                    // see if the class recognizes the descriptor type; it should call usbControlRead if it does
                    usbCallbackClassDescriptorHandler();

                    if (controlTransferState == CONTROL_TRANSFER_STATE_NONE)
                    {
                        // unknown type of descriptor
                        return;
                    }
                    break;
                }
            }

            controlTransferState = CONTROL_TRANSFER_STATE_READ;
            return;
        }
        case USB_REQUEST_SET_ADDRESS: // USB Spec, 9.4.6 Set Address
        {
            // Get ready to set the address when the status phase is complete.
            // We always set the most siginificant bit, because .device_address might be 0
            // and that is a valid request, meaning we should revert to address 0.
            //pendingDeviceAddress = (usbSetupPacket.wValue & 0xFF) | 0x80;

            USBADDR = (uint8)usbSetupPacket.wValue;
            usbDeviceState = ((uint8)usbSetupPacket.wValue) ? USB_STATE_ADDRESS : USB_STATE_DEFAULT;

            // Get ready to provide a handshake.
            usbControlAcknowledge();
            return;
        }
        case USB_REQUEST_SET_CONFIGURATION: // USB Spec, 9.4.7 Set Configuration
        {
            // Assumption: there is only one configuration and its value is 1.
            switch(usbSetupPacket.wValue)
            {
                case 0:
                {
                    // We have been deconfigured.

                    // TODO: Add resetNonzeroEndpoints() and call it here.

                    if (usbDeviceState > USB_STATE_ADDRESS)
                    {
                        usbDeviceState = USB_STATE_ADDRESS;
                    }
                    break;
                }
                case 1:
                {
                    // The device has been configured.  This is normal operating
                    // state of a USB device.  We can now start using non-zero
                    // endpoints.
                    usbDeviceState = USB_STATE_CONFIGURED;
                    usbCallbackInitEndpoints();
                    break;
                }
                default:
                {
                    // Invalid configuration value, so STALL.
                    return;
                }
            }

            // Get ready to provide a handshake.
            usbControlAcknowledge();
            return;
        }
        case USB_REQUEST_GET_CONFIGURATION: // USB Spec 9.4.2 Get Configuration
        {
            // Assumption: there is only one configuration and its value is 1.
            response[0] = (usbDeviceState == USB_STATE_CONFIGURED) ? 1 : 0;
            usbControlRead(1, response);
            return;
        }
        case USB_REQUEST_GET_INTERFACE: // USB Spec 9.4.4 Get Interface
        {
            // Assumption: the "alternate setting number" of each interface
            //   is zero and there are no alternate settings.
            // Assumption: interface numbers go from 0 to
            //   config->interface_count-1, with no gaps.

            if (usbDeviceState < USB_STATE_CONFIGURED)
            {
                // Invalid request because we have not reached the configured state.
                return;
            }

            if (usbSetupPacket.wIndex >= ((USB_DESCRIPTOR_CONFIGURATION *)&usbConfigurationDescriptor)->bNumInterfaces)
            {
                // Invalid index: there is no such interface.
                return;
            }

            // Send a single-byte response of "0".
            // Assumption: response[0] == 0
            usbControlRead(1, response);
            return;
        }
        case USB_REQUEST_GET_STATUS: // USB Spec 9.4.5 Get Status
        {
            switch(usbSetupPacket.recipient)
            {
                case USB_RECIPIENT_DEVICE:
                {
                    // See USB Spec Table 9-4.
                    response[0] = vinPowerPresent() ? 1 : 0;
                    // Assumption: response[1] == 0
                    usbControlRead(2, response);
                    return;
                }
                case USB_RECIPIENT_INTERFACE:
                {
                    if (usbDeviceState < USB_STATE_CONFIGURED && usbSetupPacket.wIndex != 0)
                    {
                        // It is invalid to ask about interfaces other than 0 before the
                        // configured state.
                        return;
                    }

                    if (usbSetupPacket.wIndex >= ((USB_DESCRIPTOR_CONFIGURATION *)&usbConfigurationDescriptor)->bNumInterfaces)
                    {
                        // Invalid index: there is no such interface.
                        return;
                    }

                    // Send a 2-byte response of 0,0 (all of the bits are reserved)
                    // Assumption: response[0] == 0 and response[1] == 0
                    usbControlRead(2, response);
                    return;
                }
                case USB_RECIPIENT_ENDPOINT:
                {
                    if ((usbSetupPacket.wValue & 15) == 0)
                    {
                        // We don't support the halt feature on Endpoint 0
                        // (the USB Spec does not require or recommend it).
                        return;
                    }

                    if (usbDeviceState < USB_STATE_CONFIGURED)
                    {
                        // It is invalid to ask about non-zero endpoints before
                        // the configured state.
                        return;
                    }

                    // Assumption: We don't have a USB halt feature, i.e. we
                    // don't stall on non-zero endpoints.

                    // Send a 2-byte response of 0,0.
                    // Assumption: response[0] == 0 and response[1] == 0
                    usbControlRead(2, response);
                    return;
                }
            }
            return;
        }

        // Here are some more standard device requests we would need
        // to be USB compliant.  We didn't use them yet on any of our
        // PIC devices and it has not caused a problem as far as I
        // know.  We pay lip service to them here just in case they are
        // needed by some future driver.
        case USB_REQUEST_SET_FEATURE:
        case USB_REQUEST_CLEAR_FEATURE:
        {
            // Acknowledge the request but don't do anything.
            usbControlAcknowledge();
            return;
        }
        case USB_REQUEST_SYNCH_FRAME:
        {
            // Send a two-byte response of 0,0.
            usbControlRead(2, response);
            return;
        }
    }
}
Пример #11
0
static int
readDevice (unsigned char request, void *buffer, int length) {
  return usbControlRead(usbChannel->device, MT_REQUEST_RECIPIENT, MT_REQUEST_TYPE,
                        request, 0, 0, buffer, length, MT_REQUEST_TIMEOUT);
}