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

📄 nnetdrv.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
*    sshort  : not used in this driver.                                      
*    UINT32   : contains a pointer to the local hostname.                    
*    UINT32   : not used in this driver.                                     
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    sshort  : NU_SUCCESS if everything goes as planned, a negative number   
*              otherwise.                                                    
*                                                                            
******************************************************************************/
STATUS VDRV_Open (UINT8 *ether_addr, DV_DEVICE_ENTRY *device)
{
    CHAR                    *aInterfaceType[] =  {"Internal",
                                                  "Isa",
                                                  "Eisa",
                                                  "MicroChannel",
                                                  "TurboChannel" };
    HKEY                    hKey;
    UINT                    stat;
    DWORD                   valueDWORD, dataSize = 4;
    PHYSICAL_MEMORY_INFO    pmi;
    DWORD                   cbReturned;
    VOID                    *pointer;
    INT                     i;

    SNMP_ifDescr(device->dev_index, "VNET Driver: Software revision 1.1");
    SNMP_ifType(device->dev_index, 6);
    SNMP_ifMtu(device->dev_index, device->dev_mtu);
    SNMP_ifSpeed(device->dev_index, 10000000); /* 10 Mbps */

    /* First retrieve the virtual address of the common memory buffer.
     * Later this address will be mapped into our own address space. */
    stat = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                        "SYSTEM\\CURRENTCONTROLSET\\SERVICES\\NDISMNT\\COMMEMCONFIG",
                        0, KEY_ALL_ACCESS, &hKey);

    /* Read the starting address of the commomn memory area. */
    dataSize = sizeof(pmi.CommonMemAddr);
    stat = RegQueryValueEx(hKey, "COMMEMSTART", NULL, &valueDWORD,
                           (UINT8 *)&pmi.CommonMemAddr,
                           &dataSize);

    /* Read the size of the commomn memory area. */
    dataSize = sizeof(pmi.Length);
    stat = RegQueryValueEx(hKey, "COMMEMSIZE", NULL, &valueDWORD,
                           (UINT8 *)&pmi.Length,
                           &dataSize);


    pmi.InterfaceType       = (INTERFACE_TYPE) 0;  // Internal
    pmi.BusNumber           = (ULONG)          0;  // Standard 80x86
    pmi.AddressSpace        = (LONG)           0;  // Memory

    NDISComMemStart = pmi.CommonMemAddr;

    /* Get a handle to the virtual Nucleus NET ethernet driver. */
    hDriver = CreateFile ("\\\\.\\VNET", GENERIC_READ | GENERIC_WRITE,
                                 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
                                 NULL);

    if (hDriver == INVALID_HANDLE_VALUE) {
        return -1;
    }

    /* Try to map the common memory area into the local address space. */
    if (!DeviceIoControl (hDriver,
                         (DWORD) IOCTL_MAP_COMMON_MEMORY_AREA,
                         &pmi,
                         sizeof(PHYSICAL_MEMORY_INFO),
                         &CommonMemPtr,
                         sizeof(PVOID),
                         &cbReturned,
                         0
                         ) )
    {
        return -1;
    }
   
    /* So far so good.  Now check to see if NDIS has initialized the common
       memory area.  Note that the NDIS driver must execute first.  If NDIS
       has not executed then exit.
    */
    if (CommonMemPtr->MNT_an_ready != MNT_READY)
    {
        return -1;
    }
    

    /* The MNT anchor was ready.  Now verify that the MNT header was also
       initialized by NDIS.  Note that the MNT_an_pHdr field in the anchor
       structure is not really a pointer to the MNT_HEADER, but an offset from
       the beginning of the common memory area to the MNT_HEADER.
    */
    MNT_Header_Ptr = ItoKval(CommonMemPtr->MNT_an_pHdr,
                             PMNT_HEADER,
                             CommonMemPtr);

    if (MNT_Header_Ptr->MNT_hdr_ready != MNT_READY)
    {
        return -1;
    }
    
    /* Copy the number of possible MNT processes. */
    if((VNET_Ncpu = MNT_Header_Ptr->MNT_hdr_ncpu) <= 0)
    {
        return -1;
    }

    /* Lookup the ID used by this virtual node. */
    if (VDRV_Lookup_ID(device->dev_net_if_name) != NU_SUCCESS)
        return -1;

    /* Find an unused cpu desc in the common memory. */
    if (VDRV_Init_MNT_DESC(MNT_Header_Ptr, MNT_ID) != NU_SUCCESS)
    {
        return -1;
    }

    if(VDRV_Lookup_Default_Gateway(device) != NU_SUCCESS)
        return -1;

    if(VDRV_Lookup_Base_Ether() != NU_SUCCESS)
        return -1;

    /* Initialize our ethernet address. The first 5 octets of the ethernet
       address are all 0. */
    for(i=0; i<5; i++)
        Ether_Addr[i] = 0;

    /* The last octet of the ethernet address is the our ID + the base ether. */
    Ether_Addr[5] = (CHAR)((CHAR)MNT_ID + VNET_BaseEtherAddr);

    NU_Get_Address(ether_addr, 0, 0);

    /* Initialize the Physical address in the MIB. */
    SNMP_ifPhysAddress(device->dev_index, ether_addr);

    /* Initialize the vector table entry for the virtual network ISR.  For other
       simulated interrupts (timer, uart) this is done in INT_Initialize.  I
       chose to do it here so that MNT would not need to be modified to
       accomodate the virtual network. */
    INT_Vector_Table[VNETPRIO] = VDRV_ISR;

    /* Initialize the device vector field.  It will be used later in the 
       receive ISR.  The vector is used to detect which device a packet is 
       received on. */
    device->dev_vect = VNETPRIO;

    /* Register the recive ISR with the OS. */
    if (NU_Register_LISR(VNETPRIO, VDRV_ISR, &oldlisr) != NU_SUCCESS)
        return (-1);

    /* create the HISR for handleing the simulated interrupt. */
    if (NU_Allocate_Memory (&System_Memory,
                            &pointer,
                            2000,
                            NU_NO_SUSPEND) != NU_SUCCESS)
    {
        NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
    }

    if (NU_Create_HISR (&Recv_HISR, "ETHRHISR",
                                VDRV_Recv_HISR,
                                0, pointer, 2000)!= NU_SUCCESS)
    {
        NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
    }

    /* Create the NT thread that will retrieve arriving packets.  The thread's
       entry point is NU_Recv_Packet.
    */
    Recv_Thread_ID.thread_hdl = CreateThread (NULL, 0,
                                (LPTHREAD_START_ROUTINE) NU_Recv_Packet,
                                NULL, 0, &Recv_Thread_ID.thread_id);

    if (Recv_Thread_ID.thread_hdl == NULL) {
        return(-1);
    }


    /* Allocate memory to for the input and output buffers to the
       DeviceIoControl call.  These buffers are only used in VDRV_Xmit_Packet.
       Rather than allocate the memory each time VDRV_Xmit_Packet is called I
       chose to allocate them once here and reuse them each time VDRV_Xmit_Packet
       is called.  The memory is deallocated in NU_Close_Driver.
    */
    if (NU_Allocate_Memory(&System_Memory, &mRinggetInput,
                           sizeof(ULONG) * (1 + VNET_Ncpu),
                           NU_NO_SUSPEND) != NU_SUCCESS)
        return (-1);

    if (NU_Allocate_Memory(&System_Memory, &mRingputInfo,
                           sizeof(ULONG) * (2 + (2 * VNET_Ncpu)),
                           NU_NO_SUSPEND) != NU_SUCCESS)
        return (-1);

    if (NU_Allocate_Memory(&System_Memory, &mGeneventOut,
                           sizeof(ULONG) * (3 + VNET_Ncpu),
                           NU_NO_SUSPEND) != NU_SUCCESS)
        return (-1);

    /* Set the current status to operational. */
    SNMP_ifAdminStatus(device->dev_index, 1);
    SNMP_ifOperStatus(device->dev_index, 1);
    

    return NU_SUCCESS;

}   /* VDRV_Open */

/******************************************************************************
* FUNCTION                                                                   
*                                                                            
*    NU_Close_Driver                                                         
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    This closes the driver.  It reverses many of the actions performed by   
*    VDRV_Open.  After execution of this function packets can no longer be   
*    transmitted or recieved.                                                
*                                                                            
*AUTHOR
*
*   Glen Johnson
*
* INPUTS                                                                     
*                                                                            
*    none                                                                    
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    sshort  : NU_SUCCESS if everything goes as planned, a negative number   
*              otherwise.                                                    
*                                                                            
******************************************************************************/
STATUS NU_Close_Driver(VOID)
{
   
    NU_Deallocate_Memory(mRinggetInput);
    NU_Deallocate_Memory(mRingputInfo);
    NU_Deallocate_Memory(mGeneventOut);

    VDRV_Driver_Closing = 1;

    if(CloseHandle(hDriver) != TRUE)
        return(-1);
    else
        return (NU_SUCCESS);

}/* end NU_Close_Driver */

/******************************************************************************
* FUNCTION                                                                   
*                                                                            
*    NU_Recv_Packet                                                          
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    This function is the entry point for an NT thread.  Upon executing this 
*    thread will check to see if there are any packets in the receive ring.  
*    If not it waits for an NT event to be sent indicating that an packet has
*    arrived.  The event is our simulated interrupt.  When the event oocurs  
*    The ISR will be called to pull tha packet off of the network.  The      
*    process is repeated until the driver closes.                            
*                                                                            
* AUTHOR
*
*   Glen Johnson
*
* INPUTS                                                                     
*                                                                            
*    No inputs to this function.                                             
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    none                                                                    
*                                                                            
******************************************************************************/
VOID NU_Recv_Packet (LPDWORD unusedParam)
{
    HANDLE              hEvt;
    BOOL                status;
    DWORD               dwData;
    OVERLAPPED          ovl;
    IOCTL_OUT_GETEVENT  geteventInfo;
    INT                 oldlevel;
        
    /* Create the event that will be used to signal the arrival of a packet. */
    hEvt = CreateEvent (NULL, TRUE, FALSE, NULL);
    if (!hEvt) {
        demo_exit(0);
    }

    ovl.hEvent = hEvt;

    /* Go ahead and raise the interrupt level, just in case there may be
       something waiting when we get here.  This should not be the case.
    */
    /* If there is already an interrupt service routine executing that is a
       higher priority than that of the virtual network then suspend.  This
       thread will be restarted in that "ISR" is complete.
    */

⌨️ 快捷键说明

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