]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c
6cd24037fc95fc1f06fedf06293fcd7645f90029
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator / UDPCommandServer.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 #pragma comment( lib, "ws2_32.lib" )\r
29 \r
30 /* Win32 includes. */\r
31 #include <WinSock2.h>\r
32 #include <stdio.h>\r
33 \r
34 /* FreeRTOS includes. */\r
35 #include "FreeRTOS.h"\r
36 #include "task.h"\r
37 \r
38 /* FreeRTOS+CLI includes. */\r
39 #include "FreeRTOS_CLI.h"\r
40 \r
41 /* Dimensions the buffer into which input characters are placed. */\r
42 #define cmdMAX_INPUT_SIZE       60\r
43 \r
44 /* Dimensions the buffer into which string outputs can be placed. */\r
45 #define cmdMAX_OUTPUT_SIZE      1024\r
46 \r
47 /* Dimensions the buffer passed to the recvfrom() call. */\r
48 #define cmdSOCKET_INPUT_BUFFER_SIZE 60\r
49 \r
50 /*\r
51  * Open and configure the UDP socket.\r
52  */\r
53 static SOCKET prvOpenUDPSocket( void );\r
54 \r
55 /*-----------------------------------------------------------*/\r
56 \r
57 /*\r
58  * Task that provides the input and output for the FreeRTOS+CLI command\r
59  * interpreter.  In this case a UDP port is used.  See the URL in the comments\r
60  * within main.c for the location of the online documentation.\r
61  */\r
62 void vUDPCommandInterpreterTask( void *pvParameters )\r
63 {\r
64 long lBytes, lByte;\r
65 signed char cInChar, cInputIndex = 0;\r
66 static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];\r
67 BaseType_t xMoreDataToFollow;\r
68 volatile int iErrorCode = 0;\r
69 struct sockaddr_in xClient;\r
70 int xClientAddressLength = sizeof( struct sockaddr_in );\r
71 SOCKET xSocket;\r
72 \r
73         /* Just to prevent compiler warnings. */\r
74         ( void ) pvParameters;\r
75 \r
76         /* Attempt to open the socket. */\r
77         xSocket = prvOpenUDPSocket();\r
78 \r
79         if( xSocket != INVALID_SOCKET )\r
80         {\r
81                 for( ;; )\r
82                 {\r
83                         /* Wait for incoming data on the opened socket. */\r
84                         lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength );\r
85 \r
86                         if( lBytes == SOCKET_ERROR )\r
87                         {\r
88                                 /* Something went wrong, but it is not handled by this simple\r
89                                 example. */\r
90                                 iErrorCode = WSAGetLastError();\r
91                         }\r
92                         else\r
93                         {\r
94                                 /* Process each received byte in turn. */\r
95                                 lByte = 0;\r
96                                 while( lByte < lBytes )\r
97                                 {\r
98                                         /* The next character in the input buffer. */\r
99                                         cInChar = cLocalBuffer[ lByte ];\r
100                                         lByte++;\r
101 \r
102                                         /* Newline characters are taken as the end of the command\r
103                                         string. */\r
104                                         if( cInChar == '\n' )\r
105                                         {\r
106                                                 /* Process the input string received prior to the\r
107                                                 newline. */\r
108                                                 do\r
109                                                 {\r
110                                                         /* Pass the string to FreeRTOS+CLI. */\r
111                                                         xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );\r
112 \r
113                                                         /* Send the output generated by the command's\r
114                                                         implementation. */\r
115                                                         sendto( xSocket, cOutputString,  strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
116 \r
117                                                 } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */\r
118 \r
119                                                 /* All the strings generated by the command processing\r
120                                                 have been sent.  Clear the input string ready to receive\r
121                                                 the next command. */\r
122                                                 cInputIndex = 0;\r
123                                                 memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );\r
124 \r
125                                                 /* Transmit a spacer, just to make the command console\r
126                                                 easier to read. */\r
127                                                 sendto( xSocket, "\r\n",  strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
128                                         }\r
129                                         else\r
130                                         {\r
131                                                 if( cInChar == '\r' )\r
132                                                 {\r
133                                                         /* Ignore the character.  Newlines are used to\r
134                                                         detect the end of the input string. */\r
135                                                 }\r
136                                                 else if( cInChar == '\b' )\r
137                                                 {\r
138                                                         /* Backspace was pressed.  Erase the last character\r
139                                                         in the string - if any. */\r
140                                                         if( cInputIndex > 0 )\r
141                                                         {\r
142                                                                 cInputIndex--;\r
143                                                                 cInputString[ cInputIndex ] = '\0';\r
144                                                         }\r
145                                                 }\r
146                                                 else\r
147                                                 {\r
148                                                         /* A character was entered.  Add it to the string\r
149                                                         entered so far.  When a \n is entered the complete\r
150                                                         string will be passed to the command interpreter. */\r
151                                                         if( cInputIndex < cmdMAX_INPUT_SIZE )\r
152                                                         {\r
153                                                                 cInputString[ cInputIndex ] = cInChar;\r
154                                                                 cInputIndex++;\r
155                                                         }\r
156                                                 }\r
157                                         }\r
158                                 }\r
159                         }\r
160                 }\r
161         }\r
162         else\r
163         {\r
164                 /* The socket could not be opened. */\r
165                 vTaskDelete( NULL );\r
166         }\r
167 }\r
168 /*-----------------------------------------------------------*/\r
169 \r
170 static SOCKET prvOpenUDPSocket( void )\r
171 {\r
172 WSADATA xWSAData;\r
173 WORD wVersionRequested;\r
174 struct sockaddr_in xServer;\r
175 SOCKET xSocket = INVALID_SOCKET;\r
176 \r
177         wVersionRequested = MAKEWORD( 2, 2 );\r
178 \r
179         /* Prepare to use WinSock. */\r
180         if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )\r
181         {\r
182                 fprintf( stderr, "Could not open Windows connection.\n" );\r
183         }\r
184         else\r
185         {\r
186                 xSocket = socket( AF_INET, SOCK_DGRAM, 0 );\r
187                 if( xSocket == INVALID_SOCKET)\r
188                 {\r
189                         fprintf( stderr, "Could not create socket.\n" );\r
190                         WSACleanup();\r
191                 }\r
192                 else\r
193                 {\r
194                         /* Zero out the server structure. */\r
195                         memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) );\r
196 \r
197                         /* Set family and port. */\r
198                         xServer.sin_family = AF_INET;\r
199                         xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER );\r
200 \r
201                         /* Assign the loopback address */\r
202                         xServer.sin_addr.S_un.S_un_b.s_b1 = 127;\r
203                         xServer.sin_addr.S_un.S_un_b.s_b2 = 0;\r
204                         xServer.sin_addr.S_un.S_un_b.s_b3 = 0;\r
205                         xServer.sin_addr.S_un.S_un_b.s_b4 = 1;\r
206 \r
207                         /* Bind the address to the socket. */\r
208                         if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 )\r
209                         {\r
210                                 fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER );\r
211                                 closesocket( xSocket );\r
212                                 xSocket = INVALID_SOCKET;\r
213                                 WSACleanup();\r
214                         }\r
215                 }\r
216         }\r
217 \r
218         return xSocket;\r
219 }\r
220 \r
221 \r