Exemple #1
0
static void handle_osmosdr_write(const USBGenericRequest* request)
{
	uint16_t func = USBGenericRequest_GetValue(request);
	int len = USBGenericRequest_GetLength(request);
	int i;
/*
	printf("OsmoSDR SET request: type:%d, request:%d, value:%04x, index: %04x, length: %d\n\r",
		USBGenericRequest_GetType(request),
		USBGenericRequest_GetRequest(request),
		USBGenericRequest_GetValue(request),
		USBGenericRequest_GetIndex(request),
		len);
*/
	for(i = 0; i < ARRAY_SIZE(g_writeRequests); i++) {
		if(g_writeRequests[i].func == func)
			break;
	}
	if(i == ARRAY_SIZE(g_writeRequests)) {
		USBD_Stall(0);
		return;
	}
	if(len != g_writeRequests[i].len) {
		USBD_Stall(0);
		return;
	}

	g_writeState.func = func;

	if(len > 0)
		USBD_Read(0, g_writeState.data, len, finalize_write, 0);
	else finalize_write(NULL, 0, 0, 0);
}
Exemple #2
0
//-----------------------------------------------------------------------------
/// Handles composite-specific USB requests sent by the host, and forwards
/// standard ones to the USB device driver.
/// \param request Pointer to a USBGenericRequest instance.
//-----------------------------------------------------------------------------
void MULTIDriver_RequestHandler(const USBGenericRequest *request)
{
    // Check if this is a class request
    if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {

        unsigned char rc = 0;

        //rc = CCID_RequestHandler(request);
        if (!rc) {
            TRACE_WARNING(
              "MULTIDriver_RequestHandler: Unsupported request (%d)\n\r",
              USBGenericRequest_GetRequest(request));
            USBD_Stall(0);
        }

    }
    // Check if this is a standard request
    else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {

        unsigned char rc = 0;

        // Forward request to the standard handler
        if (rc == 0)
            USBDDriver_RequestHandler(&(usbdDriver), request);
    }
    // Unsupported request type
    else {
        TRACE_WARNING(
          "MULTIDriver_RequestHandler: Unsupported request type (%d)\n\r",
          USBGenericRequest_GetType(request));
        USBD_Stall(0);
    }
}
Exemple #3
0
void fastsource_req_hdlr(const USBGenericRequest *request)
{
	unsigned char entity;
	unsigned char interface;

	switch (USBGenericRequest_GetType(request)) {
	case USBGenericRequest_STANDARD:
		USBDDriver_RequestHandler(&fast_source_driver, request);
		return;
	case USBGenericRequest_CLASS:
		/* continue below */
		break;
	default:
		TRACE_WARNING("Unsupported request type %u\n\r",
				USBGenericRequest_GetType(request));
		USBD_Stall(0);
		return;
	}

	switch (USBGenericRequest_GetRequest(request)) {
	case AUDGenericRequest_SETCUR:
		entity = AUDGenericRequest_GetEntity(request);
		interface = AUDGenericRequest_GetInterface(request);
		if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) ||
		     (entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) &&
		    (interface == AUDDLoopRecDriverDescriptors_CONTROL)) {
			fastsource_set_feat_cur_val(entity,
				AUDFeatureUnitRequest_GetChannel(request),
				AUDFeatureUnitRequest_GetControl(request),
				USBGenericRequest_GetLength(request));
		} else {
			TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r",
					USBGenericRequest_GetIndex(request));
			USBD_Stall(0);
		}
		break;
	case AUDGenericRequest_GETCUR:
		entity = AUDGenericRequest_GetEntity(request);
		interface = AUDGenericRequest_GetInterface(request);
		if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) ||
		     (entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) &&
		    (interface == AUDDLoopRecDriverDescriptors_CONTROL)) {
			fastsource_get_feat_cur_val(entity,
				AUDFeatureUnitRequest_GetChannel(request),
				AUDFeatureUnitRequest_GetControl(request),
				USBGenericRequest_GetLength(request));
		} else {
			TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r",
					USBGenericRequest_GetIndex(request));
			USBD_Stall(0);
		}
		break;
	default:
		TRACE_WARNING("Unsupported request %u\n\r",
				USBGenericRequest_GetIndex(request));
		USBD_Stall(0);
		break;
	}
}
//------------------------------------------------------------------------------
/// Sets the current value of a particular Feature control of a channel.
/// \param entity Entity number.
/// \param channel Channel number.
/// \param control Control selector value (see TODO).
/// \param length Length of the data containing the new value.
//------------------------------------------------------------------------------
static void AUDDSpeakerDriver_SetFeatureCurrentValue(unsigned char entity,
                                                     unsigned char channel,
                                                     unsigned char control,
                                                     unsigned short length)
{
    TRACE_INFO_WP("sFeature ");
    TRACE_DEBUG("\b(E%d, CS%d, CN%d, L%d) ",
                           entity, control, channel, length);

    // Check the the requested control is supported
    // Control/channel combination not supported
    if ((control == AUDFeatureUnitRequest_MUTE)
        && (channel < (AUDDSpeakerDriver_NUMCHANNELS+1))
        && (length == 1)) {

        unsigned int argument = channel; // Avoids compiler warning
        USBD_Read(0, // Endpoint #0
                  &muted,
                  sizeof(muted),
                  (TransferCallback) AUDDSpeakerDriver_MuteReceived,
                  (void *) argument);
    }
    // Control/channel combination not supported
    else {

        USBD_Stall(0);
    }
}
/**
 * Handles audio-specific USB requests sent by the host, and forwards
 * standard ones to the USB device driver.
 * \param request Pointer to a USBGenericRequest instance.
 */
void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request)
{
    AUDDSpeakerDriver *pAudd = &auddSpeakerDriver;
    AUDDSpeakerPhone *pAudf  = &pAudd->fun;
    USBDDriver *pUsbd = pAudf->pUsbd;

    TRACE_INFO_WP("NewReq ");

    /* Handle Audio Class requests */
    if (AUDDSpeakerPhone_RequestHandler(pAudf, request) == USBRC_SUCCESS) {
        return;
    }

    /* Handle STD requests */
    if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {

        USBDDriver_RequestHandler(pUsbd, request);
    }
    /* Unsupported request */
    else {

        TRACE_WARNING(
            "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d,%x)\n\r",
            USBGenericRequest_GetType(request),
            USBGenericRequest_GetRequest(request));
        USBD_Stall(0);
    }
}
/**
 * Handles composite-specific USB requests sent by the host, and forwards
 * standard ones to the USB device driver.
 * \param request Pointer to a USBGenericRequest instance.
 */
void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request)
{
    CDCDSerialPort *pCdcd = 0;
    USBDDriver *pUsbd = 0;
    uint32_t rc, i;

    TRACE_INFO_WP("NewReq ");

    for (i = 0; i < NUM_PORTS; i ++) {
        pCdcd = &dualcdcdDriver.cdcdSerialPort[i];
        rc = CDCDSerialPort_RequestHandler(pCdcd, request);
        if (rc == USBRC_SUCCESS)
            break;
    }

    /* Not handled by CDC Serial */
    if (rc != USBRC_SUCCESS) {
        if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
            pUsbd = pCdcd->pUsbd;
            USBDDriver_RequestHandler(pUsbd, request);
        }
        else {
            TRACE_WARNING(
              "DUALCDCDDriver_RequestHandler: Unsupported request (%d,%d)\n\r",
              USBGenericRequest_GetType(request),
              USBGenericRequest_GetRequest(request));
            USBD_Stall(0);
        }
    }

}
Exemple #7
0
/**
 * Sets the active setting of the given interface if the configuration supports
 * it; otherwise, the control pipe is STALLed. If the setting of an interface
 * changes.
 * \parma pDriver  Pointer to a USBDDriver instance.
 * \parma infnum  Interface number.
 * \parma setting  New active setting for the interface.
 */
