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

📄 kitleth.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
}

//------------------------------------------------------------------------------
//
//  Function:  KitlEthSend
//
//  This function is called by KITL to send packet over transport layer
//
static BOOL KitlEthSend(UCHAR *pData, USHORT length)
{
    UCHAR *pSendData;
    ULONG sendLength;
    USHORT code;
    int   nRetries = 0;

    KITL_RETAILMSG(ZONE_SEND,  (
        "+KitlEthSend(0x%08x, %d)\r\n", pData, length
    ));

    // Update multicast addresses
    if (g_kitlEthState.updateMCast) {
        if (g_kitlEthState.pDriver->pfnMulticastList)
            g_kitlEthState.pDriver->pfnMulticastList(
                g_kitlEthState.deviceMCast, g_kitlEthState.deviceMCastSize
            );
        g_kitlEthState.updateMCast = FALSE;
    }

    // Update filter 
    if (g_kitlEthState.updateFilter) {
        // Update filter
        g_kitlEthState.pDriver->pfnCurrentPacketFilter(
            g_kitlEthState.deviceFilter
        );
        // Tell VBRIDGE that there is new filter
        VBridgeUCurrentPacketFilter(&g_kitlEthState.deviceFilter);
        g_kitlEthState.updateFilter = FALSE;
    }

    do {
        code = g_kitlEthState.pDriver->pfnSendFrame(pData, length);
        if (code == 0) {
            if (g_kitlEthState.flags & OAL_KITL_FLAGS_VMINI) {
                // Consume all the client packets.
                while (VBridgeKGetOneTxBuffer(&pSendData, &sendLength)) {
                    g_kitlEthState.pDriver->pfnSendFrame(pSendData, (USHORT)sendLength);
                    VBridgeKGetOneTxBufferComplete(pSendData);
                }
            }
            break;
        }
        KITL_RETAILMSG(ZONE_ERROR, ("!Driver Send failure, retry %u\n",nRetries));
    } while (nRetries ++ < 8);

    KITL_RETAILMSG(ZONE_SEND,  (
        "-KitlEthSend(rc = %d)\r\n", code == 0));
    return code == 0;
}

//------------------------------------------------------------------------------
//
//  Function:  KitlEthRecv
//
//  This function is called by KITL to receive packet from transport layer
//
static BOOL KitlEthRecv(UCHAR *pData, USHORT *pLength)
{
    USHORT code;
    UCHAR *pSendData;
    ULONG sendLength;

    KITL_RETAILMSG(ZONE_RECV,  (
        "+KitlEthRecv(0x%08x, 0x%08x->%d)\r\n", pData, pLength, *pLength
    ));

    // Update multicast addresses
    if (g_kitlEthState.updateMCast) {
        if (g_kitlEthState.pDriver->pfnMulticastList)
            g_kitlEthState.pDriver->pfnMulticastList(
                g_kitlEthState.deviceMCast, g_kitlEthState.deviceMCastSize
            );
        g_kitlEthState.updateMCast = FALSE;
    }

    // Update filter 
    if (g_kitlEthState.updateFilter) {
        // Update filter
        g_kitlEthState.pDriver->pfnCurrentPacketFilter(
            g_kitlEthState.deviceFilter
        );
        // Tell VBRIDGE that there is new filter
        VBridgeUCurrentPacketFilter(&g_kitlEthState.deviceFilter);
        g_kitlEthState.updateFilter = FALSE;
    }

    // When VMINI is active send all queued VMINI packets
    if ((g_kitlEthState.flags & OAL_KITL_FLAGS_VMINI) != 0) {
        // First send all VMINI packets
        while (VBridgeKGetOneTxBuffer(&pSendData, &sendLength)) {
            g_kitlEthState.pDriver->pfnSendFrame(pSendData, (USHORT)sendLength);
            VBridgeKGetOneTxBufferComplete(pSendData);
        }
    }

    // Now get packet
    code = g_kitlEthState.pDriver->pfnGetFrame(pData, pLength);

    KITL_RETAILMSG(ZONE_RECV, ("-KitlEthRecv(rc = %d)\r\n", code > 0));
    return code > 0;
}


