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

📄 rndis_pdd.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 4 页
字号:
    // 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;

    // 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"));
}

// discard outstanding messages when reset
static VOID PDD_DiscardPendingMessages()
{
    PLIST_ENTRY pLink;
    PDATA_WRAPPER pDataWrapper;
    DWORD dwDiscards = 0;

    while (!IsListEmpty(&(g_RndisKitlDev.listTxRndisMessageQueue))) {
        // remove pending message
        pLink = RemoveHeadList(&(g_RndisKitlDev.listTxRndisMessageQueue));
        pDataWrapper = CONTAINING_RECORD(pLink, DATA_WRAPPER, Link);
        // let MDD free buffer
        MddSendRndisMessageComplete(pDataWrapper);
        // record number
        ++dwDiscards;
    }

    KITLOutputDebugString("Discard %d Pending Messages\r\n", dwDiscards);
}

////////////////////////////////////////////////////////////////////////////////
//  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"));
        PDD_DiscardPendingMessages();
        break;
    case REQ_ID_SOFT_RESET:
        OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_SOFT_RESET\r\n"));
        PDD_DiscardPendingMessages();
        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)
{
    GetRNDISMACAddress((UINT16*) g_RndisMacAddress);
}

// compute a unique device serial number
void SetRNDISSerialNumber(void)
{
    BYTE b;
    int i;
    BYTE *pIdBytes; 
    DWORD dwBytesReturned = 0;
    UINT16 mac[3];

    GetRNDISMACAddress(mac);
    pIdBytes = (BYTE*)&mac[0];

    for (i=0; i< 6; 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(mac) * 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
    ));
}

// Device Register Access.
void WriteUDCRegister(DWORD dwOffset, DWORD dwData) { 
    PREFAST_ASSERT(pUsbDevReg!=NULL);
    WRITE_REGISTER_ULONG(pUsbDevReg + dwOffset, dwData);
}
DWORD ReadUDCRegister(DWORD dwOffset) {
    PREFAST_ASSERT(pUsbDevReg!=NULL);
    return READ_REGISTER_ULONG(pUsbDevReg + dwOffset);
}

DWORD   ReadControlRegister() {  return ReadUDCRegister(DEVICE_CONTROL_REGISTER); }
void    WriteControlRegister(DWORD dwData) { WriteUDCRegister(DEVICE_CONTROL_REGISTER, dwData);}
DWORD   ReadIntrCtr0Register() { return ReadUDCRegister(DEVICE_INT_CR0_REGISTER); }
DWORD   ReadIntrCtr1Register() { return ReadUDCRegister(DEVICE_INT_CR1_REGISTER); }
DWORD   ReadIntrStatus0Register() { return ReadUDCRegister(DEVICE_INT_SR0_REGISTER); }
DWORD   ReadIntrStatus1Register() { return ReadUDCRegister(DEVICE_INT_SR1_REGISTER); }
void    WriteIntrCtr0Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_CR0_REGISTER, dwData); }
void    WriteIntrCtr1Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_CR1_REGISTER, dwData); }
void    WriteIntrStatus0Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_SR0_REGISTER,dwData); }
void    WriteIntrStatus1Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_SR1_REGISTER,dwData); }

⌨️ 快捷键说明

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