static void SetInterface(
    USBDDriver *pDriver,
    uint8_t infnum,
    uint8_t setting)
{
    /* Make sure alternate settings are supported */

    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        /* Change the current setting of the interface and trigger the callback */
        /* if necessary */
        if (pDriver->pInterfaces[infnum] != setting) {

            pDriver->pInterfaces[infnum] = setting;
            USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
        }

        /* Acknowledge the request */

        USBD_Write(0, 0, 0, 0, 0);
    }
}
Exemple #8
0
static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel,
				   uint8_t control, uint8_t length)
{
	TRACE_INFO("set_feat(E%u, CO%u, CH%u, L%u) ", entity, channel, control, length);
	if (channel == 0 && control == AUDFeatureUnitDescriptor_MUTE && length == 1)
		USBD_Read(0, &usb_state.muted, sizeof(usb_state.muted), 0, 0);
	else
		USBD_Stall(0);
}
Exemple #9
0
static void handle_osmosdr_read(const USBGenericRequest* request)
{
	int len = USBGenericRequest_GetLength(request);
	printf("OsmoSDR GET request: type:%d, request:%d, value:%d, index: %d, length: %d\n\r",
		USBGenericRequest_GetType(request),
		USBGenericRequest_GetRequest(request),
		USBGenericRequest_GetValue(request),
		USBGenericRequest_GetIndex(request),
		len);
	USBD_Stall(0);
}
Exemple #10
0
//------------------------------------------------------------------------------
/// Sends the currently active setting of the given interface to the USB
/// host. If alternate settings are not supported, this function STALLs the
/// control pipe.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param infnum  Interface number.
//------------------------------------------------------------------------------
static void GetInterface(
    const USBDDriver *pDriver,
    unsigned char infnum)
{
    // Make sure alternate settings are supported, or STALL the control pipe
    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        // Sends the current interface setting to the host
        USBD_Write(0, &(pDriver->pInterfaces[infnum]), 1, 0, 0);
    }
}
Exemple #11
0
/**
 * Handle the SET_CUR request.
 * \param pAudf Pointer to AUDDSpeakerPhone instance.
 * \param pReq  Pointer to USBGenericRequest instance.
 */
static void AUDD_SetCUR(
    AUDDSpeakerPhone *pAudf,
    const USBGenericRequest* pReq)
{
    uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
    uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
    uint8_t bLength = USBGenericRequest_GetLength(pReq);
    uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
    uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
    uint8_t bSet = 1;
    AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
    TransferCallback fCallback;

    TRACE_INFO_WP("sCUR ");
    TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);

    /* Set Mute to AC, 1 byte */
    if (bCtrl == AUDFeatureUnitRequest_MUTE
        && bLength == 1
        && pAuds) {
        fCallback = (TransferCallback) AUDD_MuteReceived;
    }
    else if (bCtrl == AUDFeatureUnitRequest_VOLUME
        && bLength == 2
        && pAuds && pAuds->pwVolumes) {
        fCallback = (TransferCallback) AUDD_VolumeReceived;
    }
    else
        bSet = 0;

    if (bSet) {

        auddXfrData.pStream = pAuds;
        auddXfrData.bEntity = bEntity;
        auddXfrData.bCh     = bCh;
        USBD_Read(0,
                  &auddXfrData.usbBuffer,
                  bLength,
                  fCallback,
                  (void *) &auddXfrData);
    }
    else {

        USBD_Stall(0);
    }

}
Exemple #12
0
/**
 * Callback function which should be invoked after the data of a
 * SetLineCoding request has been retrieved. Sends a zero-length packet
 * to the host for acknowledging the request.
 * \param pCdcd Pointer to CDCDSerialPort instance.
 */
static void _SetLineCodingCallback(CDCDSerialPort * pCdcd)
{
    uint32_t exec = 1;
    if (pCdcd->fEventHandler) {
        uint32_t rc = pCdcd->fEventHandler(
                          CDCDSerialPortEvent_SETLINECODING,
                          (uint32_t)(&lineCoding),
                          pCdcd->pArg);
        if (rc == USBD_STATUS_SUCCESS) {
            pCdcd->lineCoding.dwDTERate   = lineCoding.dwDTERate;
            pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat;
            pCdcd->lineCoding.bParityType = lineCoding.bParityType;
            pCdcd->lineCoding.bDataBits   = lineCoding.bDataBits;
        } else
            exec = 0;
    }
    if (exec)   USBD_Write(0, 0, 0, 0, 0);
    else        USBD_Stall(0);
}
Exemple #13
0
/**
 * Sends the current status of an endpoints to the USB host.
 * \param bEndpoint  Endpoint number.
 */
static void GetEndpointStatus(uint8_t bEndpoint)
{
    static unsigned short data;

    data = 0;

    switch (USBD_HAL_Halt(bEndpoint, 0xFF)) {

        case USBD_STATUS_INVALID_PARAMETER: /* the endpoint not exists */
            USBD_Stall(0);
            break;

        case 1:
            data = 1;
        case 0:
            /* Send the endpoint status */
            USBD_Write(0, &data, 2, 0, 0);
            break;
    }
}
Exemple #14
0
//------------------------------------------------------------------------------
/// Sends the current status of an endpoints to the USB host.
/// \param bEndpoint  Endpoint number.
//------------------------------------------------------------------------------
static void GetEndpointStatus(unsigned char bEndpoint)
{
    unsigned short data = 0;

    // Check if the endpoint exists
    if (bEndpoint > BOARD_USB_NUMENDPOINTS) {

        USBD_Stall(0);
    }
    else {

        // Check if the endpoint if currently halted
        if (USBD_IsHalted(bEndpoint)) {

            data = 1;
        }
        
        // Send the endpoint status
        USBD_Write(0, &data, 2, 0, 0);
    }
}
Exemple #15
0
//-----------------------------------------------------------------------------
/// Sends the current value of a particular channel Feature to the USB host.
/// \param channel Number of the channel whose feature will be sent.
/// \param control The feature control that will be sent.
/// \param length The feature data size.
//-----------------------------------------------------------------------------
static void AUDD_GetFeatureCurrentValue(unsigned char channel,
                                        unsigned char control,
                                        unsigned char length)
{
    TRACE_INFO_WP("gFeature ");
    TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length);

    // Check that the requested control is supported
    // Master channel mute control
    if ((control == AUDFeatureUnitRequest_MUTE)
        && (channel < (AUDD_NUMCHANNELS+1))
        && (length == 1)) {

        muted = auddSpeakerChannels[channel].muted;
        USBD_Write(0, &muted, sizeof(muted), 0, 0);
    }
    else {

        USBD_Stall(0);
    }
}
Exemple #16
0
/**
 * Handle the GET_CUR request.
 * \param pAudf Pointer to AUDDSpeakerPhone instance.
 * \param pReq  Pointer to USBGenericRequest instance.
 */
