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

📄 rndis.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 4 页
字号:
                    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;

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDDInit\r\n"));

    g_mddInterface.dwVersion = 1;
    g_mddInterface.pfnNotify = NotifyHandler;

    memset( &g_pddInterface, 0, sizeof(g_pddInterface) );
    g_pddInterface.dwVersion = 1;

    // configure clock, I2C cotroller, USB OTG transceiver and USB OTG controller
    InitializeHardware();

    // initialize usb function unit
    if( UfnPdd_Init( NULL, NULL, &g_mddInterface, &g_pddInterface ) != ERROR_SUCCESS )
    {
        OALMSG(OAL_ERROR, (L"UfnPdd_Init failed!"));
        return FALSE;
    }

    // register device
    RegisterUSBDevice();

    // attach device to USB bus
    g_pddInterface.pfnStart( g_pddInterface.pvPddContext );

    SetRNDISMACAddress();
    SetRNDISSerialNumber();

    //
    // Everything ok, fill up our characteristics.
    //
    memset(pRndisPddCharacteristics, 0x00, sizeof(RNDIS_PDD_CHARACTERISTICS));

    pRndisPddCharacteristics->SendRndisMessageHandler = PDD_SendRndisMessage;
    pRndisPddCharacteristics->SendRndisPacketHandler = PDD_SendRndisPacket;
    pRndisPddCharacteristics->SetHandler = PDD_Set;
    pRndisPddCharacteristics->GetHandler = PDD_Get;
    pRndisPddCharacteristics->ISRHandler = PDD_ISR;
    pRndisPddCharacteristics->dwIRQ = -1;       // @todo : check this
    pRndisPddCharacteristics->dwMaxRx = MAX_INCOMING_BUFFER;
    pRndisPddCharacteristics->dwBaseAddr = (DWORD)pBaseAddress/*USB_CLIENT_BASE*/;       // TODO: check this 
    pRndisPddCharacteristics->IndicateRndisPacketCompleteHandler = PDD_IndicateRndisPacketComplete;

    // we are not a PCI device
    pRndisPddCharacteristics->bPCIDevice = FALSE;

    //
    // Everything is fine... Proceed!
    //
    InitializeListHead(&g_RndisKitlDev.listTxRndisMessageQueue);

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L" RNDIS_USBFN_PDDInit: initialization completed\r\n"
    ));

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDInit\r\n"));

    PDDZONE0 = 0;
    PDDZONE = 0;
    MDDZONE0 = 0;
    MDDZONE = 0;
    MDDZONE2 = 0;
    MDDZONE3 = 0; // 1
    MDDZONE4 = 0;
    MDDZONE5 = 0;

    return TRUE;
}

void PDDDeinit(void)
{
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDDDenit\r\n"));
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDDenit\r\n"));
}

////////////////////////////////////////////////////////////////////////////////
//  PDD_SendRndisMessage()
//  
//  Routine Description:
//
//      This routine is called by MDD to send one buffer through control 
//      channel.
//  
//  Arguments:
//      
//      pDataWrapper :: Structure containing the data..
//
//  Return Value:
//
//      None.
//

void PDD_SendRndisMessage(PDATA_WRAPPER  pDataWrapper)
{
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_SendRndisMessage\r\n"));

    //
    // We don't do the actual sending here but queue it up...
    // We then trigger Interrupt endpoint to send interrupt to host which will in turn
    // use EP0 to GET_ENCAPSULATED_RESPONSE
    InsertTailList((&g_RndisKitlDev.listTxRndisMessageQueue), &(pDataWrapper->Link));

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"+RNDIS_USBFN_PDD_SendRndisMessage: message queued.\r\n"
    ));
    // Interrupt (via interrupt endpoint) the host to GET_ENCAPSULATED_RESPONSE

    // g_EP3Transfer.dwCallerPermissions;
    g_EP3Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
    g_EP3Transfer.pvBuffer = &g_InterruptData;
    // g_EP3Transfer.dwBufferPhysicalAddress; // not used
    g_EP3Transfer.cbBuffer = sizeof(g_InterruptData);
    g_EP3Transfer.cbTransferred = 0;
    g_EP3Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
    g_EP3Transfer.pvPddData = NULL;
    g_EP3Transfer.pvPddTransferInfo = NULL;

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"+RNDIS_USBFN_PDD_SendRndisMessage: issuing interrupt...\r\n"
    ));
    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 3, &g_EP3Transfer );

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_SendRndisMessage\r\n"));

}

////////////////////////////////////////////////////////////////////////////////
//  PDD_SendRndisPacket()
//
//  Routine Description:
//
//      This routine is called by MDD to send data to host via IN pipe.
//      PDD is guaranteed to have only one outstanding packet to send until
//      the packet is retured to MDD via MddSendRndisPacketComplete()
//  
//  Arguments:
//      
//      pDataWrapper :: structure holding data we need to send.
//
//  Return Value:
//
//      None.
//

⌨️ 快捷键说明

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