udpserv.c

来自「基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7」· C语言 代码 · 共 362 行

C
362
字号
/*************************************************************************/
/*                                                                       */
/*        Copyright (c) 1999 Accelerated Technology, Inc.		 */
/*                                                                       */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
/* subject matter of this material.  All manufacturing, reproduction,    */
/* use, and sales rights pertaining to this subject matter are governed  */
/* by the license agreement.  The recipient of this software implicitly  */
/* accepts the terms of the license.                                     */
/*                                                                       */
/*************************************************************************/

/*****************************************************************************/
/*                                                                           */
/* FILE NAME                                                                 */
/*                                                                           */
/*      UDPSERV.C                                                            */
/*                                                                           */
/*                                                                           */
/* DESCRIPTION                                                               */
/*                                                                           */
/*      This is a simple example of a UDP server.  It is an echo server,     */
/*      that is, any data received is echoed back to the client.  This       */
/*      program demonstrates the use of Nucleus NET over a PPP connection    */
/*                                                                           */
/*****************************************************************************/

#include "net\target.h"
#include "net\inc\externs.h"
#include "plus\nucleus.h"
#include "net\inc\socketd.h"    /* socket interface structures */
#include "net\inc\tcpdefs.h"
#include "ppp\inc\ppp.h"

/* This is the IP address that will be assigned to a client during PPP
   negotiaton. */
UINT8   client_ip_address[] =  {192, 168, 1, 21};

/* This is the IP address the server will use. */
UINT8   server_ip_address[] =  {192, 168, 1, 50};

/* Define Memory Pool Size */
#define DOS_MEMORY_SIZE 560000

/* Define Application data structures.  */
NU_MEMORY_POOL    System_Memory;
NU_TASK           udp_server_task_ptr;

