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

📄 nnetdrv.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
            NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);

            SNMP_ifOutErrors_Inc(device->dev_index);
        }

        /* Initialize the data required to generate the events.  Note that the
           MNTID field was initialized up above. */
        mGeneventOut->SelfID = MNT_ID;
        mGeneventOut->MemPtr = MNT_Header_Ptr->MNT_hdr_cpuDesc;
        mGeneventOut->Count  = mRingputInfo->Count;

        status = DeviceIoControl (hDriver,
                              (DWORD) IOCTL_MULTI_GENEVENT,
                              mGeneventOut,
                              sizeof(ULONG) * (3 + mGeneventOut->Count),
                              &successCount,
                              sizeof(ULONG),
                              &cbReturned,
                              0);

        /* Check to see that all the events were generated. */
        if (successCount != mGeneventOut->Count)
        {
            SNMP_ifOutErrors_Inc(device->dev_index);
              
            NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);
        }

        
        SNMP_ifOutOctets(device->dev_index, pack_addr->mem_total_data_len);

    }
    else
    {
        /* The following steps must be performed to process this packet.

            1)  First we need the ID of the MNT process to which the packet is
                to be sent.  That is simple enough.  It can be extracted from
                the packet (the destination ethernet address is also the ID.)
                Unless this is destined for a node on a real network.  This can
                also be determined from the ethernet address.  In which case we
                send it to NDIS whose ID is always 0.

            2)  Once we know the ID a ringget can be performed to extract a
                buffer from the buffer free list.  ringget should return either
                a pointer or an offset from the beginning of the common memory
                area.  In either case the packet can be copied to this buffer.

            3)  Next a ringput is performed to place the now ready buffer
                into the receive list for the destination node, whether that be
                NDIS or some MNT process.

            4)  Finally a genevent will be performed to let the receiving node
                know that a packet is awaiting processing.
        */

        /* Is this packet destined for a node on the virtual network or for a
           node on the real network.  If destined for the virtual network then
           the ID is the same as the last octet of the ethernet address.  Else
           the ID equals 0, i.e., the ID for the NDIS driver.
        */
        if( (memcmp(dlayer->dest, "\0\0\0\0\0", 5) == 0)
             && ((dlayer->dest[5] - (CHAR)VNET_BaseEtherAddr) < (LONG)VNET_Ncpu) 
             && (dlayer->dest[5] != 0))
        {
            /* The packet is destined for the virtual network.
               The destination id = last octet of ether addr - base ether addr. */
            dest_id = dlayer->dest[5] - (CHAR)VNET_BaseEtherAddr;
        }
        else
        {
            /* This packet needs to go to the NDIS driver. */
            dest_id = 0;
        }

        mnt_cpu_ptr = MNT_Header_Ptr->MNT_hdr_cpuDesc;

        if(!mnt_cpu_ptr[dest_id].MNT_cd_active)
            return -1;


        /* Do a ringget from the buffer free list. */

        /* We will need to provide the pointer to the anchor and a pointer to
           the freelist ring.  Note that the driver needs the address that was
           mapped by NDIS. */
        ringgetInfo.MemPtr = NDISComMemStart;
        ringgetInfo.RingPtr = ItoKval(MNT_Header_Ptr->MNT_hdr_pFreeRing,
                                      PMNT_RING,
                                      NDISComMemStart);

        if (!DeviceIoControl (hDriver,
                         (DWORD) IOCTL_RINGGET,
                         &ringgetInfo,
                         sizeof(ringgetInfo),
                         &bufferOffset,
                         sizeof(bufferOffset),
                         &cbReturned,
                         0) )
        {

            SNMP_ifOutErrors_Inc(device->dev_index);
            NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);
            return -1;
        }

        /* Was a buffer retrieved? */
        if(bufferOffset == 0)
        {
            SNMP_ifOutErrors_Inc(device->dev_index);
            return -1;
        }

        buf_node_ptr = ItoKval(bufferOffset, PMNT_BUF_NODE, CommonMemPtr);

        /* Copy the packet from the buffer chain. */

        /* Do the parent buffer first */
        memcpy((CHAR *)CommonMemPtr + (ULONG)buf_node_ptr->MNT_b_addr,
                buf_ptr->data_ptr, buf_ptr->data_len);

        /* Update the bytes copied. */
        bytes_copied = buf_ptr->data_len;

        /* Loop through the chain if needed and copy all buffers. */
        while (buf_ptr->next_buffer != NU_NULL)
        {
            /* Move to the next buffer in the chain */
            buf_ptr = buf_ptr->next_buffer;

            /* Copy the data */
            memcpy((CHAR *)CommonMemPtr + (ULONG)buf_node_ptr->MNT_b_addr + bytes_copied,
                buf_ptr->mem_packet, buf_ptr->data_len);

            /* Update the bytes copied. */
            bytes_copied += buf_ptr->data_len;

        } /* end while there are buffers in the chain */

        
        buf_node_ptr -> MNT_b_len = (UINT16) pack_addr->mem_total_data_len;

        ringputInfo.MemPtr = NDISComMemStart;
        ringputInfo.RingPtr =
            ItoKval(MNT_Header_Ptr->MNT_hdr_cpuDesc[dest_id].MNT_cd_pInputRing,
                    PMNT_RING,
                    NDISComMemStart);

        ringputInfo.BuffNodeOffset = bufferOffset;


        status = DeviceIoControl (hDriver,
                         (DWORD) IOCTL_RINGPUT,
                         &ringputInfo,
                         sizeof(ringputInfo),
                         &ringputStatus,
                         sizeof(ringputStatus),
                         &cbReturned,
                         0);

        if ((!status) || (ringputStatus == 0))
        {
            NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);

            SNMP_ifOutErrors_Inc(device->dev_index);
            return -1;
        }

        /* Now set the event to let the destination node know that a packet is
           waiting to be processed.
        */
        /* First initialize the data required to generate an event. */
        geneventInfo.SelfID = MNT_ID;
        geneventInfo.MemPtr = MNT_Header_Ptr->MNT_hdr_cpuDesc;
        geneventInfo.MNTID = dest_id;

        /* Generate the event. */
        if(!DeviceIoControl (hDriver,
                             IOCTL_GENEVENT,
                             &geneventInfo,
                             sizeof(geneventInfo),
                             NULL,
                             0,
                             &cbReturned,
                             0) )
        {
              SNMP_ifOutErrors_Inc(device->dev_index);

            NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);
            return -1;
        }

        SNMP_ifOutOctets(device->dev_index, pack_addr->mem_total_data_len);

    }

    return (NU_SUCCESS);
} /* end NU_Xmit */

