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

📄 rndis.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 3 页
字号:

    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.
//
void PDD_SendRndisPacket(PDATA_WRAPPER pDataWrapper)
{    
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_SendRndisPacket\r\n"));
    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"Got SendPacket Request [%d bytes]\r\n", pDataWrapper->dwDataSize
    ));

    if (g_RndisKitlDev.pTxDataWrapper != NULL) {
        //
        // BAD!
        // This should never happen!!
        // Return the packet immediately..
        //
        OALMSG(OAL_ERROR, (L"****Multiple pending send rndis packet!!\r\n"));
        MddSendRndisPacketComplete(pDataWrapper);
    }

    // save the data wrapper pointer so we can return later it in TxComplete call
    g_RndisKitlDev.pTxDataWrapper = pDataWrapper;

    // Get permision same as caller
    // perm = GetCurrentPermissions();
    // SetProcPermissions(pTransfer->dwCallerPermissions);

    // g_EP2Transfer.dwCallerPermissions;
    g_EP2Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
    g_EP2Transfer.pvBuffer = pDataWrapper->pucData;
    // g_EP2Transfer.dwBufferPhysicalAddress; // not used
    g_EP2Transfer.cbBuffer = pDataWrapper->dwDataSize;
    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;

    g_EP2TransferState = TS_SENDING_PACKET;
    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 2, &g_EP2Transfer );

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

////////////////////////////////////////////////////////////////////////////////
//  PDD_Set()
//
//  Routine Description:
//
//      This routine is used by the MDD to set misc aspects of USB 
//      communication.
//  
//  Arguments:
//      
//      uiRequestId  :: As defined in rndismini.h
//      pvData       :: What to set to.
//      ulDataLength :: The length of data pointed to by pvData.
//
//  Return Value:
//
//      TRUE  :: If successful.
//      FALSE :: otherwise..
//
BOOL PDD_Set(
    IN  UINT    uiRequestId,
    IN  PVOID   pvData,
    IN  ULONG   ulDataLength)
{
    BOOL fRet = TRUE;

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_Set\r\n"));
    // TODO: finish all requests here
    switch(uiRequestId) {
    case REQ_ID_HARD_RESET:
        OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_HARD_RESET\r\n"));
        break;
    case REQ_ID_SOFT_RESET:
        OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_SOFT_RESET\r\n"));
        break;
    case REQ_ID_ENABLE_INT:
        OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_ENABLE_INT\r\n"));
        break;
    case REQ_ID_DISABLE_INT:
        OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_DISABLE_INT\r\n"));
        break;
    default:
        OALMSG(OAL_ETHER&&OAL_FUNC, (
            L"PDD_Set:Unknown request:0x%x\r\n", uiRequestId
        ));
        fRet = FALSE;
        break;
    }
    
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_Set\r\n"));
    return fRet;
}

////////////////////////////////////////////////////////////////////////////////
//  PDD_Get()
//
//  Routine Description:
//
//      This routine is used by MDD to query information pertaining to 
//      PDD (like vendor ID, Vendor description, etc).      
//  
//  Arguments:
//      
//      uiRequestId      :: as defined in RndisMini.h
//      pvData           :: The return buffer.
//      ulDataLength     :: Length of the buffer.
//      ulRequiredLength :: Return by us if the passed in buffer is not enough.
//
//  Return Value:
//
//      TRUE  :: If successful.
//      FALSE :: otherwise..
//

