⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enum.cpp

📁 It permits simultaneous use of multiple USB Serial protocols.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
static
CONTROL_RESPONSE
ProcessGetInterface(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    ValidateContext(pContext);

    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        // Nothing to do.
        goto EXIT;
    }

    const DWORD dwLength = 1;
    DEBUGCHK(dim(pContext->rgbBuffer) >= dwLength);

    CONTROL_RESPONSE response = CR_SUCCESS;

    DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Get interface.\r\n"), pszFname));   
    
    if (pContext->deviceState == DS_CONFIGURED) {
        PUFN_CONFIGURATION pConfig = GetConfig(pContext, pContext->Speed);
        PUFN_INTERFACE pInterface = &pConfig->pInterfaces[udr.wIndex];
        BYTE bAlternateSetting = pInterface->Descriptor.bAlternateSetting;
        pContext->rgbBuffer[0] = bAlternateSetting;
        SetupTx(pContext, pContext->rgbBuffer, dwLength, udr.wLength);
    }
    else {
        response = CR_STALL_DEFAULT_PIPE;
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a Get Status request.
static
CONTROL_RESPONSE
ProcessGetStatus(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    ValidateContext(pContext);

    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        // Nothing to do.
        goto EXIT;
    }

    const DWORD dwLength = 2;
    DEBUGCHK(dim(pContext->rgbBuffer) >= dwLength);
    CONTROL_RESPONSE response = CR_SUCCESS;

    pContext->rgbBuffer[0] = 0;
    pContext->rgbBuffer[1] = 0;

    BYTE bRecipient = GET_REQUESET_RECIPIENT(udr.bmRequestType);

    if (bRecipient == USB_REQUEST_FOR_DEVICE) {
        DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Get device status.\r\n"), pszFname));

        BYTE bStatus = 0;

        if (pContext->pHighSpeedConfigDesc->bmAttributes & USB_CONFIG_SELF_POWERED) {
            bStatus |= USB_GETSTATUS_SELF_POWERED;
        }

        if (pContext->fRemoteWakeupEnabled) {
            bStatus |= USB_GETSTATUS_REMOTE_WAKEUP_ENABLED;
        }

        pContext->rgbBuffer[0] = bStatus;
    }
    else if (bRecipient == USB_REQUEST_FOR_INTERFACE) {
        if ( (pContext->deviceState != DS_CONFIGURED) || (udr.wIndex != 1) ) {
            DEBUGMSG(ZONE_ERROR, (_T("%s Bad interface request\r\n"),
                pszFname));
            response = CR_STALL_DEFAULT_PIPE;
        }
    }
    else if (bRecipient == USB_REQUEST_FOR_ENDPOINT) {
        PCPipe pPipe = FindPipe(pContext, udr.wIndex);

        if ( pPipe && 
             ( (pContext->deviceState == DS_CONFIGURED) || (udr.wIndex == 0) ) ) {
            BOOL fHalted;
            pContext->PddInfo.pfnIsEndpointHalted(pContext->PddInfo.pvPddContext, 
                pPipe->GetPhysicalEndpoint(), &fHalted);
            if (fHalted) {
                pContext->rgbBuffer[0] = 1;
            }
        }
        else {
            DEBUGMSG(ZONE_ERROR, (_T("%s Bad endpoint request\r\n"),
                pszFname));
            response = CR_STALL_DEFAULT_PIPE;
        }
    }
    else {
        response = CR_UNHANDLED_REQUEST;
    }

    if (response == CR_SUCCESS) {
        // Need to send the data
        SetupTx(pContext, pContext->rgbBuffer, dwLength, udr.wLength);
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a Set Adress request.
static
CONTROL_RESPONSE
ProcessSetAddress(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);

    DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Set address (%u) request.\r\n"),
        pszFname, udr.wValue));

    // Check for invalid conditions according to the USB spec.
    DEBUGCHK(udr.wValue <= 0x7F);
    DEBUGCHK(pContext->deviceState != DS_CONFIGURED);

    if (udr.wValue == 0) {
        ChangeDeviceState(pContext, DS_DEFAULT);
    }
    else {
        ChangeDeviceState(pContext, DS_ADDRESSED);
    }

    CONTROL_RESPONSE response;
    if (dwMsg == UFN_MSG_SETUP_PACKET) {
        response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
        pContext->PddInfo.pfnSetAddress(pContext->PddInfo.pvPddContext, 
            (BYTE) udr.wValue);
    }
    else {
        response = CR_SUCCESS;
    }

    FUNCTION_LEAVE_MSG();

    return response;
}
    

