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