BOOL PDD_Get(
    IN  UINT    uiRequestId,
    IN  PVOID   pvData,
    IN  ULONG   ulDataLength,
    OUT ULONG   *pulRequiredLength)
{
    BOOL fRet = FALSE;
    ULONG GenericUlong;
    ULONG ulTotalBytes;
    PUCHAR pucBuffer;

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

    switch(uiRequestId) {
    case REQ_ID_VENDOR_ID:
        pucBuffer = pucVendorID;
        ulTotalBytes = strlen(pucVendorID);
        break;
    case REQ_ID_VENDOR_DESCRIPTION:
        pucBuffer = pucVendorDescription;
        ulTotalBytes = strlen(pucVendorDescription);
        break;
    case REQ_ID_DEVICE_MAX_RX:
        GenericUlong = MAX_INCOMING_BUFFER;
        pucBuffer = (UCHAR *)&GenericUlong;
        ulTotalBytes = sizeof(GenericUlong);
        break;
    case REQ_ID_DEVICE_MACADDR:
        pucBuffer = g_RndisMacAddress;
        ulTotalBytes = sizeof(g_RndisMacAddress);
        break;
    default:
        OALMSG(OAL_ETHER&&OAL_FUNC, (
            L"-PDD_Get: unknown request 0x%x\r\n", uiRequestId
        ));
        pucBuffer = NULL;
        ulTotalBytes = 0;
        break;
    }

    if (pucBuffer) {
        if (pulRequiredLength)
            *pulRequiredLength = ulTotalBytes;

        if (ulTotalBytes <= ulDataLength) {
            memcpy(pvData, pucBuffer, ulTotalBytes);
            fRet = TRUE;
        }
    }

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_Get\r\n"));
    return fRet;
}

////////////////////////////////////////////////////////////////////////////////
//  PDD_ISR()
//  
//  Routine Description:
//
//      This function handles the USB interrupt.
//  
//  Arguments:
//      
//      pdwWaitTime ::  The next time out value while waiting for interrupt..
//
//  Return Value:
//
//      TRUE  :: We want more interrupt coming..
//      FALSE :: We have enough, getting outta here!!! that's the end of 
//               eveything.. (in theory, should never be used..).
//

BOOL PDD_ISR(PDWORD  pdwWaitTime)
{
    InterruptThread( g_pddInterface.pvPddContext );

    return TRUE;
}   //  PDD_ISR()

////////////////////////////////////////////////////////////////////////////////
//  PDD_IndicateRndisPacketComplete()
//
//  Routine Description:
//
//      Called by MDD when the data passed to it via MddIndicateRndisPacket is
//      completed.
//  
//  Arguments:
//      
//      pucBuffer    :: Buffer passed in MddIndicateRndisPacket.
//      uiBufferSize :: Size of the buffer.
//
//  Return Value:
//
//      None.
//
void PDD_IndicateRndisPacketComplete(PDATA_WRAPPER   pDataWrapper)   
{
    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"+RNDIS_USBFN_PDD_IndicateRndisPacketComplete\r\n"
    ));
    MDDFreeMem(pDataWrapper->pucData);
    MDDFreeDataWrapper(pDataWrapper);
    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"-RNDIS_USBFN_PDD_IndicateRndisPacketComplete\r\n"
    ));
}

// compute a unique MAC address
void SetRNDISMACAddress(void)
{
    DWORD udId = GetUniqueDeviceID();
    g_RndisMacAddress[2] = (UCHAR)(udId);
    g_RndisMacAddress[3] = (UCHAR)(udId >> 8);
    g_RndisMacAddress[4] = (UCHAR)(udId >> 16);
    g_RndisMacAddress[5] = (UCHAR)(udId >> 24);
}

// compute a unique device serial number
void SetRNDISSerialNumber(void)
{
    BYTE b;
    int i;
    BYTE *pIdBytes; 
    DWORD dwBytesReturned = 0;
    DWORD udId = GetUniqueDeviceID();
    
    pIdBytes = (BYTE*)&udId;

    for (i=0; i< sizeof(udId); i++) {
        b = pIdBytes[i] & 0xff;
        gs_SerialNumber.ptcbString[i * 2] = DigitTable[b % 16];
        gs_SerialNumber.ptcbString[(i * 2) + 1] = DigitTable[b / 16];
    }

    gs_SerialNumber.ptcbString[sizeof(udId) * 2] = '\0';
    gs_SerialNumber.ucbLength = sizeof(gs_SerialNumber);
    gs_SerialNumber.udbDescriptorType = USB_STRING_DESCRIPTOR_TYPE;

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"RNDIS Serial Number=[%s]\r\n", gs_SerialNumber.ptcbString
    ));
}

#pragma optimize ( "", on )

⌨️ 快捷键说明

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