static void AUDD_GetCUR(
    AUDDSpeakerPhone *pAudf,
    const USBGenericRequest *pReq)
{
    uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
    uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
    uint8_t bLength = USBGenericRequest_GetLength(pReq);
    uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
    uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
    uint8_t bGet = 1;
    AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);

    TRACE_INFO_WP("gCUR ");
    TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);

    /* Get Mute 1 byte */
    if (bCtrl == AUDFeatureUnitRequest_MUTE
        && bLength == 1
        && pAuds) {
        auddXfrData.usbBuffer = ((pAuds->bmMute & (1<<bCh)) > 0);
    }
    else if (bCtrl == AUDFeatureUnitRequest_VOLUME
        && bLength == 2
        && pAuds && pAuds->pwVolumes) {
        auddXfrData.usbBuffer = pAuds->pwVolumes[bCh];
    }
    else
        bGet = 0;

    if (bGet) {

        USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0);
    }
    else {

        USBD_Stall(0);
    }
}
Exemple #17
0
//------------------------------------------------------------------------------
/// Sets the active setting of the given interface if the configuration supports
/// it; otherwise, the control pipe is STALLed. If the setting of an interface
/// changes.
/// \parma pDriver  Pointer to a USBDDriver instance.
/// \parma infnum  Interface number.
/// \parma setting  New active setting for the interface.
//------------------------------------------------------------------------------
static void SetInterface(
    USBDDriver *pDriver,
    unsigned char infnum,
    unsigned char setting)
{
    // Make sure alternate settings are supported
    if (!pDriver->pInterfaces) {

        USBD_Stall(0);
    }
    else {

        // Change the current setting of the interface and trigger the callback 
        // if necessary
        if (pDriver->pInterfaces[infnum] != setting) {

            pDriver->pInterfaces[infnum] = setting;
            USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
        }

        // Acknowledge the request
        USBD_Write(0, 0, 0, 0, 0);
    }
}
//------------------------------------------------------------------------------
/// Handles audio-specific USB requests sent by the host, and forwards
/// standard ones to the USB device driver.
/// \param request Pointer to a USBGenericRequest instance.
//------------------------------------------------------------------------------
void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request)
{
    unsigned char entity;
    unsigned char interface;

    TRACE_INFO_WP("NewReq ");

    // Check if this is a class request
    if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {

        // Check if the request is supported
        switch (USBGenericRequest_GetRequest(request)) {

            case AUDGenericRequest_SETCUR:
                TRACE_INFO_WP(
                          "sCur(0x%04X) ",
                          USBGenericRequest_GetIndex(request));
    
                // Check the target interface and entity
                entity = AUDGenericRequest_GetEntity(request);
                interface = AUDGenericRequest_GetInterface(request);
                if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT)
                    && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) {

                    AUDDSpeakerDriver_SetFeatureCurrentValue(
                        entity,
                        AUDFeatureUnitRequest_GetChannel(request),
                        AUDFeatureUnitRequest_GetControl(request),
                        USBGenericRequest_GetLength(request));
                }
                else {
    
                    TRACE_WARNING(
                              "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                              USBGenericRequest_GetIndex(request));
                    USBD_Stall(0);
                }
                break;
    
            case AUDGenericRequest_GETCUR:
                TRACE_INFO_WP(
                          "gCur(0x%04X) ",
                          USBGenericRequest_GetIndex(request));
    
                // Check the target interface and entity
                entity = AUDGenericRequest_GetEntity(request);
                interface = AUDGenericRequest_GetInterface(request);
                if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT)
                    && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) {
    
                    AUDDSpeakerDriver_GetFeatureCurrentValue(
                        entity,
                        AUDFeatureUnitRequest_GetChannel(request),
                        AUDFeatureUnitRequest_GetControl(request),
                        USBGenericRequest_GetLength(request));
                }
                else {
    
                    TRACE_WARNING(
                              "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                              USBGenericRequest_GetIndex(request));
                    USBD_Stall(0);
                }
                break;
    
            default:
    
                TRACE_WARNING(
                          "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d)\n\r",
                          USBGenericRequest_GetRequest(request));
                USBD_Stall(0);
        }
    }
    // Check if this is a standard request
    else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {

        // Forward request to the standard handler
        USBDDriver_RequestHandler(&(auddSpeakerDriver.usbdDriver), request);
    }
    // Unsupported request type
    else {

        TRACE_WARNING(
                  "AUDDSpeakerDriver_RequestHandler: Unsupported request type (%d)\n\r",
                  USBGenericRequest_GetType(request));
        USBD_Stall(0);
    }
}
Exemple #19
0
//------------------------------------------------------------------------------
/// Sends the requested USB descriptor to the host if available, or STALLs  the
/// request.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param type  Type of the requested descriptor
/// \param index  Index of the requested descriptor.
/// \param length  Maximum number of bytes to return.
//------------------------------------------------------------------------------
static void GetDescriptor(
    const USBDDriver *pDriver,
    unsigned char type,
    unsigned char index,
    unsigned int length)
{
    const USBDeviceDescriptor *pDevice;
    const USBConfigurationDescriptor *pConfiguration;
    const USBGenericDescriptor **pStrings =
        (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings;
    unsigned char numStrings = pDriver->pDescriptors->numStrings;
    const USBGenericDescriptor *pString;

	pDevice = pDriver->pDescriptors->pFsDevice;
	pConfiguration = pDriver->pDescriptors->pFsConfiguration;

    // Check the descriptor type
    switch (type) {
        
        case USBGenericDescriptor_DEVICE:
            TRACE_INFO_WP("Dev ");

            // Adjust length and send descriptor
            if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) {

                length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice);
            }
            USBD_Write(0, pDevice, length, 0, 0);
            break;

        case USBGenericDescriptor_CONFIGURATION:
            TRACE_INFO_WP("Cfg ");

            // Adjust length and send descriptor
            if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) {

                length = USBConfigurationDescriptor_GetTotalLength(pConfiguration);
            }
            USBD_Write(0, pConfiguration, length, 0, 0);
            break;

        case USBGenericDescriptor_STRING:
            TRACE_INFO_WP("Str%d ", index);

            // Check if descriptor exists
            if (index > numStrings) {

                USBD_Stall(0);
            }
            else {

                pString = pStrings[index];

                // Adjust length and send descriptor
                if (length > USBGenericDescriptor_GetLength(pString)) {

                    length = USBGenericDescriptor_GetLength(pString);
                }
                USBD_Write(0, pString, length, 0, 0);
            }
            break;

        default:
            TRACE_WARNING(
                      "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r",
                      type);
            USBD_Stall(0);
    }
}
Exemple #20
0
static void finalize_write(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining)
{
	int res;

	if((status != 0) ||(remaining != 0)) {
		USBD_Stall(0);
		return;
	}

	printf("Func: %04x ...", g_writeState.func);

	switch(g_writeState.func) {
		// general api
		case FUNC(GROUP_GENERAL, 0x00): // init all
			printf("general_init()");
			res = 0; // no op so far
			break;
		case FUNC(GROUP_GENERAL, 0x01): // power down
			printf("general_power_down()");
			osdr_fpga_power(0);
			sam3u_e4k_stby(&e4k, 1);
			sam3u_e4k_power(&e4k, 0);
			res = 0;
			break;
		case FUNC(GROUP_GENERAL, 0x02): // power up
			printf("general_power_up()");
			osdr_fpga_power(1);
			sam3u_e4k_power(&e4k, 1);
			sam3u_e4k_stby(&e4k, 0);
			res = 0;
			break;

		// fpga commands
		case FUNC(GROUP_FPGA_V2, 0x00): // fpga init
			printf("fpga_v2_init()");
			res = 0; // no op so far
			break;
		case FUNC(GROUP_FPGA_V2, 0x01):
			printf("fpga_v2_reg_write()");
			osdr_fpga_reg_write(g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
			res = 0;
			break;
		case FUNC(GROUP_FPGA_V2, 0x02):
			printf("osdr_fpga_set_decimation()");
			osdr_fpga_set_decimation(g_writeState.data[0]);
			res = 0;
			break;
		case FUNC(GROUP_FPGA_V2, 0x03):
			printf("osdr_fpga_set_iq_swap()");
			osdr_fpga_set_iq_swap(g_writeState.data[0]);
			res = 0;
			break;
		case FUNC(GROUP_FPGA_V2, 0x04):
			printf("osdr_fpga_set_iq_gain()");
			osdr_fpga_set_iq_gain(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2));
			res = 0;
			break;
		case FUNC(GROUP_FPGA_V2, 0x05):
			printf("osdr_fpga_set_iq_ofs()");
			osdr_fpga_set_iq_ofs(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2));
			res = 0;
			break;

		// si570 vcxo commands
		case FUNC(GROUP_VCXO_SI570, 0x00): // si570_init()
			printf("si570_init()");
			res = si570_reinit(&si570);
			break;
		case FUNC(GROUP_VCXO_SI570, 0x01):
			printf("si570_reg_write()");
			res = si570_reg_write(&si570, g_writeState.data[0], g_writeState.data[1], g_writeState.data + 2);
			break;
		case FUNC(GROUP_VCXO_SI570, 0x02):
			printf("si570_set_freq()");
			res = si570_set_freq(&si570, read_bytewise32(g_writeState.data), read_bytewise32(g_writeState.data + 4));
			break;

		// e4000 tuner commands
		case FUNC(GROUP_TUNER_E4K, 0x00):
			printf("e4k_init()");
			res = e4k_init(&e4k);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x01): // reg write
			printf("e4k_reg_write()");
			res = -1;
			break;
		case FUNC(GROUP_TUNER_E4K, 0x02):
			printf("e4k_if_gain_set()");
			res = e4k_if_gain_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
			break;
		case FUNC(GROUP_TUNER_E4K, 0x03):
			printf("e4k_mixer_gain_set()");
			res = e4k_mixer_gain_set(&e4k, g_writeState.data[0]);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x04):
			printf("e4K_commonmode_set()");
			res = e4k_commonmode_set(&e4k, g_writeState.data[0]);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x05):
			printf("e4k_tune_freq()");
			res = e4k_tune_freq(&e4k, read_bytewise32(g_writeState.data));
			break;
		case FUNC(GROUP_TUNER_E4K, 0x06):
			printf("e4k_if_filter_bw_set()");
			res = e4k_if_filter_bw_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
			break;
		case FUNC(GROUP_TUNER_E4K, 0x07):
			printf("e4k_if_filter_chan_enable()");
			res = e4k_if_filter_chan_enable(&e4k, g_writeState.data[0]);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x08):
			printf("e4k_manual_dc_offset()");
			res = e4k_manual_dc_offset(&e4k, g_writeState.data[0], g_writeState.data[1], g_writeState.data[2], g_writeState.data[3]);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x09):
			printf("e4k_dc_offset_calibrate()");
			res = e4k_dc_offset_calibrate(&e4k);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x0a):
			printf("e4k_dc_offset_gen_table()");
			res = e4k_dc_offset_gen_table(&e4k);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x0b):
			printf("e4k_set_lna_gain()");
			res = e4k_set_lna_gain(&e4k, read_bytewise32(g_writeState.data));
			if(res == -EINVAL)
				res = -1;
			else res = 0;
			break;
		case FUNC(GROUP_TUNER_E4K, 0x0c):
			printf("e4k_enable_manual_gain()");
			res = e4k_enable_manual_gain(&e4k, g_writeState.data[0]);
			break;
		case FUNC(GROUP_TUNER_E4K, 0x0d):
			printf("e4k_set_enh_gain()");
			res = e4k_set_enh_gain(&e4k, read_bytewise32(g_writeState.data));
			break;

		default:
			res = -1;
			break;
	}

	printf(" res: %d\n\r", res);

	if(res == 0)
		USBD_Write(0, 0, 0, 0, 0);
	else USBD_Stall(0);
}
Exemple #21
0
/**
 * Handler for incoming SETUP requests on default Control endpoint 0.
 *
 * Standard requests are forwarded to the USBDDriver_RequestHandler
 * method.
 * \param  pMsdDriver  Pointer to MSDDriver instance.
 * \param  request Pointer to a USBGenericRequest instance
 */