/******************************************************************************
* FUNCTION                                                                   
*                                                                            
*    VDRV_ISR                                                                
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    This is the entry point for the simulated interrupt.  It is actually    
*    called, however, from the NT receive thread NU_Recv_Packet.  This       
*    function retrieves a packet from this receive ring.  The received       
*    packet is placed onto the buffer_list where it can be processed by the  
*    upper layer software.  Once the packet is copied the receive HISR is    
*    activated.                                                              
*                                                                            
* AUTHOR
*
*   Glen Johnson
*
* INPUTS                                                                     
*                                                                            
*    none                                                                    
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    sshort   : Returns NU_SUCCESS if ok, else -1                            
*                                                                            
*                                                                            
******************************************************************************/
INT VDRV_ISR(INT vector)
{
    INT                 bufferOffset = 0;
    NET_BUFFER          *buf_ptr, *work_buf;
    IOCTL_OUT_RINGGET   ringgetInfo;
    IOCTL_OUT_RINGPUT   ringputInfo;
    IPKT                *pkt_ptr;
    DWORD               cbReturned;
    MNT_BUF_NODE        *buf_node_ptr;
#if (INCLUDE_SNMP == NU_TRUE)
    INT                 octets;
#endif
    INT                 pktlen;
    INT                 ringputStatus;
    DV_DEVICE_ENTRY     *device;
    INT32               bytes_left;
    UINT8               *work_ptr;

    /*  Find the device for this interrupt. */
    device = DEV_Get_Dev_For_Vector(vector);

    if (device == NU_NULL)
        return -1;

    /* Do a ringget from our receive list. */

    /* We will need to provide the pointer to the anchor and the offset to
       the freelist ring. */
    ringgetInfo.MemPtr = NDISComMemStart;
    ringgetInfo.RingPtr = ItoKval(
            MNT_Header_Ptr->MNT_hdr_cpuDesc[MNT_ID].MNT_cd_pInputRing,
            PMNT_RING,
            NDISComMemStart);

    /* Get the packet. */
    if (!DeviceIoControl (hDriver,
                     (DWORD) IOCTL_RINGGET,
                     &ringgetInfo,
                     sizeof(ringgetInfo),
                     &bufferOffset,
                     sizeof(bufferOffset),
                     &cbReturned,
                     0) )
    {
        SNMP_ifInErrors_Inc(device->dev_index);
        NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);
        return -1;
    }

    /* Was a packetretrieved? */
    if(bufferOffset == 0)
    {
        SNMP_ifInErrors_Inc(device->dev_index);
        return -1;
    }

    buf_node_ptr = (MNT_BUF_NODE *)((CHAR *)CommonMemPtr + bufferOffset);

    pkt_ptr = (IPKT *)((CHAR *)CommonMemPtr + (ULONG)buf_node_ptr->MNT_b_addr);

    /* Now determine how big the packet is.  The only way I know to do this is
       to extract the info from the packet itself.  Switch on the packet type. */
    switch (INTSWAP(pkt_ptr->d.type))
    {             /* what to do with it? */
        case EARP:
        case ERARP:
            pktlen = sizeof(ARP_LAYER) + sizeof(DLAYER);
            break;

        case EIP:

            /* For an IP packet the size is computed by adding together the IP
               data length, the IP header, and the size of the ethernet header.
            */
            pktlen = INTSWAP(pkt_ptr->i.ip_tlen) + sizeof(DLAYER);

⌨️ 快捷键说明

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