// Handle a Set Configuration request.
static
CONTROL_RESPONSE
ProcessSetConfiguration(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    CONTROL_RESPONSE response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
    
    ValidateContext(pContext);

    DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Set configuration (%u) request.\r\n"),
        pszFname, udr.wValue));

    PUFN_CONFIGURATION pConfig = GetConfig(pContext, pContext->Speed);
    BYTE bConfigurationValue = pConfig->Descriptor.bConfigurationValue;

    if (udr.wValue == 0) {
        if (pContext->deviceState == DS_CONFIGURED) {       
            ChangeDeviceState(pContext, DS_ADDRESSED);
            pContext->dwConfiguration = 0;
            SendDeviceNotification(pContext->lpDeviceNotify, 
                pContext->pvDeviceNotifyParameter, UFN_MSG_CONFIGURED, udr.wValue);
        }
        // else simply stay in addressed state        
    }
    else if (udr.wValue == bConfigurationValue) {
        // Only send the "device configured" message to the client once.
        if (pContext->deviceState != DS_CONFIGURED) {
            ChangeDeviceState(pContext, DS_CONFIGURED);
            pContext->dwConfiguration = bConfigurationValue;
            SendDeviceNotification(pContext->lpDeviceNotify, 
                pContext->pvDeviceNotifyParameter, UFN_MSG_CONFIGURED, udr.wValue);
        }
        // else simply stay in configured state
    }
    else {
        response = CR_STALL_DEFAULT_PIPE;
    }

    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        response = CR_SUCCESS;
    }

    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a Set Interface request.
static
CONTROL_RESPONSE
ProcessSetInterface(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    CONTROL_RESPONSE response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
    
    ValidateContext(pContext);

    DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Set interface (%u) request.\r\n"),
        pszFname, udr.wValue));

    PUFN_CONFIGURATION pConfig = GetConfig(pContext, pContext->Speed);
    PUFN_INTERFACE pInterface = &pConfig->pInterfaces[udr.wIndex];
    BYTE bAlternateSetting = pInterface->Descriptor.bAlternateSetting;

    if ( (udr.wValue != bAlternateSetting) || 
         (pContext->deviceState != DS_CONFIGURED) ) {
        response = CR_STALL_DEFAULT_PIPE;
    }

    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        response = CR_SUCCESS;
    }

    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a Clear Feature request.
static
CONTROL_RESPONSE
ProcessClearFeature(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    CONTROL_RESPONSE response = CR_UNHANDLED_REQUEST;
    
    ValidateContext(pContext);

    if ( (GET_REQUESET_RECIPIENT(udr.bmRequestType) == USB_REQUEST_FOR_ENDPOINT) && 
         (udr.wValue == USB_FEATURE_ENDPOINT_STALL) ) {
        BYTE bEndpoint = LOBYTE(udr.wIndex);
        DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Clear endpoint (0x%02x) halt request.\r\n"),
            pszFname, bEndpoint));

        PCPipe pPipe = FindPipe(pContext, bEndpoint);
        if (pPipe == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s Asked to clear halt for invalid endpoint 0x%02x\r\n"),
                pszFname, bEndpoint));
            response = CR_STALL_DEFAULT_PIPE;
        }
        else {
            if (dwMsg == UFN_MSG_SETUP_PACKET) {
                pContext->PddInfo.pfnClearEndpointStall(pContext->PddInfo.pvPddContext,
                    pPipe->GetPhysicalEndpoint());
                response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            }
        }
    }
    else if ( (GET_REQUESET_RECIPIENT(udr.bmRequestType) == USB_REQUEST_FOR_DEVICE)) {
        switch (udr.wValue) {
          case USB_FEATURE_REMOTE_WAKEUP:
            pContext->fRemoteWakeupEnabled = FALSE;
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            break;
          case USB_FEATURE_B_HNP_ENABLE:
            if (pContext->hParentBusHandle && BusChildIoControl(pContext->hParentBusHandle,IOCTL_BUS_USBOTG_HNP_DISABLE,NULL,0)) {
                response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            }
            break;
        }
    }
    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        response = CR_SUCCESS;
    }
    
    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a Set Feature request.