uint32_t MSDFunction_RequestHandler(
    const USBGenericRequest *request)
{
    MSDDriver *pMsdDriver = &msdFunction;
    uint32_t reqCode = (USBGenericRequest_GetType(request) << 8)
                     | (USBGenericRequest_GetRequest(request));

    TRACE_INFO_WP("Msdf ");

    /* Handle requests */
    switch (reqCode) {
    /*--------------------- */
    case USBGenericRequest_CLEARFEATURE:
    /*--------------------- */
        TRACE_INFO_WP("ClrFeat ");

        switch (USBFeatureRequest_GetFeatureSelector(request)) {

        /*--------------------- */
        case USBFeatureRequest_ENDPOINTHALT:
        /*--------------------- */
            TRACE_INFO_WP("Hlt ");

            /* Do not clear the endpoint halt status if the device is waiting */
            /* for a reset recovery sequence */
            if (!pMsdDriver->waitResetRecovery) {

                /* Forward the request to the standard handler */
                USBDDriver_RequestHandler(USBD_GetDriver(), request);
            }
            else {

                TRACE_INFO_WP("No ");
            }

            USBD_Write(0, 0, 0, 0, 0);

            return USBRC_SUCCESS; /* Handled */

        }
        break;

    /*------------------- */
    case (USBGenericRequest_CLASS<<8)|MSD_GET_MAX_LUN:
    /*------------------- */
        TRACE_INFO_WP("gMaxLun ");

        /* Check request parameters */
        if ((request->wValue == 0)
            && (request->wIndex == pMsdDriver->interfaceNb)
            && (request->wLength == 1)) {

            USBD_Write(0, &(pMsdDriver->maxLun), 1, 0, 0);

        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        return USBRC_SUCCESS; /* Handled */

    /*----------------------- */
    case (USBGenericRequest_CLASS<<8)|MSD_BULK_ONLY_RESET:
    /*----------------------- */
        TRACE_INFO_WP("Rst ");

        /* Check parameters */
        if ((request->wValue == 0)
            && (request->wIndex == pMsdDriver->interfaceNb)
            && (request->wLength == 0)) {

            /* Reset the MSD driver */
            MSDFunction_Reset();
            USBD_Write(0, 0, 0, 0, 0);
        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        return USBRC_SUCCESS; /* Handled */
    }

    return USBRC_PARAM_ERR;
}
Exemple #22
0
//-----------------------------------------------------------------------------
/// Handles AUDIO-specific USB requests sent by the host
/// \param request Pointer to a USBGenericRequest instance.
/// \return 0 if the request is Unsupported, 1 if the request handled.
//-----------------------------------------------------------------------------
unsigned char AUDDFunctionDriver_RequestHandler(
    const USBGenericRequest *request)
{
    unsigned char entity;
    unsigned char interface;

    // Check if the request is supported
    switch (USBGenericRequest_GetRequest(request)) {

        case AUDGenericRequest_SETCUR:
            TRACE_INFO_WP(
                      "sCur(0x%04X) ",
                      USBGenericRequest_GetIndex(request));

            // Check the target interface and entity
            entity = AUDGenericRequest_GetEntity(request);
            interface = AUDGenericRequest_GetInterface(request);
            if ((entity == AUDD_Descriptors_FEATUREUNIT)
                && (interface == AUDD_Descriptors_CONTROL)) {

                AUDD_SetFeatureCurrentValue(
                    AUDFeatureUnitRequest_GetChannel(request),
                    AUDFeatureUnitRequest_GetControl(request),
                    USBGenericRequest_GetLength(request));
            }
            else {

                TRACE_WARNING(
                          "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                          USBGenericRequest_GetIndex(request));
                USBD_Stall(0);
            }
            break;

        case AUDGenericRequest_GETCUR:
            TRACE_INFO_WP(
                      "gCur(0x%04X) ",
                      USBGenericRequest_GetIndex(request));

            // Check the target interface and entity
            entity = AUDGenericRequest_GetEntity(request);
            interface = AUDGenericRequest_GetInterface(request);
            if ((entity == AUDD_Descriptors_FEATUREUNIT)
                && (interface == AUDD_Descriptors_CONTROL)) {

                AUDD_GetFeatureCurrentValue(
                    AUDFeatureUnitRequest_GetChannel(request),
                    AUDFeatureUnitRequest_GetControl(request),
                    USBGenericRequest_GetLength(request));
            }
            else {

                TRACE_WARNING(
                          "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
                          USBGenericRequest_GetIndex(request));
                USBD_Stall(0);
            }
            break;

        default:
            return 0;
    }
    return 1;
}
Exemple #23
0
//------------------------------------------------------------------------------
/// Handles the given request if it is standard, otherwise STALLs it.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param pRequest  Pointer to a USBGenericRequest instance.
//------------------------------------------------------------------------------
void USBDDriver_RequestHandler(
    USBDDriver *pDriver,
    const USBGenericRequest *pRequest)
{
    unsigned char cfgnum;
    unsigned char infnum;
    unsigned char eptnum;
    unsigned char setting;
    unsigned char type;
    unsigned char indexDesc;
    unsigned int length;
    unsigned int address;

    TRACE_INFO_WP("Std ");

    // Check request code
    switch (USBGenericRequest_GetRequest(pRequest)) {

        case USBGenericRequest_GETDESCRIPTOR:
            TRACE_INFO_WP("gDesc ");

            // Send the requested descriptor
            type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
            indexDesc = USBGetDescriptorRequest_GetDescriptorIndex(pRequest);
            length = USBGenericRequest_GetLength(pRequest);
            GetDescriptor(pDriver, type, indexDesc, length);
            break;

        case USBGenericRequest_SETADDRESS:
            TRACE_INFO_WP("sAddr ");

            // Sends a zero-length packet and then set the device address
            address = USBSetAddressRequest_GetAddress(pRequest);
            USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address);
            break;

        case USBGenericRequest_SETCONFIGURATION:
            TRACE_INFO_WP("sCfg ");

            // Set the requested configuration
            cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
            SetConfiguration(pDriver, cfgnum);
            break;

        case USBGenericRequest_GETCONFIGURATION:
            TRACE_INFO_WP("gCfg ");

            // Send the current configuration number
            GetConfiguration(pDriver);
            break;

        case USBGenericRequest_GETSTATUS:
            TRACE_INFO_WP("gSta ");
    
            // Check who is the recipient
            switch (USBGenericRequest_GetRecipient(pRequest)) {
    
                case USBGenericRequest_DEVICE:
                    TRACE_INFO_WP("Dev ");
    
                    // Send the device status
                    GetDeviceStatus(pDriver);
                    break;
    
                case USBGenericRequest_ENDPOINT:
                    TRACE_INFO_WP("Ept ");
    
                    // Send the endpoint status
                    eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
                    GetEndpointStatus(eptnum);
                    break;
    
                default:
                    TRACE_WARNING(
                              "USBDDriver_RequestHandler: Unknown recipient (%d)\n\r",
                              USBGenericRequest_GetRecipient(pRequest));
                    USBD_Stall(0);
            }
            break;

        case USBGenericRequest_CLEARFEATURE:
            TRACE_INFO_WP("cFeat ");

            // Check which is the requested feature
            switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

                case USBFeatureRequest_ENDPOINTHALT:
                    TRACE_INFO_WP("Hlt ");

                    // Unhalt endpoint and send a zero-length packet
                    USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                    TRACE_INFO_WP("RmWU ");

                    // Disable remote wake-up and send a zero-length packet
                    pDriver->isRemoteWakeUpEnabled = 0;
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                default:
                    TRACE_WARNING(
                              "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                              USBFeatureRequest_GetFeatureSelector(pRequest));
                    USBD_Stall(0);
            }
            break;

    case USBGenericRequest_SETFEATURE:
        TRACE_INFO_WP("sFeat ");

        // Check which is the selected feature
        switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

            case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                TRACE_INFO_WP("RmWU ");

                // Enable remote wake-up and send a ZLP
                pDriver->isRemoteWakeUpEnabled = 1;
                USBD_Write(0, 0, 0, 0, 0);
                break;

            case USBFeatureRequest_ENDPOINTHALT:
                TRACE_INFO_WP("Halt ");
                // Halt endpoint
                USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
                USBD_Write(0, 0, 0, 0, 0);
                break;

#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)

            case USBFeatureRequest_TESTMODE:
                // 7.1.20 Test Mode Support
                if ((USBGenericRequest_GetType(pRequest) == USBGenericRequest_DEVICE)
                    && ((USBGenericRequest_GetIndex(pRequest) & 0x000F) == 0)) {

                    // Handle test request
                    USBDDriver_Test(USBFeatureRequest_GetTestSelector(pRequest));
                }
                else {

                    USBD_Stall(0);
                }
                break;
#endif
#if defined(CHIP_USB_OTGHS)
            case USBFeatureRequest_OTG_B_HNP_ENABLE:
                    TRACE_INFO_WP("OTG_B_HNP_ENABLE ");
                    otg_features_supported |= 1<<USBFeatureRequest_OTG_B_HNP_ENABLE;
                    USBD_Write(0, 0, 0, 0, 0);
                break;
            case USBFeatureRequest_OTG_A_HNP_SUPPORT:
                    TRACE_INFO_WP("OTG_A_HNP_SUPPORT ");
                    otg_features_supported |= 1<<USBFeatureRequest_OTG_A_HNP_SUPPORT;
                    USBD_Write(0, 0, 0, 0, 0);
                break;
            case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT:
                    TRACE_INFO_WP("OTG_A_ALT_HNP_SUPPORT ");
                    otg_features_supported |= 1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT;
                    USBD_Write(0, 0, 0, 0, 0);
                break;
#endif
            default:
                TRACE_WARNING(
                          "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                          USBFeatureRequest_GetFeatureSelector(pRequest));
                USBD_Stall(0);
        }
        break;

    case USBGenericRequest_SETINTERFACE:
        TRACE_INFO_WP("sInterface ");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
        SetInterface(pDriver, infnum, setting);
        break;

    case USBGenericRequest_GETINTERFACE:
        TRACE_INFO_WP("gInterface ");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        GetInterface(pDriver, infnum);
        break;

    default:
        TRACE_WARNING(
                  "USBDDriver_RequestHandler: Unknown request code (%d)\n\r",
                  USBGenericRequest_GetRequest(pRequest));
        USBD_Stall(0);
    }
}
Exemple #24
0
//------------------------------------------------------------------------------
// Performs the selected test on the USB device (high-speed only).
// \param test  Test selector value.
//------------------------------------------------------------------------------
static void USBDDriver_Test(unsigned char test)
{
    TRACE_DEBUG("UDPHS_Test\n\r");

    // the lower byte of wIndex must be zero
    // the most significant byte of wIndex is used to specify the specific test mode
    switch (test) {
        case USBFeatureRequest_TESTPACKET:
            //Test mode Test_Packet: 
            //Upon command, a port must repetitively transmit the following test packet until
            //the exit action is taken. This enables the testing of rise and fall times, eye 
            //patterns, jitter, and any other dynamic waveform specifications.
            //The test packet is made up by concatenating the following strings. 
            //(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one 
            //transmitted. “S” indicates that a bit stuff occurs, which inserts an “extra” NRZI data bit. 
            //“* N” is used to indicate N occurrences of a string of bits or symbols.)
            //A port in Test_Packet mode must send this packet repetitively. The inter-packet timing 
            //must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and 
            //no greater than 125 us.
            // Send ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            // Tst PACKET
            USBD_Test(USBFeatureRequest_TESTPACKET);
            while (1);
            //break; not reached

        case USBFeatureRequest_TESTJ:
            //Test mode Test_J:
            //Upon command, a port’s transceiver must enter the high-speed J state and remain in that
            //state until the exit action is taken. This enables the testing of the high output drive
            //level on the D+ line.
            // Send ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            // Tst J
            USBD_Test(USBFeatureRequest_TESTJ);
            while (1);
            //break; not reached

        case USBFeatureRequest_TESTK:
            //Test mode Test_K:
            //Upon command, a port’s transceiver must enter the high-speed K state and remain in
            //that state until the exit action is taken. This enables the testing of the high output drive
            //level on the D- line.
            // Send a ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            USBD_Test(USBFeatureRequest_TESTK);
            while (1);
            //break; not reached

        case USBFeatureRequest_TESTSE0NAK:
            //Test mode Test_SE0_NAK:
            //Upon command, a port’s transceiver must enter the high-speed receive mode
            //and remain in that mode until the exit action is taken. This enables the testing
            //of output impedance, low level output voltage, and loading characteristics.
            //In addition, while in this mode, upstream facing ports (and only upstream facing ports)
            //must respond to any IN token packet with a NAK handshake (only if the packet CRC is
            //determined to be correct) within the normal allowed device response time. This enables testing of
            //the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
            //test for basic functional testing.
            // Send a ZLP
            USBD_Test(USBFeatureRequest_TESTSENDZLP);
            // Test SE0_NAK
            USBD_Test(USBFeatureRequest_TESTSE0NAK);
            while (1);
            //break; not reached

        default:
            USBD_Stall(0);
            break;

    }
    // The exit action is to power cycle the device.
    // The device must be disconnected from the host
}
Exemple #25
0
static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel,
				   uint8_t control, uint8_t length)
{
	/* FIXME */
	USBD_Stall(0);
}
/**
 * Handles HID-specific SETUP request sent by the host.
 * \param request Pointer to a USBGenericRequest instance
 */
void HIDDTransferDriver_RequestHandler(const USBGenericRequest *request)
{
    HIDDTransferDriver *pDrv = &hiddTransferDriver;
    HIDDFunction *pHidd = &pDrv->hidFunction;

    TRACE_INFO("NewReq ");

    /* Check if this is a standard request */
    if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {

        /* This is a standard request */
        switch (USBGenericRequest_GetRequest(request)) {

        case USBGenericRequest_GETDESCRIPTOR:
            /* Check if this is a HID descriptor, otherwise forward it to
               the standard driver */
            if (!HIDDTransferDriver_GetDescriptor(
                    USBGetDescriptorRequest_GetDescriptorType(request),
                    USBGenericRequest_GetLength(request))) {

                USBDDriver_RequestHandler(pHidd->pUsbd,
                                          request);
            }
            return; /* Handled, no need to do others */

        case USBGenericRequest_CLEARFEATURE:

            /* Check which is the requested feature */
            switch (USBFeatureRequest_GetFeatureSelector(request)) {
                case USBFeatureRequest_ENDPOINTHALT:
                {   uint8_t ep =
                        USBGenericRequest_GetEndpointNumber(request);
                        if (USBD_IsHalted(ep)) {
                            /* Unhalt endpoint restart OUT EP
                             */
                            USBD_Unhalt(ep);
                            if (ep == pHidd->bPipeOUT) {
                                HIDDFunction_StartPollingOutputs(pHidd);
                            }
                        }
                        /* and send a zero-length packet */
                        USBD_Write(0, 0, 0, 0, 0);
                    return; /* Handled, no need to do others */
                }
            }
            break;

        }
    }
    /* We use different buffer for SetReport */
    else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {

        switch (USBGenericRequest_GetRequest(request)) {

        case HIDGenericRequest_SETREPORT:
            {
                uint16_t length = USBGenericRequest_GetLength(request);
                uint8_t  type = HIDReportRequest_GetReportType(request);
                if (type == HIDReportRequest_OUTPUT) {
                    if (length > HIDDTransferDriver_REPORTSIZE)
                        length = HIDDTransferDriver_REPORTSIZE;
                    USBD_Read(0,
                              pDrv->iReportBuf,
                              length,
                              HIDDTransferDriver_ReportReceived,
                              0); /* No argument to the callback function */
                }
                else {

                    USBD_Stall(0);
                }
            }
            return; /* Handled, no need do others */
        }
    }
    

    /* Process HID requests */
    if (USBRC_SUCCESS == HIDDFunction_RequestHandler(pHidd,
                                                     request)) {
        return;
    }
    else
        USBDDriver_RequestHandler(pHidd->pUsbd, request);
}
Exemple #27
0
//-----------------------------------------------------------------------------
/// Handler for incoming SETUP requests on default Control endpoint 0.
///
/// Standard requests are forwarded to the USBDDriver_RequestHandler
/// method.
/// \param  request Pointer to a USBGenericRequest instance
//-----------------------------------------------------------------------------
void MSDDriver_RequestHandler(const USBGenericRequest *request)
{
    TRACE_INFO_WP("NewReq ");

    // Handle requests
    switch (USBGenericRequest_GetRequest(request)) {
    //---------------------
    case USBGenericRequest_CLEARFEATURE:
    //---------------------
        TRACE_INFO_WP("ClrFeat ");

        switch (USBFeatureRequest_GetFeatureSelector(request)) {

        //---------------------
        case USBFeatureRequest_ENDPOINTHALT:
        //---------------------
            TRACE_INFO_WP("Hlt ");

            // Do not clear the endpoint halt status if the device is waiting
            // for a reset recovery sequence
            if (!msdDriver.waitResetRecovery) {

                // Forward the request to the standard handler
                USBDDriver_RequestHandler(&usbdDriver, request);
            }
            else {

                TRACE_INFO_WP("No ");
            }

            USBD_Write(0, 0, 0, 0, 0);
            break;

        //------
        default:
        //------
            // Forward the request to the standard handler
            USBDDriver_RequestHandler(&usbdDriver, request);
        }
        break;

    //-------------------
    case MSD_GET_MAX_LUN:
    //-------------------
        TRACE_INFO_WP("gMaxLun ");

        // Check request parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 1)) {

            USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0);

        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //-----------------------
    case MSD_BULK_ONLY_RESET:
    //-----------------------
        TRACE_INFO_WP("Rst ");

        // Check parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 0)) {

            // Reset the MSD driver
            MSDDriver_Reset();
            USBD_Write(0, 0, 0, 0, 0);
        }
        else {

            TRACE_WARNING(
                "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
                request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //------
    default:
    //------
        // Forward request to standard handler
        USBDDriver_RequestHandler(&usbdDriver, request);

        break;
    }
}
Exemple #28
0
/**
 * Handles the given request if it is standard, otherwise STALLs it.
 * \param pDriver  Pointer to a USBDDriver instance.
 * \param pRequest  Pointer to a USBGenericRequest instance.
 */
void USBDDriver_RequestHandler(
    USBDDriver *pDriver,
    const USBGenericRequest *pRequest)
{
    uint8_t cfgnum;
    uint8_t infnum;
    uint8_t eptnum;
    uint8_t setting;
    uint8_t type;
    uint8_t indexDesc;
    uint32_t length;
    uint32_t address;

    TRACE_INFO_WP("Std ");

    /* Check request code */
    switch (USBGenericRequest_GetRequest(pRequest)) {

        case USBGenericRequest_GETDESCRIPTOR:
            TRACE_INFO_WP("gDesc ");

            /* Send the requested descriptor */
            type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
            indexDesc = USBGetDescriptorRequest_GetDescriptorIndex(pRequest);
            length = USBGenericRequest_GetLength(pRequest);
            GetDescriptor(pDriver, type, indexDesc, length);
            break;

        case USBGenericRequest_SETADDRESS:
            TRACE_INFO_WP("sAddr ");

            /* Sends a zero-length packet and then set the device address */
            address = USBSetAddressRequest_GetAddress(pRequest);
            USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address);
            break;

        case USBGenericRequest_SETCONFIGURATION:
            TRACE_INFO_WP("sCfg ");

            /* Set the requested configuration */
            cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
            SetConfiguration(pDriver, cfgnum);
            break;

        case USBGenericRequest_GETCONFIGURATION:
            TRACE_INFO_WP("gCfg ");

            /* Send the current configuration number */
            GetConfiguration(pDriver);
            break;

        case USBGenericRequest_GETSTATUS:
            TRACE_INFO_WP("gSta ");

            /* Check who is the recipient */
            switch (USBGenericRequest_GetRecipient(pRequest)) {

                case USBGenericRequest_DEVICE:
                    TRACE_INFO_WP("Dev ");

                    /* Send the device status */
                    GetDeviceStatus(pDriver);
                    break;

                case USBGenericRequest_ENDPOINT:
                    TRACE_INFO_WP("Ept ");

                    /* Send the endpoint status */
                    eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
                    GetEndpointStatus(eptnum);
                    break;

                default:
                    TRACE_WARNING(
                              "USBDDriver_RequestHandler: Unknown recipient (%d)\n\r",
                              USBGenericRequest_GetRecipient(pRequest));
                    USBD_Stall(0);
            }
            break;

        case USBGenericRequest_CLEARFEATURE:
            TRACE_INFO_WP("cFeat ");

            /* Check which is the requested feature */
            switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

                case USBFeatureRequest_ENDPOINTHALT:
                    TRACE_INFO_WP("Hlt ");

                    /* Unhalt endpoint and send a zero-length packet */
                    USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                    TRACE_INFO_WP("RmWU ");

                    /* Disable remote wake-up and send a zero-length packet */
                    pDriver->isRemoteWakeUpEnabled = 0;
                    USBD_Write(0, 0, 0, 0, 0);
                    break;

                default:
                    TRACE_WARNING(
                              "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                              USBFeatureRequest_GetFeatureSelector(pRequest));
                    USBD_Stall(0);
            }
            break;

    case USBGenericRequest_SETFEATURE:
        TRACE_INFO_WP("sFeat ");

        /* Check which is the selected feature */
        switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {

            case USBFeatureRequest_DEVICEREMOTEWAKEUP:
                TRACE_INFO_WP("RmWU ");

                /* Enable remote wake-up and send a ZLP */
                pDriver->isRemoteWakeUpEnabled = 1;
                USBD_Write(0, 0, 0, 0, 0);
                break;

            case USBFeatureRequest_ENDPOINTHALT:
                TRACE_INFO_WP("Halt ");
                /* Halt endpoint */
                USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
                USBD_Write(0, 0, 0, 0, 0);
                break;
            case USBFeatureRequest_OTG_B_HNP_ENABLE:
                    TRACE_INFO_WP("OTG_B_HNP_ENABLE ");
                    pDriver->otg_features_supported |=
                        1<<USBFeatureRequest_OTG_B_HNP_ENABLE;
                    USBD_Write(0, 0, 0, 0, 0);
                break;
            case USBFeatureRequest_OTG_A_HNP_SUPPORT:
                    TRACE_INFO_WP("OTG_A_HNP_SUPPORT ");
                    pDriver->otg_features_supported |=
                        1<<USBFeatureRequest_OTG_A_HNP_SUPPORT;
                    USBD_Write(0, 0, 0, 0, 0);
                break;
            case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT:
                    TRACE_INFO_WP("OTG_A_ALT_HNP_SUPPORT ");
                    pDriver->otg_features_supported |=
                        1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT;
                    USBD_Write(0, 0, 0, 0, 0);
                break;

            default:
                TRACE_WARNING(
                          "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r",
                          USBFeatureRequest_GetFeatureSelector(pRequest));
                USBD_Stall(0);
        }
        break;

    case USBGenericRequest_SETINTERFACE:
        TRACE_INFO_WP("sInterface ");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
        SetInterface(pDriver, infnum, setting);
        break;

    case USBGenericRequest_GETINTERFACE:
        TRACE_INFO_WP("gInterface ");

        infnum = USBInterfaceRequest_GetInterface(pRequest);
        GetInterface(pDriver, infnum);
        break;

    default:
        TRACE_WARNING(
                  "USBDDriver_RequestHandler: Unknown request code (%d)\n\r",
                  USBGenericRequest_GetRequest(pRequest));
        USBD_Stall(0);
    }
}
Exemple #29
0
//------------------------------------------------------------------------------
/// Sends the requested USB descriptor to the host if available, or STALLs  the
/// request.
/// \param pDriver  Pointer to a USBDDriver instance.
/// \param type  Type of the requested descriptor
/// \param index  Index of the requested descriptor.
/// \param length  Maximum number of bytes to return.
//------------------------------------------------------------------------------
static void GetDescriptor(
    const USBDDriver *pDriver,
    unsigned char type,
    unsigned char indexRDesc,
    unsigned int length)
{
    const USBDeviceDescriptor *pDevice;
    const USBConfigurationDescriptor *pConfiguration;
    const USBDeviceQualifierDescriptor *pQualifier;
    const USBConfigurationDescriptor *pOtherSpeed;
    const USBGenericDescriptor **pStrings =
        (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings;
    const USBGenericDescriptor *pString;
    unsigned char numStrings = pDriver->pDescriptors->numStrings;
    unsigned char terminateWithNull = 0;

    // Use different set of descriptors depending on device speed
    if (USBD_IsHighSpeed()) {

        TRACE_DEBUG("HS ");
        pDevice = pDriver->pDescriptors->pHsDevice;
        pConfiguration = pDriver->pDescriptors->pHsConfiguration;
        pQualifier = pDriver->pDescriptors->pHsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed;
    }
    else {

        TRACE_DEBUG("FS ");
        pDevice = pDriver->pDescriptors->pFsDevice;
        pConfiguration = pDriver->pDescriptors->pFsConfiguration;
        pQualifier = pDriver->pDescriptors->pFsQualifier;
        pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed;
    }

    // Check the descriptor type
    switch (type) {
        
        case USBGenericDescriptor_DEVICE:
            TRACE_INFO_WP("Dev ");

            // Adjust length and send descriptor
            if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) {

                length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice);
            }
            USBD_Write(0, pDevice, length, 0, 0);
            break;

        case USBGenericDescriptor_CONFIGURATION:
            TRACE_INFO_WP("Cfg ");

            // Adjust length and send descriptor
            if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) {

                length = USBConfigurationDescriptor_GetTotalLength(pConfiguration);
                terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
            }
            USBD_Write(0,
                       pConfiguration,
                       length,
                       terminateWithNull ? TerminateCtrlInWithNull : 0,
                       0);
            break;

        case USBGenericDescriptor_DEVICEQUALIFIER:
            TRACE_INFO_WP("Qua ");

            // Check if descriptor exists
            if (!pQualifier) {

                USBD_Stall(0);
            }
            else {

                // Adjust length and send descriptor
                if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) {

                    length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier);
                }
                USBD_Write(0, pQualifier, length, 0, 0);
            }
            break;

        case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
            TRACE_INFO_WP("OSC ");

            // Check if descriptor exists
            if (!pOtherSpeed) {

                USBD_Stall(0);
            }
            else {

                // Adjust length and send descriptor
                if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) {

                    length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed);
                    terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
                }
                USBD_Write(0,
                           pOtherSpeed,
                           length,
                           terminateWithNull ? TerminateCtrlInWithNull : 0,
                           0);
            }
            break;

        case USBGenericDescriptor_STRING:
            TRACE_INFO_WP("Str%d ", indexRDesc);

            // Check if descriptor exists
            if (indexRDesc > numStrings) {

                USBD_Stall(0);
            }
            else {

                pString = pStrings[indexRDesc];

                // Adjust length and send descriptor
                if (length > USBGenericDescriptor_GetLength(pString)) {

                    length = USBGenericDescriptor_GetLength(pString);
                    terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
                }
                USBD_Write(0,
                           pString,
                           length,
                           terminateWithNull ? TerminateCtrlInWithNull : 0,
                           0);
            }
            break;

        default:
            TRACE_WARNING(
                      "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r",
                      type);
            USBD_Stall(0);
    }
}
Exemple #30
0
// https://github.com/pbatard/libwdi/wiki/WCID-Devices
static void GetMSDescriptor(
    const USBDDriver *pDriver,
    uint16_t indexRDesc,
    uint32_t length)
{
    const USBDeviceDescriptor *pDevice;
    uint8_t terminateWithNull = 0;

    /* Use different set of descriptors depending on device speed */
    if (USBD_IsHighSpeed()) {
        TRACE_DEBUG("HS ");
        pDevice = pDriver->pDescriptors->pHsDevice;
    }
    else {
        TRACE_DEBUG("FS ");
        pDevice = pDriver->pDescriptors->pFsDevice;
    }

    /* Check the descriptor index */
    switch (indexRDesc) {
        // https://github.com/pbatard/libwdi/wiki/WCID-Devices
        case 0x0004: { // Extended Compat ID (Microsoft OS 1.0 Descriptors)
            const uint8_t extendedCompatID[] = {
                0x28, 0x00, 0x00, 0x00, // dwLength
                0x00, 0x01, // bcdVersion
                0x04, 0x00, // wIndex
                0x01, // bCount
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
                0x00, // bFirstInterfaceNumber
                0x01, // Reserved
                0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // CompatibleID "WINUSB\0\0"
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SubCompatibleID
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved
            };
            const uint8_t extendedCompatIDLength = sizeof(extendedCompatID);

            /* Adjust length and send descriptor */
            if (length > extendedCompatIDLength) {
                length = extendedCompatIDLength;
                terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
            }

            terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);

            USBD_Write(0,
                       extendedCompatID,
                       length,
                       terminateWithNull ? TerminateCtrlInWithNull : 0,
                       0);

            break;
        }
        case 0x0005: { // Extended Properties (Microsoft OS 1.0 Descriptors)
            const uint8_t extendedProperties[] = {
                0x92, 0x00, 0x00, 0x00, // dwLength
                0x00, 0x01, // bcdVersion
                0x05, 0x00, // wIndex
                0x01, 0x00, // wCount
                0x88, 0x00, 0x00, 0x00, // dwSize
                0x07, 0x00, 0x00, 0x00, // dwPropertyDataType
                0x2a, 0x00, // wPropertyNameLength
                0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00,
                0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00,
                0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x47, 0x00, 0x55, 0x00, 0x49, 0x00,
                0x44, 0x00, 0x73, 0x00, 0x00, 0x00, // bPropertyName "DeviceInterfaceGUIDs\0"
                0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
                0x7b, 0x00, 0x38, 0x00, 0x37, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00,
                0x33, 0x00, 0x44, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x46, 0x00, 0x42, 0x00,
                0x31, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x42, 0x00, 0x44, 0x00,
                0x37, 0x00, 0x2d, 0x00, 0x41, 0x00, 0x39, 0x00, 0x36, 0x00, 0x43, 0x00,
                0x2d, 0x00, 0x31, 0x00, 0x46, 0x00, 0x30, 0x00, 0x42, 0x00, 0x37, 0x00,
                0x44, 0x00, 0x33, 0x00, 0x31, 0x00, 0x41, 0x00, 0x46, 0x00, 0x34, 0x00,
                0x31, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, // bPropertyData "{870013DD-FB1D-4BD7-A96C-1F0B7D31AF41}\0\0"
            };
            const uint8_t extendedPropertiesLength = sizeof(extendedProperties);

            /* Adjust length and send descriptor */
            if (length > extendedPropertiesLength) {
                length = extendedPropertiesLength;
                terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
            }

            terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);

            USBD_Write(0,
                       extendedProperties,
                       length,
                       terminateWithNull ? TerminateCtrlInWithNull : 0,
                       0);

            break;
        }

        default:
            TRACE_WARNING(
                      "USBDDriver_GetMSDescriptor: Unknown descriptor index (%d)\n\r",
                      indexRDesc);
            USBD_Stall(0);
    }
}