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

📄 rndis.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 3 页
字号:
            OALMSG(OAL_ERROR, (L"No mem for RX data\r\n"));
            MDDFreeDataWrapper(g_pEP1DataWrapper);
            return;
        }
        g_pEP1DataWrapper->dwDataSize = MAX_INCOMING_BUFFER;
    }

    // g_EP1Transfer.dwCallerPermissions;
    g_EP1Transfer.pvBuffer = g_pEP1DataWrapper->pucData;
    // g_EP1Transfer.dwBufferPhysicalAddress; // not used
    g_EP1Transfer.cbBuffer = g_pEP1DataWrapper->dwDataSize;
    g_EP1Transfer.cbTransferred = 0;
    g_EP1Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
    g_EP1Transfer.pvPddData = NULL;
    g_EP1Transfer.pvPddTransferInfo = NULL;
    g_EP1Transfer.dwFlags = 0;
    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 1, &g_EP1Transfer );
}

// parses the setup packet received on EP0
BOOL HandleSetupPacket(USB_DEVICE_REQUEST *pUdr, EP0_REQUEST *pRequest)
{
    if (pUdr->bmRequestType & (USB_REQUEST_CLASS | USB_REQUEST_VENDOR)) {
        if (PDD_DoVendorCommand(pUdr, pRequest)) {
            // do nothing
        } else {
            OALMSG(OAL_ERROR, (
                L"**** Unhandled verndor command 0x%x\r\n", pUdr->bRequest
            ));
            pRequest->eDir = EP0Setup;
            pRequest->pucData = NULL;
            pRequest->dwExpectedSize = 0;
            pRequest->dwActualSize = 0;
            pRequest->pfnNotification = NULL;
            pRequest->pvUser = NULL;
        }
        return TRUE;
    }

    // standard chapter 9 commands
    pRequest->eDir = EP0Setup;
    pRequest->pucData = NULL;
    pRequest->dwExpectedSize = 0;
    pRequest->dwActualSize = 0;
    pRequest->pfnNotification = NULL;
    pRequest->pvUser = NULL;

    switch(pUdr->bRequest) {
        case USB_REQUEST_GET_STATUS:
            if (pUdr->bmRequestType == 0x82) {
                // TODO: handle this
                OALMSG(OAL_WARN, (L"***RequestType==0x82\r\n"));
                // check for the stall bit
            }
            break;

        case USB_REQUEST_CLEAR_FEATURE:
            if (pUdr->bmRequestType == 0x02) {
                // TODO: handle this
                OALMSG(OAL_WARN, (L"***RequestType==0x02\r\n"));
            }
            break;

        case USB_REQUEST_SET_FEATURE:
            if (pUdr->bmRequestType == 0x02) {
                // TODO: handle this
                OALMSG(OAL_WARN, (L"***RequestType==0x02\r\n"));
            }
            break;

        case USB_REQUEST_SET_ADDRESS:
            // TODO: handle this
            break;

        case USB_REQUEST_GET_DESCRIPTOR:
            if (PDD_GetDescriptor(pUdr, pRequest)) {
                // do nothing
            } else {
                OALMSG(OAL_ERROR, (
                    L"*** UnHandled GET_DESCRIPTOR request:0x%x\r\n",
                    pUdr->wValue
                ));
            }
            break;

        case USB_REQUEST_SET_DESCRIPTOR:
            // TODO: handle this
            break;

        case USB_REQUEST_GET_CONFIGURATION:
            // TODO: handle this
            break;

        case USB_REQUEST_SET_CONFIGURATION:
            OALStall(5000);
            // setup RX transfer on EP1
            SetupEP1Transfer();
            ////pDev->ucConfigValue = (BYTE)pUdr->wValue;
            break;

        case USB_REQUEST_GET_INTERFACE:
            // TODO: handle this
            break;

        case USB_REQUEST_SET_INTERFACE:
            // TODO: handle this
            break;

        case USB_REQUEST_SYNC_FRAME:
            // TODO: handle this
            break;

        default:
            OALMSG(OAL_WARN, (
                L"*** Unknown request 0x%x\r\n", pUdr->bRequest
            ));
    }
    return TRUE;
}

// indicates to the KITL MDD that a packet has been sent
void TxComplete(void)
{
    RNDIS_KITLDEV *pRndisKitlDev = &g_RndisKitlDev;

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"SendPacket request completed! [%d bytes]\r\n", 
        g_EP2Transfer.cbTransferred 
    ));
    MddSendRndisPacketComplete(pRndisKitlDev->pTxDataWrapper);

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done\r\n"));
    pRndisKitlDev->pTxDataWrapper = NULL;
}

// The USB FN PDD will call this function to notify it of various events (data sent/received, 
// setup packet received, device addressed, reset, etc.
BOOL WINAPI NotifyHandler (
    PVOID pvMddContext,
    DWORD dwMsg,
    DWORD dwParam
    )
{
    USB_DEVICE_REQUEST request;
    EP0_REQUEST EP0Request;
    STransfer *pTransfer;

    switch( dwMsg )
    {
    case UFN_MSG_SETUP_PACKET:
        request = *(USB_DEVICE_REQUEST*)(void*)dwParam;
        g_udr = request;

        if( !HandleSetupPacket( &g_udr, &EP0Request ) )
        {
            OALMSG(OAL_ERROR, (L"ERROR PARSING SETUP PACKET\r\n"));
        }

        memcpy(&g_RndisKitlDev.EP0Request, &EP0Request, sizeof(EP0Request));
        g_RndisKitlDev.EP0Request.dwProcessed = 0;
        g_RndisKitlDev.EP0Request.fCompleted = FALSE;

        if (g_RndisKitlDev.EP0Request.eDir != EP0Setup) {
            g_EP0DataWrapper.pucData = g_RndisKitlDev.EP0Request.pucData;
            g_EP0DataWrapper.dwDataSize = g_RndisKitlDev.EP0Request.dwActualSize;
            
            // g_EP2Transfer.dwCallerPermissions;
            g_EP0Transfer.pvBuffer = g_EP0DataWrapper.pucData;
            // g_EP2Transfer.dwBufferPhysicalAddress; // not used
            g_EP0Transfer.cbBuffer = g_EP0DataWrapper.dwDataSize;
            g_EP0Transfer.cbTransferred = 0;
            g_EP0Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
            g_EP0Transfer.pvPddData = NULL;
            g_EP0Transfer.pvPddTransferInfo = NULL;

            if (g_RndisKitlDev.EP0Request.eDir == EP0In) {
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"Got SETUP IN packet\r\n"));
                g_EP0Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
                g_EP0TransferState = TS_SENDING_MESSAGE;
                g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 0, &g_EP0Transfer );
            }
            else
            {
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"Got SETUP OUT packet.\r\n"));
                g_EP0Transfer.dwFlags = 0;
                g_EP0TransferState = TS_RECEIVING_MESSAGE;
                g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 0, &g_EP0Transfer );
            }
        }
        else
        {
            OALMSG(OAL_ETHER&&OAL_FUNC, (
                L"Got SETUP <NO DATA: %x %x %x %x %x> packet.\r\n",
                g_udr.bmRequestType, g_udr.bRequest, g_udr.wValue, g_udr.wIndex,
                 g_udr.wLength 
            ));

            // Send the SETUP ACK packet
            g_EP0TransferState = TS_IDLE;
            g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );
        }
        break;

    case UFN_MSG_TRANSFER_COMPLETE: 
        pTransfer = (STransfer *)dwParam;
        if( pTransfer == &g_EP0Transfer )
        {
            switch( g_EP0TransferState )
            {
            case TS_RECEIVING_MESSAGE:
                g_EP0TransferState = TS_IDLE;
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done receiving data.\r\n"));

                g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );

                if (g_RndisKitlDev.EP0Request.pfnNotification) {
                    OALMSG(OAL_ETHER&&OAL_FUNC, (L"Received a message!\r\n"));
                    g_RndisKitlDev.EP0Request.pfnNotification(&g_RndisKitlDev.EP0Request, g_RndisKitlDev.EP0Request.pvUser);
                }
                memset(&g_RndisKitlDev.EP0Request, 0, sizeof (g_RndisKitlDev.EP0Request));
                break;
            case TS_SENDING_MESSAGE:
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done sending data.\r\n"));

                g_EP0TransferState = TS_IDLE;
                g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );

                if (g_RndisKitlDev.EP0Request.pfnNotification) {
                    OALMSG(OAL_ETHER&&OAL_FUNC, (L"SendMessage request completed!\r\n"));
                    g_RndisKitlDev.EP0Request.pfnNotification(&g_RndisKitlDev.EP0Request, g_RndisKitlDev.EP0Request.pvUser);

                    //memset(&g_RndisKitlDev.EP0Request, 0, sizeof (g_RndisKitlDev.EP0Request));
                    g_RndisKitlDev.EP0Request.pfnNotification = NULL;
                    g_RndisKitlDev.EP0Request.pvUser = NULL;
                }
                break;
            }
        }
        else if( pTransfer == &g_EP1Transfer )
        {
            // BULK OUT data received on EP1
            OALMSG(OAL_ETHER&&OAL_FUNC, (
                L"Received a packet [%d bytes]!\r\n", pTransfer->cbTransferred
            ));
            // notify the MDD
            g_pEP1DataWrapper->dwDataSize = pTransfer->cbTransferred;
            MddIndicateRndisPacket(g_pEP1DataWrapper);
            g_pEP1DataWrapper = NULL;
            // setup another transfer
            SetupEP1Transfer();
        }
        else if( pTransfer == &g_EP2Transfer )
        {
            if( g_EP2TransferState == TS_SENDING_PACKET )
            {
                if( ( g_EP2Transfer.cbTransferred % EPMaxSize ) == 0 )
                {
                    // g_EP2Transfer.dwCallerPermissions;
                    g_EP2Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
#ifdef USE_1BYTE_TERMINATING_PACKETS
                    g_EP2Transfer.pvBuffer = &g_ucScratch;
                    g_EP2Transfer.cbBuffer = sizeof(UCHAR);
#else
                    g_EP2Transfer.pvBuffer = NULL;
                    g_EP2Transfer.cbBuffer = 0;
#endif
                    // g_EP2Transfer.dwBufferPhysicalAddress; // not used
                    g_EP2Transfer.cbTransferred = 0;
                    g_EP2Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
                    g_EP2Transfer.pvPddData = NULL;
                    g_EP2Transfer.pvPddTransferInfo = NULL;


                    OALMSG(OAL_ETHER&&OAL_FUNC, (
                        L"Sending NULL terminator for the packet...\r\n"
                    ));
                    g_EP2TransferState = TS_SENDING_PACKET_TERMINATOR;
                    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 2, &g_EP2Transfer );
                }
                else
                {
                    g_EP2TransferState = TS_IDLE;
                    TxComplete();
                }
            }
            else if( g_EP2TransferState == TS_SENDING_PACKET_TERMINATOR )
            {
                ASSERT( g_EP2Transfer.dwUsbError == UFN_NO_ERROR );
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"SendPacket NULL terminator sent!\r\n"));
                g_EP2TransferState = TS_IDLE;

                TxComplete();
            }
            else
            {
                OALMSG(OAL_ERROR, (L"Unexpected EP2 transfer state!"));
            }
        }
        else if( pTransfer == &g_EP3Transfer )
        {
            OALMSG(OAL_ETHER&&OAL_FUNC, (
                L"EP3 Interrupt successfully sent!\r\n"
            ));
            // interrupt succesfully sent
        }
        else
        {
            OALMSG(OAL_ERROR, (L"INVALID TRANSFER!\r\n"));
        }
        break;

    case UFN_MSG_BUS_EVENTS:
        switch( dwParam )
        {
        case UFN_DETACH:
            g_devState = DS_DETACHED;
            break;
        case UFN_ATTACH:
            g_devState = DS_ATTACHED;
            break;
        case UFN_RESET:
            g_devState = DS_DEFAULT;
            g_EP0TransferState = TS_IDLE;
            g_EP2TransferState = TS_IDLE;
            break;
        case UFN_SUSPEND:
            g_devState = DS_ATTACHED;
            break;
        case UFN_RESUME:
            g_devState = DS_ATTACHED;
            break;
        default:
            ASSERT(!"Unexpected bus event!");
        }
        break;

    case UFN_MSG_BUS_SPEED:
        break;

    case UFN_MSG_SET_ADDRESS:
        if( dwParam )
        {
            g_devState = DS_ADDRESSED;
        }
        else
        {
            g_devState = DS_DEFAULT;
        }
        // we should call pfnSetAddress here
        break;

    default:
        ASSERT(!"Unexpected Msg in NotifyHandler!");
    }

    return FALSE;
}