static
CONTROL_RESPONSE
ProcessSetFeature(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    CONTROL_RESPONSE response = CR_UNHANDLED_REQUEST;
    
    ValidateContext(pContext);
    DEBUGMSG( ZONE_USB_EVENTS,(_T("%s:ProcessSetFeature udr.bmRequestType=0x%x, udr.wIndex=0x%x,udr.wValue=0x%x\r\n"),pszFname,udr.bmRequestType,udr.wIndex,udr.wValue));
    if ( (GET_REQUESET_RECIPIENT(udr.bmRequestType) == USB_REQUEST_FOR_ENDPOINT) && 
         (udr.wValue == USB_FEATURE_ENDPOINT_STALL) ) {
        BYTE bEndpoint = LOBYTE(udr.wIndex);
        DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Halt endpoint (0x%02x) request.\r\n"),
            pszFname, bEndpoint));

        PCPipe pPipe = FindPipe(pContext, bEndpoint);
        if (pPipe == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s Asked to halt invalid endpoint 0x%02x\r\n"),
                pszFname, bEndpoint));
            response = CR_STALL_DEFAULT_PIPE;
        }
        else {
            if (dwMsg == UFN_MSG_SETUP_PACKET) {
                pContext->PddInfo.pfnStallEndpoint(pContext->PddInfo.pvPddContext, 
                    pPipe->GetPhysicalEndpoint());
                response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            }
        }
    }
    else if ( (GET_REQUESET_RECIPIENT(udr.bmRequestType) == USB_REQUEST_FOR_DEVICE)) {
        switch (udr.wValue) {
          case USB_FEATURE_REMOTE_WAKEUP:
            pContext->fRemoteWakeupEnabled = TRUE;
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            break;
          case USB_FEATURE_B_HNP_ENABLE:
            if (pContext->hParentBusHandle && BusChildIoControl(pContext->hParentBusHandle,IOCTL_BUS_USBOTG_HNP_ENABLE,NULL,0)) {
                response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            }
            break;
          case USB_FEATURE_A_HNP_SUPPORT:
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            break;
          case USB_FEATURE_A_ALT_HNP_SUPPORT: {
            RETAILMSG(1, (_T("%s ProcessSetFeature: SetFeature (a_alt_hnp_support) indicate this device does not connected to OTG port!!!\r\n"), pszFname));
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
            break;
          }
        }
    }
    else if ( (GET_REQUESET_RECIPIENT(udr.bmRequestType) == USB_REQUEST_FOR_DEVICE) && 
              (udr.wValue == USB_FEATURE_REMOTE_WAKEUP) ) {
        pContext->fRemoteWakeupEnabled = TRUE;
        response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
    }


    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        response = CR_SUCCESS;
    }
    DEBUGMSG( ZONE_USB_EVENTS,(_T("%s:ProcessSetFeature return: response = %d \r\n"),pszFname,response));
    FUNCTION_LEAVE_MSG();

    return response;
}


// Handle a USB request.
static
CONTROL_RESPONSE
ProcessRequest(
    PUFN_MDD_CONTEXT pContext,
    USB_DEVICE_REQUEST udr,
    DWORD dwMsg
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -