1 /*
2 * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * http://aws.amazon.com/freertos
25 * http://www.FreeRTOS.org
26 */
27
28 /**
29 * @file main.c
30 * @brief Implements the main function.
31 */
32
33 /* FreeRTOS include. */
34 #include <FreeRTOS.h>
35 #include "task.h"
36
37 /* System application includes. */
38 #include "FreeRTOS_IP.h"
39 #include "FreeRTOS_Sockets.h"
40 #include "FreeRTOS_DHCP.h"
41
42 #include <string.h>
43 #include <stdarg.h>
44 #include <time.h>
45
46 #define mainHOST_NAME "Build Combination"
47 #define mainDEVICE_NICK_NAME "Build_Combination"
48
49 #if defined( _MSC_VER ) && ( _MSC_VER <= 1600 )
50 #define local_stricmp _stricmp
51 #else
52 #define local_stricmp strcasecmp
53 #endif
54 /*-----------------------------------------------------------*/
55
56 /* Notes if the trace is running or not. */
57 static BaseType_t xTraceRunning = pdTRUE;
58
59 /* Default MAC address configuration. The demo creates a virtual network
60 * connection that uses this MAC address by accessing the raw Ethernet data
61 * to and from a real network connection on the host PC. See the
62 * configNETWORK_INTERFACE_TO_USE definition for information on how to configure
63 * the real network connection to use. */
64 const uint8_t ucMACAddress[ 6 ] =
65 {
66 configMAC_ADDR0,
67 configMAC_ADDR1,
68 configMAC_ADDR2,
69 configMAC_ADDR3,
70 configMAC_ADDR4,
71 configMAC_ADDR5
72 };
73
74 /* The default IP and MAC address used by the code. It is used as a place holder.
75 */
76 static const uint8_t ucIPAddress[ 4 ] =
77 {
78 configIP_ADDR0,
79 configIP_ADDR1,
80 configIP_ADDR2,
81 configIP_ADDR3
82 };
83 static const uint8_t ucNetMask[ 4 ] =
84 {
85 configNET_MASK0,
86 configNET_MASK1,
87 configNET_MASK2,
88 configNET_MASK3
89 };
90 static const uint8_t ucGatewayAddress[ 4 ] =
91 {
92 configGATEWAY_ADDR0,
93 configGATEWAY_ADDR1,
94 configGATEWAY_ADDR2,
95 configGATEWAY_ADDR3
96 };
97 static const uint8_t ucDNSServerAddress[ 4 ] =
98 {
99 configDNS_SERVER_ADDR0,
100 configDNS_SERVER_ADDR1,
101 configDNS_SERVER_ADDR2,
102 configDNS_SERVER_ADDR3
103 };
104
105 /* Use by the pseudo random number generator. */
106 static UBaseType_t ulNextRand;
107
108 /*-----------------------------------------------------------*/
main(void)109 int main( void )
110 {
111 /* Initialize the network interface.
112 *
113 ***NOTE*** Tasks that use the network are created in the network event hook
114 * when the network is connected and ready for use (see the definition of
115 * vApplicationIPNetworkEventHook() below). The address values passed in here
116 * are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
117 * but a DHCP server cannot be contacted. */
118 #if ( ipconfigIPv4_BACKWARD_COMPATIBLE != 0 ) && ( ipconfigUSE_IPv4 != 0 )
119 FreeRTOS_printf( ( "FreeRTOS_IPInit\n" ) );
120 FreeRTOS_IPInit(
121 ucIPAddress,
122 ucNetMask,
123 ucGatewayAddress,
124 ucDNSServerAddress,
125 ucMACAddress );
126 #else
127 FreeRTOS_printf( ( "FreeRTOS_IPInit_Multi\n" ) );
128 FreeRTOS_IPInit_Multi();
129 #endif
130
131 vTaskStartScheduler();
132
133 return 0;
134 }
135 /*-----------------------------------------------------------*/
136 /* *INDENT-OFF* */
137 #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 )
vApplicationIPNetworkEventHook(eIPCallbackEvent_t eNetworkEvent)138 void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
139 #else
140 void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent,
141 struct xNetworkEndPoint * pxEndPoint )
142 #endif
143 /* *INDENT-ON* */
144 {
145 static BaseType_t xTasksAlreadyCreated = pdFALSE;
146
147 /* If the network has just come up...*/
148 if( ( eNetworkEvent == eNetworkUp ) && ( xTasksAlreadyCreated == pdFALSE ) )
149 {
150 /* Do nothing. Just a stub. */
151
152 xTasksAlreadyCreated = pdTRUE;
153 }
154 }
155
156 /*-----------------------------------------------------------*/
157
158 #if ( ( ipconfigUSE_LLMNR != 0 ) || \
159 ( ipconfigUSE_NBNS != 0 ) || \
160 ( ipconfigDHCP_REGISTER_HOSTNAME == 1 ) )
161
pcApplicationHostnameHook(void)162 const char * pcApplicationHostnameHook( void )
163 {
164 /* This function will be called during the DHCP: the machine will be registered
165 * with an IP address plus this name. */
166 return mainHOST_NAME;
167 }
168
169 #endif /* if ( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 ) ) */
170 /*-----------------------------------------------------------*/
171
172 #if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
173
xApplicationDNSQueryHook(const char * pcName)174 BaseType_t xApplicationDNSQueryHook( const char * pcName )
175 {
176 BaseType_t xReturn;
177
178 /* Determine if a name lookup is for this node. Two names are given
179 * to this node: that returned by pcApplicationHostnameHook() and that set
180 * by mainDEVICE_NICK_NAME. */
181 if( local_stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
182 {
183 xReturn = pdPASS;
184 }
185 else if( local_stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
186 {
187 xReturn = pdPASS;
188 }
189 else
190 {
191 xReturn = pdFAIL;
192 }
193
194 return xReturn;
195 }
196
197 #endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */
198 /*-----------------------------------------------------------*/
199
vApplicationIdleHook(void)200 void vApplicationIdleHook( void )
201 {
202 const uint32_t ulMSToSleep = 1;
203 const TickType_t xKitHitCheckPeriod = pdMS_TO_TICKS( 1000UL );
204 static TickType_t xTimeNow, xLastTimeCheck = 0;
205
206 if( ( xTimeNow - xLastTimeCheck ) > xKitHitCheckPeriod )
207 {
208 xLastTimeCheck = xTimeNow;
209 }
210
211 /* Exit. Just a stub. */
212 }
213
214 /*-----------------------------------------------------------*/
215
vLoggingPrintf(const char * pcFormat,...)216 void vLoggingPrintf( const char * pcFormat,
217 ... )
218 {
219 va_list arg;
220
221 va_start( arg, pcFormat );
222 vprintf( pcFormat, arg );
223 va_end( arg );
224 }
225 /*-----------------------------------------------------------*/
226
getUserCmd(char * pucUserCmd)227 void getUserCmd( char * pucUserCmd )
228 {
229 /* Provide a stub for this function. */
230 }
231 /*-----------------------------------------------------------*/
232
uxRand(void)233 UBaseType_t uxRand( void )
234 {
235 const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
236
237 /* Utility function to generate a pseudo random number. */
238
239 ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
240 return( ( int ) ( ulNextRand ) & 0x7fffUL );
241 }
242
xApplicationGetRandomNumber(uint32_t * pulNumber)243 BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
244 {
245 *pulNumber = ( uint32_t ) uxRand();
246
247 return pdTRUE;
248 }
249
250 /*-----------------------------------------------------------*/
251
vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize)252 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
253 StackType_t ** ppxIdleTaskStackBuffer,
254 uint32_t * pulIdleTaskStackSize )
255 {
256 /* Provide a stub for this function. */
257 }
258
259 /*-----------------------------------------------------------*/
260
vApplicationTickHook(void)261 void vApplicationTickHook( void )
262 {
263 /* Provide a stub for this function. */
264 }
265
266 /*-----------------------------------------------------------*/
267
vApplicationDaemonTaskStartupHook(void)268 void vApplicationDaemonTaskStartupHook( void )
269 {
270 /* Provide a stub for this function. */
271 }
272
273 /*
274 * Callback that provides the inputs necessary to generate a randomized TCP
275 * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION
276 * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION
277 * SYSTEMS.
278 */
ulApplicationGetNextSequenceNumber(uint32_t ulSourceAddress,uint16_t usSourcePort,uint32_t ulDestinationAddress,uint16_t usDestinationPort)279 extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
280 uint16_t usSourcePort,
281 uint32_t ulDestinationAddress,
282 uint16_t usDestinationPort )
283 {
284 ( void ) ulSourceAddress;
285 ( void ) usSourcePort;
286 ( void ) ulDestinationAddress;
287 ( void ) usDestinationPort;
288
289 return ( uint32_t ) uxRand();
290 }
291
vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer,StackType_t ** ppxTimerTaskStackBuffer,uint32_t * pulTimerTaskStackSize)292 void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
293 StackType_t ** ppxTimerTaskStackBuffer,
294 uint32_t * pulTimerTaskStackSize )
295 {
296 /* Provide a stub for this function. */
297 }
298
vApplicationMallocFailedHook(void)299 void vApplicationMallocFailedHook( void )
300 {
301 /* Provide a stub for this function. */
302 }
303
xNetworkInterfaceOutput(NetworkInterface_t * pxInterface,NetworkBufferDescriptor_t * const pxNetworkBuffer,BaseType_t bReleaseAfterSend)304 BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface,
305 NetworkBufferDescriptor_t * const pxNetworkBuffer,
306 BaseType_t bReleaseAfterSend )
307 {
308 /* Provide a stub for this function. */
309 return pdTRUE;
310 }
311
xNetworkInterfaceInitialise(void)312 BaseType_t xNetworkInterfaceInitialise( void )
313 {
314 /* Provide a stub for this function. */
315 return pdTRUE;
316 }
317
pxFillInterfaceDescriptor(BaseType_t xEMACIndex,struct xNetworkInterface * pxInterface)318 struct xNetworkInterface * pxFillInterfaceDescriptor( BaseType_t xEMACIndex,
319 struct xNetworkInterface * pxInterface )
320 {
321 return pxInterface;
322 }
323
324 #if ( ipconfigUSE_DHCP_HOOK != 0 )
325 #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 )
xApplicationDHCPHook(eDHCPCallbackPhase_t eDHCPPhase,uint32_t ulIPAddress)326 eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
327 uint32_t ulIPAddress )
328 #else
329 eDHCPCallbackAnswer_t xApplicationDHCPHook_Multi( eDHCPCallbackPhase_t eDHCPPhase,
330 struct xNetworkEndPoint * pxEndPoint,
331 IP_Address_t * pxIPAddress )
332 #endif
333 {
334 /* Provide a stub for this function. */
335 return eDHCPContinue;
336 }
337 #endif /* ( ipconfigUSE_DHCP_HOOK != 0 ) */
338
339 #if ( ipconfigPROCESS_CUSTOM_ETHERNET_FRAMES != 0 )
340
341 /*
342 * The stack will call this user hook for all Ethernet frames that it
343 * does not support, i.e. other than IPv4, IPv6 and ARP ( for the moment )
344 * If this hook returns eReleaseBuffer or eProcessBuffer, the stack will
345 * release and reuse the network buffer. If this hook returns
346 * eReturnEthernetFrame, that means user code has reused the network buffer
347 * to generate a response and the stack will send that response out.
348 * If this hook returns eFrameConsumed, the user code has ownership of the
349 * network buffer and has to release it when it's done.
350 */
eApplicationProcessCustomFrameHook(NetworkBufferDescriptor_t * const pxNetworkBuffer)351 eFrameProcessingResult_t eApplicationProcessCustomFrameHook( NetworkBufferDescriptor_t * const pxNetworkBuffer )
352 {
353 ( void ) ( pxNetworkBuffer );
354 return eProcessBuffer;
355 }
356
357 #endif
vApplicationPingReplyHook(ePingReplyStatus_t eStatus,uint16_t usIdentifier)358 void vApplicationPingReplyHook( ePingReplyStatus_t eStatus,
359 uint16_t usIdentifier )
360 {
361 /* Provide a stub for this function. */
362 }
363
364 #if ( ipconfigUSE_IPv6 != 0 ) && ( ipconfigUSE_DHCPv6 != 0 )
365 /* DHCPv6 needs a time-stamp, seconds after 1970. */
ulApplicationTimeHook(void)366 uint32_t ulApplicationTimeHook( void )
367 {
368 return ( uint32_t ) time( NULL );
369 }
370 #endif
371