/* Define prototypes for function references.  */
VOID    UDP_server_task(UNSIGNED argc, VOID *argv);
CHAR    *DEMO_Get_Modem_String(CHAR *response, CHAR *dev_name);
VOID    Error_Loop (INT error_num);


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      Application_Initialize                                           */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      Application_Initialize performs any tasks that must be done      */
/*      before the first task executes.                                  */
/*                                                                       */
/*************************************************************************/
VOID Application_Initialize (VOID *first_available_memory)
{
    VOID *pointer;
    STATUS status;

    /* Create a system memory pool that will be used to allocate task stacks,
       queue areas, etc.  */
    status = NU_Create_Memory_Pool(&System_Memory, "SYSMEM",
                        first_available_memory, DOS_MEMORY_SIZE, 50, NU_FIFO);

    if (status != NU_SUCCESS)
    {
        Error_Loop (1);
    }

    /* Create each task in the system.  */

    /* Create UDP_server_task.  */
    status = NU_Allocate_Memory (&System_Memory, &pointer, 5000, NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
    {
        Error_Loop (2);
    }

    status = NU_Create_Task (&udp_server_task_ptr, "UDPSERV", UDP_server_task, 0,
                             NU_NULL, pointer, 5000, 3, 0, NU_PREEMPT,
                             NU_START);
    if (status != NU_SUCCESS)
    {
        Error_Loop (3);
    }

}  /* end Application_Initialize */


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      udp_server_task                                                  */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      This is the task entry function for the task that will accept    */
/*      connection requests from clients.  Whenever a new connection is  */
/*      accepted the socket descriptor is pushed onto the Socket         */
/*      Descriptor queue.  The echo task will perform the actual         */
/*      communication with the client.                                   */
/*                                                                       */
/*************************************************************************/
VOID UDP_server_task(UNSIGNED argc, VOID *argv)
{
    int                 socketd;    /* the socket descriptor */
    struct addr_struct  servaddr;   /* holds the server address structure */
    struct addr_struct  cliaddr;    /* holds the client address structure */
    STATUS              status;
    int                 bytes_received;
    int                 bytes_sent;
    char                *buffer;
    INT16               clilen;
    char                null_ip[] = {0, 0, 0, 0};   /* Not used by PPP */
    char                mstring[80];
    NU_DEVICE          devices[1];
    DV_DEVICE_ENTRY     *dev_ptr;
    char                subnet_mask[] = {255, 255, 255, 0};

    /* Call the network initialization.  This must be done before any other net
       work services are called.  When PPP is being used only the first and
       second parameters are used.  The second parameter is used to pass in a
       pointer to the PPP initialization structure.
    */
    if(NU_Init_Net(&System_Memory) != NU_SUCCESS)
    {
        Error_Loop(4);
    }

    /* Setup the device structure for initialization of PPP. */
    memcpy (devices[0].dv_ip_addr, null_ip, 4);         /* Not use by PPP. */
    memcpy (devices[0].dv_subnet_mask, subnet_mask, 4); /* Not use by PPP. */
    devices[0].dv_name = "PPP_Link";
    devices[0].dv_init = HDLC_Initialize;
    devices[0].dv_flags = (DV_POINTTOPOINT | DV_NOARP);
    
    devices[0].dv_hw.uart.com_port         = UART1;
    devices[0].dv_hw.uart.baud_rate        = 115200;
    devices[0].dv_hw.uart.parity           = URT_PARITY_NONE;
    devices[0].dv_hw.uart.stop_bits        = STOP_BITS_1;
    devices[0].dv_hw.uart.data_bits        = DATA_BITS_8;

    NU_Init_Devices(devices, 1);

    /*  Allocate space for the buffer.  */
    status = NU_Allocate_Memory (&System_Memory, (VOID **) &buffer, 2000,
                                    NU_SUSPEND);

    if (status != NU_SUCCESS)
    {
        /*  Can't allocate memory, get out.  */
        Error_Loop(5);
    }
NU_Add_DNS_Server((UINT8 *)"\xc0\x1\x1\x1", DNS_ADD_TO_END);
NU_Add_DNS_Server((UINT8 *)"\xc0\x1\x1\x2", DNS_ADD_TO_END);
    
    /* Switch to terminal mode. */
    NU_Change_Communication_Mode(MDM_TERMINAL_COMMUNICATION, devices[0].dv_name);

    /* This while loop simply receives strings from the serial port and echos
       back OK in response.  This code is used to trick Windows 95 into thinking
       that it is communicating with modem, when in fact it is connected via
       null modem to an embedded device.
    */
    while(1)
    {
        /* Receive a MODEM command. */
        DEMO_Get_Modem_String(mstring, devices[0].dv_name);

        /* If the command received was a command to dial then Windows 95 now
           thinks that it has a modem connection to a remote HOST.  Get out of
           this loop because data exchanged beyond this point will be in the
           form of IP packets. */
        if (strncmp(mstring, "ATDT", 4) == 0)
            break;
        
        /* Respond with OK. */
        NU_Modem_Control_String("OK\n\r", devices[0].dv_name);
    }
    
    
/* Get a pointer to the device structure.  Only used in null modem demo */
    dev_ptr = DEV_Get_Dev_By_Name (devices[0].dv_name);




	/* Switch to PPP mode. */
    NU_Change_Communication_Mode(MDM_NETWORK_COMMUNICATION, devices[0].dv_name);
    
    
//PPP_Wait_For_Client(server_ip_address, "PPP_LINK");


    /* Change to SERVER mode */
    NCP_Change_IP_Mode (NCP_SERVER, dev_ptr);

    /* Set the IP address to assign to the client */
    NU_Set_PPP_Client_IP_Address (client_ip_address, devices[0].dv_name);
    
     ((LINK_LAYER*)dev_ptr->dev_ppp_layer)->lcp.state=OPENED;
     ((LINK_LAYER*)dev_ptr->dev_ppp_layer)->ipcp.state=OPENED;
     
     
    /* Act like a modem. */
    sprintf (mstring, "CONNECT %ld\n\r", devices[0].dv_hw.uart.baud_rate);
    NU_Modem_Control_String(mstring, devices[0].dv_name);
    

    /* Start the PPP negotiation. This call is only used for the null modem
       demos. It is normally handled by NU_Wait_For_PPP_Client. */
    status = PPP_Lower_Layer_Up(server_ip_address, dev_ptr);

    if (status == NU_SUCCESS)
    {
        /**** These two functions calls are only needed because ****
         **** this demo is running over null modem. If a real   ****
         **** modem was used this would be taken care of by the ****
         **** PPP service NU_Wait_For_PPP_Client.               ****/

        /* Get the subnet mask for this type of address. */
        IP_Get_Net_Mask (server_ip_address, (UINT8 *)subnet_mask);

        /* Set our new address */
        DEV_Attach_IP_To_Device ("PPP_Link", (UINT8 *)server_ip_address, (UINT8 *)subnet_mask);

        /**** End of null modem specific code.                 ****/

        /* open a connection via the socket interface */
        if ((socketd = NU_Socket(NU_FAMILY_IP, NU_TYPE_DGRAM, 0))>=0)
        {
            
            /* Fill in a structure with the server address. */
            servaddr.family    = NU_FAMILY_IP;
            servaddr.port      = 7;
            servaddr.name = "ati";
            *((UINT32 *)servaddr.id.is_ip_addrs) = IP_ADDR_ANY;

            /* Initialize the client address structure. */
            cliaddr.family    = NU_FAMILY_IP;
            cliaddr.port      = 0;
            cliaddr.id.is_ip_addrs[0]  = (unsigned char) 0;
            cliaddr.id.is_ip_addrs[1]  = (unsigned char) 0;
            cliaddr.id.is_ip_addrs[2]  = (unsigned char) 0;
            cliaddr.id.is_ip_addrs[3]  = (unsigned char) 0;
            cliaddr.name = "";

            /*  Bind our address to the socket.  */
            if (NU_Bind(socketd, &servaddr, 0) < 0)
            {
                Error_Loop(6);
            }

            /*  Prime the loop. */
            buffer[0] = (char) 0;

            while(buffer[0] != 'q')
            {
                /*  Get a string from the client.  */
                 bytes_received = NU_Recv_From(socketd, buffer, 1000, 0,
                                          &cliaddr, &clilen);

                /*  If we got back less than zero there is a bad error. */
                if (bytes_received < 0)
                {
                    buffer[0] = 'q';
                }
                else
                {
                    /*  Send the string back to the client.  */
                    bytes_sent = NU_Send_To(socketd, buffer, bytes_received, 0,
                                    &cliaddr, clilen);

                    /*  If the return value is less than zero an error ocurred. */
                    if (bytes_sent < 0)
                    {
                        buffer[0] = 'q';
                    }
                }
            }
            /* close the connection */
            NU_Close_Socket(socketd);

        } /* end successful NU_Socket */

    } /* end successful connection */

}

/******************************************************************************/
/*                                                                            */
/* FUNCTION                                                                   */
/*                                                                            */
/*      DEMO_Get_Modem_String                                                 */
/*                                                                            */
/* DESCRIPTION                                                                */
/*                                                                            */
/*     This function is used to receive "modem" commands from Windows 95.     */
/*                                                                            */
/******************************************************************************/
CHAR *DEMO_Get_Modem_String(CHAR *response, CHAR *dev_name)
{
    CHAR            c;
    CHAR            *write_ptr;

    write_ptr = response;
    *write_ptr = NU_NULL;

    while (1)
    {
		/* get a character from the port if one's there */
        if (NU_Terminal_Data_Ready(dev_name))
        {
            NU_Get_Terminal_Char(&c, dev_name);

            switch (c)
            {
                case 0xD:                /* CR - return the result string */
                    if (*response)
                        return response;
					continue;
				default:
                    if (c != 10)
                    {      /* add char to end of string */
                        *write_ptr++ = (char)c;
                        *write_ptr = NU_NULL;
						/* ignore RINGING and the dial string */
					}
			}
		}
        else
            NU_Sleep(5);

	}

} /* DEMO_Get_Modem_String */

VOID Error_Loop (INT error_num)
{
    INT x, y;

    while (NU_TRUE)
    {
        x++;
        y++;
    }
}

⌨️ 快捷键说明

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