//------------------------------------------------------------------------------
//
//  Function:  KitlEthEnableInt
//
//  This function is called by KITL to enable and disable the KITL transport
//  interrupt if the transport is interrupt-based
//
//
static VOID KitlEthEnableInt(BOOL enable)
{
    KITL_RETAILMSG(ZONE_KITL_OAL, ("+KitlEthEnableInt(%d)\r\n", enable));
    if (enable) {
        g_kitlEthState.pDriver->pfnEnableInts();
    } else {
        g_kitlEthState.pDriver->pfnDisableInts();
    }
    KITL_RETAILMSG(ZONE_KITL_OAL, ("-KitlEthEnableInt\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  OALIoCtlVBridge
//
//  This function implements OEMKitlIoctl calls, e.g. VMINI related IOCTL codes.
//
BOOL OALIoCtlVBridge(
    UINT32 code, VOID *pInBuffer, UINT32 inSize, VOID *pOutBuffer, 
    UINT32 outSize, UINT32 *pOutSize
) {
    BOOL rc = TRUE;

    KITL_RETAILMSG(ZONE_SEND|ZONE_RECV, ("+OALIoCtlVBridge(0x%08x,...)\r\n", code));

    switch (code) {
    case IOCTL_VBRIDGE_GET_TX_PACKET:
        rc = VBridgeUGetOneTxPacket((UINT8**)pOutBuffer, inSize);
        break;

    case IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE:
        VBridgeUGetOneTxPacketComplete((UINT8*)pInBuffer, inSize);
        break;

    case IOCTL_VBRIDGE_GET_RX_PACKET:
        rc = VBridgeUGetOneRxPacket((UINT8**)pOutBuffer, pOutSize);
        break;

    case IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE:
        VBridgeUGetOneRxPacketComplete((UINT8*)pInBuffer);
        break;

    case IOCTL_VBRIDGE_GET_ETHERNET_MAC:
        VBridgeUGetEDBGMac((UINT8*)pOutBuffer);
        break;

    case IOCTL_VBRIDGE_CURRENT_PACKET_FILTER:
        g_kitlEthState.deviceFilter = *(UINT32*)pInBuffer;
        g_kitlEthState.updateFilter = TRUE;
        break;

    case IOCTL_VBRIDGE_802_3_MULTICAST_LIST:
        if (inSize * 6 <= sizeof(g_kitlEthState.deviceMCast)) {
            memcpy(g_kitlEthState.deviceMCast, pInBuffer, inSize * 6);
            g_kitlEthState.deviceMCastSize = inSize;
            g_kitlEthState.updateMCast = TRUE;
        } else {
            rc = FALSE;
        }
        break;

    case IOCTL_VBRIDGE_WILD_CARD:
        rc = VBridgeUWildCard(
            pInBuffer, inSize, pOutBuffer, outSize, pOutSize
        );
        break;

    case IOCTL_VBRIDGE_SHARED_ETHERNET:
        break;

    default:
        NKSetLastError (ERROR_NOT_SUPPORTED);
        rc = FALSE;
    }

    KITL_RETAILMSG(ZONE_SEND|ZONE_RECV, ("-OALIoCtlVBridge(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  OALKitlEthInit
//
//  This function is called by OAL to initialize KITL Ethernet/IP4 protocol
//  driver. It first initialize KITL device, fill KITLTRANSPORT structure
//  and if OAL_KITL_FLAGS_DHCP flag is set it gets or renews IP4 address
//  from DHCP server.
//
BOOL OALKitlEthInit(
    LPSTR deviceId, OAL_KITL_DEVICE *pDevice, OAL_KITL_ARGS *pArgs,
    KITLTRANSPORT *pKitl
) {
    BOOL rc = FALSE;
    OAL_KITL_ETH_DRIVER *pDriver;
    UINT32 irq, sysIntr;

    KITL_RETAILMSG(ZONE_KITL_OAL, (
        "+OALKitlEthInit('%S', '%s', 0x%08x, 0x%08x)\r\n",
        deviceId, pDevice->name, pArgs, pKitl
    ));

    // Cast driver config parameter
    pDriver = (OAL_KITL_ETH_DRIVER*)pDevice->pDriver;
    if (pDriver == NULL) {
        KITL_RETAILMSG(ZONE_ERROR, ("ERROR: KITL device driver is NULL\r\n"));
        goto cleanUp;
    }

    // Call InitDmaBuffer if there is any
    if (pDriver->pfnInitDmaBuffer != NULL) {
        if (!pDriver->pfnInitDmaBuffer(
            (DWORD)g_oalKitlBuffer, sizeof(g_oalKitlBuffer)
        )) {
                KITL_RETAILMSG(ZONE_ERROR, (
                "ERROR: KITL call to pfnInitDmaBuffer failed\r\n"
            ));
            goto cleanUp;
        }
    }

    // Call pfnInit
    if (!pDriver->pfnInit(
        (UCHAR*)pArgs->devLoc.PhysicalLoc, pArgs->devLoc.LogicalLoc, pArgs->mac
    )) {
        KITL_RETAILMSG(ZONE_ERROR, ("ERROR: KITL call to pfnInit failed\r\n"));
        goto cleanUp;
    }

    // Extend name if flag is set
    if ((pArgs->flags & OAL_KITL_FLAGS_EXTNAME) != 0) {
        OALKitlCreateName(deviceId, pArgs->mac, deviceId);
    }

    // Now we know final name, print it
    KITL_RETAILMSG(ZONE_INIT, ("KITL: *** Device Name %s ***\r\n", deviceId));

    // Map and enable interrupt
    if ((pArgs->flags & OAL_KITL_FLAGS_POLL) != 0) {
        sysIntr = KITL_SYSINTR_NOINTR;
    } else {
        // Get IRQ, when interface is undefined use Pin as IRQ
        if (pArgs->devLoc.IfcType == InterfaceTypeUndefined) {
            irq = pArgs->devLoc.Pin;
        } else {
            if (!OEMIoControl(
                IOCTL_HAL_REQUEST_IRQ, &pArgs->devLoc, sizeof(pArgs->devLoc),
                &irq, sizeof(irq), NULL
            )) {                
                    KITL_RETAILMSG(ZONE_WARNING, (
                    "WARN: KITL can't obtain IRQ for KITL device\r\n"
                ));
                irq = OAL_INTR_IRQ_UNDEFINED;
            }
        }
        // Get SYSINTR for IRQ
        if (irq != OAL_INTR_IRQ_UNDEFINED) {
            UINT32 aIrqs[3];

            aIrqs[0] = -1;
            aIrqs[1] = (pArgs->devLoc.IfcType == InterfaceTypeUndefined)
                        ? OAL_INTR_TRANSLATE
                        : OAL_INTR_FORCE_STATIC;
            aIrqs[2] = irq;
            if (
                OEMIoControl(
                    IOCTL_HAL_REQUEST_SYSINTR, aIrqs, sizeof(aIrqs), &sysIntr,
                    sizeof(sysIntr), NULL
                ) && sysIntr != SYSINTR_UNDEFINED
            ) {                
                KITL_RETAILMSG(ZONE_INIT, ("KITL: using sysintr 0x%x\r\n", sysIntr));
            } else {
                KITL_RETAILMSG(ZONE_WARNING, (
                    "WARN: KITL can't obtain SYSINTR for IRQ %d\r\n", irq
                ));
                sysIntr = KITL_SYSINTR_NOINTR;
            }
        } else {
            sysIntr = KITL_SYSINTR_NOINTR;
        }
    }


    if (sysIntr == KITL_SYSINTR_NOINTR) {
        KITL_RETAILMSG(ZONE_WARNING, (
            "WARN: KITL will run in polling mode\r\n"
        ));
    }

    //-----------------------------------------------------------------------
    // Initalize KITL transport structure
    //-----------------------------------------------------------------------

    memcpy(pKitl->szName, deviceId, sizeof(pKitl->szName));
    pKitl->Interrupt     = (UCHAR)sysIntr;
    pKitl->WindowSize    = OAL_KITL_WINDOW_SIZE;
    pKitl->FrmHdrSize    = KitlEthGetFrameHdrSize();
    pKitl->dwPhysBuffer  = 0;
    pKitl->dwPhysBufLen  = 0;
    pKitl->pfnEncode     = KitlEthEncode;
    pKitl->pfnDecode     = KitlEthDecode;
    pKitl->pfnSend       = KitlEthSend;
    pKitl->pfnRecv       = KitlEthRecv;
    pKitl->pfnEnableInt  = KitlEthEnableInt;
    pKitl->pfnGetDevCfg  = KitlEthGetDevCfg;
    pKitl->pfnSetHostCfg = KitlEthSetHostCfg;

    //-----------------------------------------------------------------------
    // Initalize KITL IP4 state structure
    //-----------------------------------------------------------------------

    g_kitlEthState.pDriver = pDriver;
    g_kitlEthState.flags = pArgs->flags;
    g_kitlEthState.deviceMAC[0] = (UINT8)pArgs->mac[0];
    g_kitlEthState.deviceMAC[1] = (UINT8)(pArgs->mac[0] >> 8);
    g_kitlEthState.deviceMAC[2] = (UINT8)pArgs->mac[1];
    g_kitlEthState.deviceMAC[3] = (UINT8)(pArgs->mac[1] >> 8);
    g_kitlEthState.deviceMAC[4] = (UINT8)pArgs->mac[2];
    g_kitlEthState.deviceMAC[5] = (UINT8)(pArgs->mac[2] >> 8);
    g_kitlEthState.deviceIP = pArgs->ipAddress;

    g_kitlEthState.kitlServerMAC[0] = 0xFF;
    g_kitlEthState.kitlServerMAC[1] = 0xFF;
    g_kitlEthState.kitlServerMAC[2] = 0xFF;
    g_kitlEthState.kitlServerMAC[3] = 0xFF;
    g_kitlEthState.kitlServerMAC[4] = 0xFF;
    g_kitlEthState.kitlServerMAC[5] = 0xFF;
    g_kitlEthState.kitlServerIP = 0xFFFFFFFF;
    g_kitlEthState.kitlServerPort = htons(KITL_SERVER_PORT);

    g_kitlEthState.dhcpXId = pArgs->mac[2] | 0x17016414;
    g_kitlEthState.dhcpState = DHCP_BOUND;

    // Get or renew DHCP address
    if ((pArgs->flags & OAL_KITL_FLAGS_DHCP) != 0) {
        // KITL isn't running let use direct functions for send/receive
        g_kitlEthState.pfnSend = pKitl->pfnSend;
        g_kitlEthState.pfnRecv = pKitl->pfnRecv;
        // Get or renew address from DHCP server
        GetAddressDHCP(pArgs->ipAddress);
    }

    // When KITL is running we should call sync function for send
    g_kitlEthState.pfnSend = KitlSendRawData;

    // There should not be direct receive
    g_kitlEthState.pfnRecv = NULL;

#ifdef KITL_ETHER     
    // Activate VMINI bridge...
    if ((pArgs->flags & OAL_KITL_FLAGS_VMINI) != 0) {
        VBridgeInit();
        VBridgeKSetLocalMacAddress((char*)pArgs->mac);
    }
#endif

    // Result depends on fact if we get IP address
    rc = (g_kitlEthState.deviceIP != 0);
    

cleanUp:
    KITL_RETAILMSG(ZONE_KITL_OAL, ("-OALKitlEthInit(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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