// register the USB device, setup the non zero endpoints
void RegisterUSBDevice()
{
    static USB_DEVICE_DESCRIPTOR deviceDescriptor;
    static UFN_ENDPOINT rgEndPoints[3];
    static UFN_INTERFACE Interface;
    static UFN_CONFIGURATION deviceConfiguration;

    deviceConfiguration.pInterfaces = &Interface;
	deviceConfiguration.Descriptor.bNumInterfaces = 1;
    Interface.pEndpoints = rgEndPoints;
    Interface.Descriptor.bNumEndpoints = 3;
    rgEndPoints[0].Descriptor.bEndpointAddress = 0x01; // EP1, OUT (BULK)
    rgEndPoints[0].Descriptor.wMaxPacketSize = EPMaxSize;
    rgEndPoints[0].Descriptor.bmAttributes = 0;
    rgEndPoints[1].Descriptor.bEndpointAddress = 0x82; // EP2, IN (BULK)
    rgEndPoints[1].Descriptor.wMaxPacketSize = EPMaxSize;
    rgEndPoints[1].Descriptor.bmAttributes = 0;
    rgEndPoints[2].Descriptor.bEndpointAddress = 0x83; // EP3, IN (INT)
    rgEndPoints[2].Descriptor.wMaxPacketSize = EPMaxSize;
    rgEndPoints[2].Descriptor.bmAttributes = 0;
    deviceDescriptor.bMaxPacketSize0 = EP0MaxSize;


    // We assume knowledge of the RegisterDevice function implementation and pass very simplified arguments
    g_pddInterface.pfnRegisterDevice( g_pddInterface.pvPddContext, 
                                        NULL, NULL, NULL,
                                        &deviceDescriptor, &deviceConfiguration, NULL,
                                        NULL, 0 );
}

// initialize the USB KITL driver
BOOL PDDInit(
  RNDIS_PDD_CHARACTERISTICS* pRndisPddCharacteristics,
  PBYTE pBaseAddress
)
{
    PDDZONE0 = 0;
    PDDZONE = 0;
    MDDZONE0 = 0;
    MDDZONE = 1;
    MDDZONE2 = 1;
    MDDZONE3 = 1;
    MDDZONE4 = 1;
    MDDZONE5 = 0;

⌨️ 快捷键说明

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