1 /* This is a small demo of the high-performance NetX TCP/IP stack.  This demo concentrates
2    on UDP packet sending and receiving - with ARP - using a simulated Ethernet driver.  */
3 /* This demo works for IPv4 only */
4 
5 #include   "tx_api.h"
6 #include   "nx_api.h"
7 #ifndef NX_DISABLE_IPV4
8 #include   "nxd_bsd.h"
9 #include   <string.h>
10 #include   <stdlib.h>
11 
12 #define     DEMO_STACK_SIZE         2048
13 #define     SERVER_PORT             721
14 
15 /* Message sent to the server */
16 #define CLIENT_MESSAGE "Client BSD UDP Socket testing\n"
17 
18 
19 /* Define the ThreadX and NetX object control blocks...  */
20 
21 TX_THREAD               thread_server;
22 TX_THREAD               thread_client;
23 NX_PACKET_POOL          bsd_pool;
24 NX_IP                   bsd_ip;
25 
26 
27 /* Define the counters used in the demo application...  */
28 
29 ULONG                  thread_0_counter;
30 ULONG                  thread_2_counter;
31 ULONG                  error_counter;
32 
33 /* Define thread prototypes.  */
34 
35 VOID    thread_server_entry(ULONG thread_input);
36 VOID    thread_client_entry(ULONG thread_input);
37 VOID    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
38 
39 
40 /* Define main entry point.  */
41 
main()42 int main()
43 {
44 
45     /* Enter the ThreadX kernel.  */
46     tx_kernel_enter();
47 }
48 
49 /* Define what the initial system looks like.  */
50 
tx_application_define(void * first_unused_memory)51 void    tx_application_define(void *first_unused_memory)
52 {
53 
54 CHAR    *pointer;
55 UINT    status;
56 
57 
58     /* Setup the working pointer.  */
59     pointer =  (CHAR *) first_unused_memory;
60 
61     /* Create a thread for the Server  */
62     tx_thread_create(&thread_server, "Server", thread_server_entry, 0,
63             pointer, DEMO_STACK_SIZE,
64             8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
65 
66     pointer =  pointer + DEMO_STACK_SIZE;
67 
68     /* Create a thread for client.  */
69     tx_thread_create(&thread_client, "Client", thread_client_entry, 0,
70             pointer, DEMO_STACK_SIZE,
71             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
72 
73     pointer =  pointer + DEMO_STACK_SIZE;
74 
75     /* Initialize the NetX system.  */
76     nx_system_initialize();
77 
78     /* Create a BSD packet pool.  */
79     status =  nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 128, pointer, 16384);
80 
81     pointer = pointer + 16384;
82     if (status)
83     {
84         error_counter++;
85         printf("Error in creating BSD packet pool\n!");
86     }
87 
88     /* Create an IP instance for BSD.  */
89     status += nx_ip_create(&bsd_ip, "NetX IP Instance 2", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL,
90                            &bsd_pool, _nx_ram_network_driver,
91                            pointer, DEMO_STACK_SIZE, 1);
92 
93     pointer =  pointer + DEMO_STACK_SIZE;
94 
95     /* Check for any errors */
96     if (status)
97         error_counter++;
98 
99     if (status)
100         printf("Error creating BSD IP instance\n!");
101 
102     /* Enable ARP and supply ARP cache memory for BSD IP Instance */
103     status +=  nx_arp_enable(&bsd_ip, (void *) pointer, 1024);
104 
105     pointer = pointer + 1024;
106 
107     /* Check ARP enable status.  */
108     if (status)
109         error_counter++;
110 
111     if (status)
112         printf("Error in Enable ARP and supply ARP cache memory to BSD IP instance\n");
113 
114     /* Enable UDP traffic.  */
115     status =  nx_udp_enable(&bsd_ip);
116 
117     /* Check for UDP enable errors.  */
118     if (status)
119         error_counter++;
120 
121     /* Now initialize BSD Socket Wrapper */
122     status = (UINT)bsd_initialize (&bsd_ip, &bsd_pool, pointer, 2048, 2);
123 
124     if (status)
125         error_counter++;
126 
127 }
128 
129 
thread_server_entry(ULONG thread_input)130 void    thread_server_entry(ULONG thread_input)
131 {
132 
133     /* Start the Server */
134 INT          status,addrlen1;
135 INT          sock_udp_2;
136 struct       sockaddr_in echoServAddr;               /* Echo server address */
137 struct       sockaddr_in fromAddr;                   /* Cleint address */
138 CHAR         buffer[64];
139 
140     NX_PARAMETER_NOT_USED(thread_input);
141 
142     /* Create a BSD UDP Server Socket */
143     sock_udp_2 = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
144 
145     /* Check for any errors */
146     if (sock_udp_2 == -1)
147     {
148         printf("Error: BSD UDP Servert socket create\n");
149         return;
150     }
151 
152      /* Fill ths socket with Server side information */
153      memset(&echoServAddr, 0, sizeof(echoServAddr));
154      echoServAddr.sin_family = PF_INET;
155      echoServAddr.sin_addr.s_addr = htonl(IP_ADDRESS(1,2,3,4));
156      echoServAddr.sin_port = htons(SERVER_PORT);
157 
158      /* Bind the UDP socket to the IP port.  */
159      status = bind (sock_udp_2, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr));
160      if (status < 0)
161      {
162          printf("Error: BSD UDP Server Socket Bind\n");
163          return;
164      }
165 
166      while(1)
167      {
168 
169          addrlen1 = sizeof(struct sockaddr_in);
170 
171          /* Receive a UDP packet from a client. */
172          status = recvfrom(sock_udp_2,(VOID *)buffer, 64, 0,(struct sockaddr *) &fromAddr, &addrlen1);
173 
174              /* Check for any errors */
175          if (status == ERROR)
176             printf("Error: BSD Server Socket receive\n");
177          else
178          {
179 
180              /* Print client information */
181              printf("Server received data from Client at IP address 0x%x at port %lu\n",
182                     (UINT)fromAddr.sin_addr.s_addr, (ULONG)fromAddr.sin_port);
183 
184             /* Print the packet received from the client */
185             printf("Server received from Client: %s\n", buffer);
186 
187             /* Now echo the recieved data string to the same client */
188             status = sendto(sock_udp_2, buffer, (INT)(status + 1), 0, (struct sockaddr *) &fromAddr, sizeof(fromAddr));
189 
190             /* Check for any errors */
191             if (status == ERROR)
192                 printf("Error:BSD Server Socket echo\n");
193          }
194 
195          tx_thread_sleep(NX_IP_PERIODIC_RATE);
196 
197         /* All done , loop back to recieve next packet */
198     }
199 }
200 
201 /* Define the Client thread.  */
thread_client_entry(ULONG thread_input)202 void    thread_client_entry(ULONG thread_input)
203 {
204 
205 INT          status,sock_udp_1;
206 INT          addrlen;
207 struct       sockaddr_in destAddr;                       /* Destination address */
208 struct       sockaddr_in ClientAddr;                     /* Client address */
209 struct       sockaddr_in fromAddr;                       /* Cleint address */
210 CHAR         echomsg[64];                                /* Message echoed by the server */
211 
212     NX_PARAMETER_NOT_USED(thread_input);
213 
214     /* Allow Server side to set up */
215     tx_thread_sleep(10);
216     thread_2_counter =0;
217 
218     while(1)
219     {
220 
221          /* Create a BSD UDP Client Socket */
222          sock_udp_1 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP);
223 
224          /* Check for any errors */
225          if (sock_udp_1 == ERROR)
226          {
227              printf("Error: BSD UDP Client socket create\n");
228              return;
229          }
230 
231          /* Set up client side */
232          memset(&ClientAddr, 0, sizeof(ClientAddr));
233          ClientAddr.sin_family = PF_INET;
234          ClientAddr.sin_addr.s_addr = htonl(IP_ADDRESS(1,2,3,4));
235 
236          /* Assign a known Server port */
237          memset(&destAddr, 0, sizeof(destAddr));
238          destAddr.sin_addr.s_addr = htonl(IP_ADDRESS(1,2,3,4));
239          destAddr.sin_port = htons(SERVER_PORT);
240          destAddr.sin_family = PF_INET;
241 
242          /* Client socket is ready now start sending packets */
243          printf("BSD Client Socket (%lu) sending test message: %s\n", (ULONG)sock_udp_1, CLIENT_MESSAGE);
244 
245          status = sendto(sock_udp_1, CLIENT_MESSAGE, (INT)(sizeof(CLIENT_MESSAGE)), 0,
246                          (struct sockaddr *) &destAddr, sizeof(destAddr));
247 
248          /* Check for any errors */
249          if (status == ERROR)
250          {
251 
252              printf("Error: BSD Client Socket send\n");
253          }
254          else
255          {
256 
257              addrlen = sizeof(struct sockaddr_in);
258 
259              /* Try to receive an echo from the server. */
260              status = recvfrom(sock_udp_1,(VOID *)echomsg,64, 0, (struct sockaddr *) &fromAddr, &addrlen);
261 
262              /* * Check for any errors */
263              if (status == ERROR)
264              {
265 
266                  printf("Error: BSD Client Socket echo receive\n");
267              }
268              else
269              {
270 
271                  /* Print Server detials */
272                  printf("Client contacted Server at IP address 0x%x and port %lu\n",
273                         (UINT)fromAddr.sin_addr.s_addr, (ULONG)fromAddr.sin_port);
274 
275                  /* Print the received echo string from the server */
276                  printf("Client (%lu) received echo string: %s\n", (ULONG)sock_udp_1, echomsg);
277              }
278          }
279 
280          /* Done with this client socket */
281          status = soc_close(sock_udp_1);
282 
283          /* Check for any errors */
284          if (status == ERROR)
285          {
286              printf("Error: BSD Client Socket close\n");
287          }
288 
289         /* Increment client transaction counter.  */
290         thread_2_counter++;
291 
292         tx_thread_sleep(NX_IP_PERIODIC_RATE);
293     }
294 }
295 #endif /* NX_DISABLE_IPV4 */
296