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 + -
显示快捷键?