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