mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-15 16:15:08 -05:00
Merging IPv6 demo changes to main (#1028)
* Add IPv6 Demo (#937) * Add demo changes * Update kernel and library paths * Update main.c * Run uncrustify * Fix spell checker * CI check file headers update * Add IPv6/v4 UDP echo server with zero copy/non-zero copy versions * Add VS proj file changes to include the UDP echo sample code * readme update --------- Co-authored-by: Tony Josi <tonyjosi@amazon.com> * Update Backward Compatibility Flag (#954) * Update Backward Compatibility Flag * Update FreeRTOS_GetUDPPayloadBuffer_ByIPType * Update FreeRTOS_IPStart to FreeRTOS_IPInit_Multi * Update Application APIs * Remove ipconfigCOMPATIBLE_WITH_SINGLE * Update Static Lib files (#956) * Update Static Lib files * making vApplicationIPNetworkEventHook backward compatible in demos * Update CI check file headers --------- Co-authored-by: Tony Josi <tonyjosi@amazon.com> * Add WinPCap NetworkInterface Changes (#958) * Update winpcap network interface * Run uncrustify * Update function to include NetworkInterface_t parameters * Adding compatibility for xApplicationDNSQueryHook with latest dev branch for old demos (#957) * adding compatibility for xApplicationDNSQueryHook with latest dev branch * adding tcp echo server source * removing unused sub demos * fix build issues (#969) * Update demo to latest +TCP dev/IPv6_integration (#978) * remove macro namings * rename sin_addr to sin_address.ulIP_IPv4 for ipv6 demo * replace in6addr_any with FreeRTOS_in6addr_any * replace mainCREATE_UDP_ECHO_SERVER_TASK with mainCREATE_UDP_ECHO_TASKS_SINGLE * handle removal of sin_addr macro to sin_address.ulIP_IPv4 * updating +TCP repo to latest dev/IPv6_integration * minor update to more clear code * more sin_addr to sin_address.ulIP_IPv4 replacements * fix makefiles for qemu and posix demos * review feedback changes * Update FreeRTOS-Plus-TCP for RC2 * Change from PR (#994) * Update FreeRTOS-Plus-TCP for RC2 * Update copyright * Ignore WinPCap for files header check failure. * Update checker * Update manifest * Point manifest to latest commit * Fix Spell-checker * Update doxygen * Update xApplicationDHCPHook for backward compatibility (#999) * Update xApplicationDHCPHook for backward compatability * Update IPv6 * Update VisualStudio Static Project files * Update pxEndPoint error (#1002) * Update IPv6 demo ReadMe (#1004) * Update ReadMe * Update setup requirement * Update UDP demo info * Update comment * TCP demo changes post build separation (#1011) * adding sin_family to dest adddr for FreeRTOS_sendto * updating FreeRTOS_bind to input sin_family post build separation changes * updating FreeRTOS_connect to input sin_family post build separation changes * minor fix * updating copyright year * updating file headers * updating +TCP submodule * updating file headers * updating file headers * updating manifest file to have latest +TCP submodule hash * Fix issue with posix demo while running with ipconfigIPv4_BACKWARD_COMPATIBLE enabled for +TCP stack (#1027) * Update the submodule pointer to IPv6 main * Update manifest with latest TCP commit * Update file checker exception * Ignore Visual studio project file from file header checker --------- Co-authored-by: Tony Josi <tonyjosi@amazon.com>
This commit is contained in:
parent
8f3233e0a0
commit
301ed5881b
83 changed files with 12126 additions and 1074 deletions
|
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
* FreeRTOS V202212.00
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NTPDemo.c
|
||||
*
|
||||
* An example of how to lookup a domain using DNS
|
||||
* And also how to send and receive UDP messages to get the NTP time
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DNS.h"
|
||||
#include "FreeRTOS_Stream_Buffer.h"
|
||||
|
||||
/* Use the date & time functions from +FAT. */
|
||||
#if ( USE_PLUS_FAT != 0 )
|
||||
#include "ff_time.h"
|
||||
#endif /* ( USE_PLUS_FAT != 0 ) */
|
||||
|
||||
#include "NTPDemo.h"
|
||||
#include "ntpClient.h"
|
||||
|
||||
#include "date_and_time.h"
|
||||
|
||||
#if ( ipconfigDNS_USE_CALLBACKS == 0 )
|
||||
#error ipconfigDNS_USE_CALLBACKS must be 1
|
||||
#endif
|
||||
|
||||
#if ( ipconfigMULTI_INTERFACE == 0 )
|
||||
#ifndef ipSIZE_OF_IPv4_ADDRESS
|
||||
#define ipSIZE_OF_IPv4_ADDRESS 4
|
||||
#endif
|
||||
#define FREERTOS_AF_INET4 FREERTOS_AF_INET
|
||||
#endif
|
||||
|
||||
/* Set time: sets the current time in seconds-after-1/1/1970
|
||||
* This function must be provided by the application. */
|
||||
|
||||
time_t get_time( time_t * puxTime );
|
||||
int set_time( const time_t * t );
|
||||
|
||||
enum EStatus
|
||||
{
|
||||
EStatusLookup,
|
||||
EStatusAsking,
|
||||
EStatusPause,
|
||||
EStatusFailed,
|
||||
};
|
||||
|
||||
static struct SNtpPacket xNTPPacket;
|
||||
|
||||
BaseType_t xNTPHasTime;
|
||||
uint32_t ulNTPTime;
|
||||
|
||||
#if ( ipconfigUSE_CALLBACKS == 0 )
|
||||
static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ];
|
||||
#endif
|
||||
|
||||
static enum EStatus xStatus = EStatusLookup;
|
||||
|
||||
static const char * pcTimeServers[] =
|
||||
{
|
||||
"0.asia.pool.ntp.org",
|
||||
"0.europe.pool.ntp.org",
|
||||
"0.id.pool.ntp.org",
|
||||
"0.south-america.pool.ntp.org",
|
||||
"0.oceania.pool.ntp.org",
|
||||
"0.north-america.pool.ntp.org"
|
||||
};
|
||||
|
||||
static SemaphoreHandle_t xNTPWakeupSem = NULL;
|
||||
static uint32_t ulIPAddressFound;
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
static struct freertos_sockaddr xIPAddressFound;
|
||||
#endif
|
||||
static BaseType_t xHasIPAddress = pdFALSE;
|
||||
|
||||
static Socket_t xUDPSocket = NULL;
|
||||
static TaskHandle_t xNTPTaskhandle = NULL;
|
||||
static TickType_t uxSendTime;
|
||||
static BaseType_t xPreferredHostType = FREERTOS_AF_INET4;
|
||||
static BaseType_t xDNSAsynchronous = pdTRUE;
|
||||
static BaseType_t xDNSLogging = pdFALSE;
|
||||
|
||||
static void prvNTPTask( void * pvParameters );
|
||||
|
||||
static void vSignalTask( void )
|
||||
{
|
||||
#if ( ipconfigUSE_CALLBACKS == 0 )
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
/* Send a signal to the socket so that the
|
||||
* FreeRTOS_recvfrom will get interrupted. */
|
||||
FreeRTOS_SignalSocket( xUDPSocket );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if( xNTPWakeupSem != NULL )
|
||||
{
|
||||
xSemaphoreGive( xNTPWakeupSem );
|
||||
}
|
||||
}
|
||||
|
||||
void vNTPClearCache( void )
|
||||
{
|
||||
ulIPAddressFound = 0U;
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
{
|
||||
memset( &( xIPAddressFound ), 0, sizeof xIPAddressFound );
|
||||
}
|
||||
#endif
|
||||
xHasIPAddress = pdFALSE;
|
||||
}
|
||||
|
||||
void vNTPSetNTPType( BaseType_t aIPType,
|
||||
BaseType_t xAsynchronous,
|
||||
BaseType_t xLogging )
|
||||
{
|
||||
switch( aIPType )
|
||||
{
|
||||
case 4:
|
||||
xPreferredHostType = FREERTOS_AF_INET4;
|
||||
break;
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
case 6:
|
||||
xPreferredHostType = FREERTOS_AF_INET6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xDNSAsynchronous = xAsynchronous;
|
||||
xDNSLogging = xLogging;
|
||||
}
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize,
|
||||
UBaseType_t uxTaskPriority )
|
||||
{
|
||||
/* The only public function in this module: start a task to contact
|
||||
* some NTP server. */
|
||||
|
||||
if( xNTPTaskhandle != NULL )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusPause:
|
||||
xStatus = EStatusAsking;
|
||||
vSignalTask();
|
||||
break;
|
||||
|
||||
case EStatusLookup:
|
||||
FreeRTOS_printf( ( "NTP looking up server\n" ) );
|
||||
break;
|
||||
|
||||
case EStatusAsking:
|
||||
FreeRTOS_printf( ( "NTP still asking\n" ) );
|
||||
break;
|
||||
|
||||
case EStatusFailed:
|
||||
FreeRTOS_printf( ( "NTP failed somehow\n" ) );
|
||||
ulIPAddressFound = 0ul;
|
||||
xStatus = EStatusLookup;
|
||||
vSignalTask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
|
||||
|
||||
if( xUDPSocket != NULL )
|
||||
{
|
||||
struct freertos_sockaddr xAddress;
|
||||
#if ( ipconfigUSE_CALLBACKS != 0 )
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 );
|
||||
#else
|
||||
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
|
||||
#endif
|
||||
|
||||
xAddress.sin_address.ulIP_IPv4 = 0ul;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
xAddress.sin_family = FREERTOS_AF_INET;
|
||||
|
||||
FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
xTaskCreate( prvNTPTask, /* The function that implements the task. */
|
||||
( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */
|
||||
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
|
||||
NULL, /* The task parameter, not used in this case. */
|
||||
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
|
||||
&xNTPTaskhandle ); /* The task handle. */
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_printf( ( "Creating socket failed\n" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
static void vDNS_callback( const char * pcName,
|
||||
void * pvSearchID,
|
||||
struct freertos_addrinfo * pxAddress )
|
||||
{
|
||||
xStatus = EStatusAsking;
|
||||
|
||||
( void ) pvSearchID;
|
||||
|
||||
if( pxAddress == NULL )
|
||||
{
|
||||
FreeRTOS_printf( ( "DNS lookup timed out\n" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pxAddress->ai_family == FREERTOS_AF_INET4 )
|
||||
{
|
||||
char pcBuf[ 16 ];
|
||||
uint32_t ulIPAddress;
|
||||
|
||||
/* The DNS lookup has a result, or it has reached the time-out. */
|
||||
ulIPAddress = pxAddress->ai_addr->sin_address.ulIP_IPv4;
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
|
||||
FreeRTOS_printf( ( "vDNS_callback: IP address of %s found: %s\n", pcName, pcBuf ) );
|
||||
|
||||
/* if( ulIPAddressFound == 0U ) */
|
||||
/* { */
|
||||
/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 162, 159, 200, 1 ); */
|
||||
/* } */
|
||||
if( ulIPAddressFound != 0U )
|
||||
{
|
||||
memset( xIPAddressFound.sin_address.xIP_IPv6.ucBytes, 0, ipSIZE_OF_IPv6_ADDRESS );
|
||||
xHasIPAddress = pdTRUE;
|
||||
}
|
||||
}
|
||||
else if( pxAddress->ai_family == FREERTOS_AF_INET6 )
|
||||
{
|
||||
/* struct freertos_sockaddr * ai_addr */
|
||||
struct freertos_sockaddr * sockaddr6 = ( struct freertos_sockaddr * ) pxAddress->ai_addr;
|
||||
|
||||
xIPAddressFound.sin_len = sizeof( xIPAddressFound ); /* Ignored, still present for backward compatibility. */
|
||||
xIPAddressFound.sin_family = FREERTOS_AF_INET6; /* Set to FREERTOS_AF_INET6. */
|
||||
xIPAddressFound.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
xIPAddressFound.sin_flowinfo = 0; /* IPv6 flow information. */
|
||||
memcpy( xIPAddressFound.sin_address.xIP_IPv6.ucBytes, sockaddr6->sin_address.xIP_IPv6.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
|
||||
|
||||
FreeRTOS_printf( ( "vDNS_callback: using address %pip\n", xIPAddressFound.sin_address.xIP_IPv6.ucBytes ) );
|
||||
ulIPAddressFound = 0U;
|
||||
xHasIPAddress = pdTRUE;
|
||||
}
|
||||
}
|
||||
|
||||
vSignalTask();
|
||||
}
|
||||
#else /* if ( ipconfigUSE_IPv6 != 0 ) */
|
||||
static void vDNS_callback( const char * pcName,
|
||||
void * pvSearchID,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
char pcBuf[ 16 ];
|
||||
|
||||
/* The DNS lookup has a result, or it has reached the time-out. */
|
||||
FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
|
||||
FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) );
|
||||
|
||||
if( ulIPAddressFound == 0U )
|
||||
{
|
||||
ulIPAddressFound = ulIPAddress;
|
||||
}
|
||||
|
||||
/* For testing: in case DNS doesn't respond, still try some NTP server
|
||||
* with a known IP-address. */
|
||||
/* if( ulIPAddressFound == 0U ) */
|
||||
/* { */
|
||||
/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 ); */
|
||||
/* / * ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); * / */
|
||||
/* } */
|
||||
if( ulIPAddressFound != 0U )
|
||||
{
|
||||
xHasIPAddress = pdTRUE;
|
||||
xStatus = EStatusAsking;
|
||||
}
|
||||
|
||||
vSignalTask();
|
||||
}
|
||||
#endif /* if ( ipconfigUSE_IPv6 != 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSwapFields( struct SNtpPacket * pxPacket )
|
||||
{
|
||||
/* NTP messages are big-endian */
|
||||
pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay );
|
||||
pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion );
|
||||
|
||||
pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds );
|
||||
pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction );
|
||||
|
||||
pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds );
|
||||
pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction );
|
||||
|
||||
pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds );
|
||||
pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction );
|
||||
|
||||
pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds );
|
||||
pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvNTPPacketInit()
|
||||
{
|
||||
memset( &xNTPPacket, '\0', sizeof( xNTPPacket ) );
|
||||
|
||||
xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */
|
||||
xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */
|
||||
xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */
|
||||
xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */
|
||||
xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */
|
||||
|
||||
/* use the recorded NTP time */
|
||||
time_t uxSecs = get_time( NULL ); /* apTime may be NULL, returns seconds */
|
||||
|
||||
xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */
|
||||
xNTPPacket.transmitTimestamp.seconds = uxSecs + 3;
|
||||
|
||||
/* Transform the contents of the fields from native to big endian. */
|
||||
prvSwapFields( &xNTPPacket );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvReadTime( struct SNtpPacket * pxPacket )
|
||||
{
|
||||
#if ( USE_PLUS_FAT != 0 )
|
||||
FF_TimeStruct_t xTimeStruct;
|
||||
#else
|
||||
struct tm xTimeStruct;
|
||||
#endif
|
||||
|
||||
time_t uxPreviousSeconds;
|
||||
time_t uxPreviousMS;
|
||||
|
||||
time_t uxCurrentSeconds;
|
||||
time_t uxCurrentMS;
|
||||
|
||||
const char * pcTimeUnit;
|
||||
int32_t ilDiff;
|
||||
TickType_t uxTravelTime;
|
||||
|
||||
uxTravelTime = xTaskGetTickCount() - uxSendTime;
|
||||
|
||||
/* Transform the contents of the fields from big to native endian. */
|
||||
prvSwapFields( pxPacket );
|
||||
|
||||
uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970;
|
||||
uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967;
|
||||
uxCurrentSeconds += uxCurrentMS / 1000;
|
||||
uxCurrentMS = uxCurrentMS % 1000;
|
||||
|
||||
/* Get the last time recorded */
|
||||
uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS );
|
||||
|
||||
/* Set the new time with precision in msec. * / */
|
||||
FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS );
|
||||
|
||||
if( uxCurrentSeconds >= uxPreviousSeconds )
|
||||
{
|
||||
ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds );
|
||||
}
|
||||
else
|
||||
{
|
||||
ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds );
|
||||
}
|
||||
|
||||
if( ( ilDiff < -5 ) || ( ilDiff > 5 ) )
|
||||
{
|
||||
/* More than 5 seconds difference. */
|
||||
pcTimeUnit = "sec";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Less than or equal to 5 second difference. */
|
||||
pcTimeUnit = "ms";
|
||||
uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds;
|
||||
int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS;
|
||||
int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS;
|
||||
ilDiff = iCurMS - iPrevMS;
|
||||
}
|
||||
|
||||
/*uxCurrentSeconds -= iTimeZone; */
|
||||
|
||||
#if ( USE_PLUS_FAT != 0 )
|
||||
FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct );
|
||||
#else
|
||||
gmtime_r( &uxCurrentSeconds, &xTimeStruct );
|
||||
#endif /* ( USE_PLUS_FAT != 0 ) */
|
||||
|
||||
/*
|
||||
* 378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms)
|
||||
* 379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms)
|
||||
*/
|
||||
/* NTP time: -858993460/-858993459/-858991560 -858993460:-858993460:-858993460.158 Diff 1607503255 sec (60 ms) */
|
||||
FreeRTOS_printf( ( "NTP time: %u/%u/%02u %2u:%02u:%02u.%03u Diff %d %s (%lu ms)\n",
|
||||
( unsigned ) xTimeStruct.tm_mday,
|
||||
( unsigned ) xTimeStruct.tm_mon + 1,
|
||||
( unsigned ) xTimeStruct.tm_year + 1900,
|
||||
( unsigned ) xTimeStruct.tm_hour,
|
||||
( unsigned ) xTimeStruct.tm_min,
|
||||
( unsigned ) xTimeStruct.tm_sec,
|
||||
( unsigned ) uxCurrentMS,
|
||||
( signed ) ilDiff,
|
||||
pcTimeUnit,
|
||||
uxTravelTime ) );
|
||||
|
||||
xNTPHasTime = pdTRUE;
|
||||
ulNTPTime = uxCurrentSeconds;
|
||||
set_time( &uxCurrentSeconds );
|
||||
|
||||
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
|
||||
( void ) pcTimeUnit;
|
||||
( void ) uxTravelTime;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ipconfigUSE_CALLBACKS != 0 )
|
||||
|
||||
static BaseType_t xOnUDPReceive( Socket_t xSocket,
|
||||
void * pvData,
|
||||
size_t xLength,
|
||||
const struct freertos_sockaddr * pxFrom,
|
||||
const struct freertos_sockaddr * pxDest )
|
||||
{
|
||||
( void ) xSocket;
|
||||
( void ) pxFrom;
|
||||
( void ) pxDest;
|
||||
|
||||
if( xLength >= sizeof( xNTPPacket ) )
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket * ) pvData );
|
||||
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
|
||||
vSignalTask();
|
||||
/* Tell the driver not to store the RX data */
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
static void prvNTPTask( void * pvParameters )
|
||||
{
|
||||
BaseType_t xServerIndex = 3;
|
||||
struct freertos_sockaddr xAddress;
|
||||
|
||||
#if ( ipconfigUSE_CALLBACKS != 0 )
|
||||
F_TCP_UDP_Handler_t xHandler;
|
||||
#endif /* ipconfigUSE_CALLBACKS != 0 */
|
||||
|
||||
( void ) pvParameters;
|
||||
|
||||
xStatus = EStatusLookup;
|
||||
#if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xNTPWakeupSem = xSemaphoreCreateBinary();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
memset( &xHandler, '\0', sizeof( xHandler ) );
|
||||
xHandler.pxOnUDPReceive = xOnUDPReceive;
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
|
||||
}
|
||||
#endif
|
||||
#if ( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
|
||||
{
|
||||
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
switch( xStatus )
|
||||
{
|
||||
case EStatusLookup:
|
||||
|
||||
if( xHasIPAddress == 0 )
|
||||
{
|
||||
char pcServerName[ 64 ];
|
||||
|
||||
if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) )
|
||||
{
|
||||
xServerIndex = 0;
|
||||
}
|
||||
|
||||
snprintf( pcServerName, sizeof pcServerName, "%s", pcTimeServers[ xServerIndex ] );
|
||||
|
||||
if( ( pcServerName[ 0 ] == '0' ) && ( xPreferredHostType == FREERTOS_AF_INET6 ) )
|
||||
{
|
||||
pcServerName[ 0 ] = '2';
|
||||
}
|
||||
|
||||
FreeRTOS_printf( ( "Looking up server '%s' IPv%c\n",
|
||||
pcServerName,
|
||||
( xPreferredHostType == FREERTOS_AF_INET4 ) ? '4' : '6' ) );
|
||||
#if ( ipconfigMULTI_INTERFACE != 0 )
|
||||
struct freertos_addrinfo xHints;
|
||||
struct freertos_addrinfo * pxResults = NULL;
|
||||
|
||||
memset( &( xHints ), 0, sizeof xHints );
|
||||
xHints.ai_family = xPreferredHostType;
|
||||
|
||||
if( xDNSAsynchronous != 0 )
|
||||
{
|
||||
FreeRTOS_getaddrinfo_a( pcServerName, /* The name of the node or device */
|
||||
NULL, /* Ignored for now. */
|
||||
&( xHints ), /* If not NULL: preferences. */
|
||||
&( pxResults ), /* An allocated struct, containing the results. */
|
||||
vDNS_callback,
|
||||
( void * ) NULL, /* An object or a reference. */
|
||||
pdMS_TO_TICKS( 2500U ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeRTOS_getaddrinfo( pcServerName, /* The name of the node or device */
|
||||
NULL, /* Ignored for now. */
|
||||
&( xHints ), /* If not NULL: preferences. */
|
||||
&( pxResults ) ); /* An allocated struct, containing the results. */
|
||||
|
||||
if( pxResults != NULL )
|
||||
{
|
||||
vDNS_callback( pcServerName, NULL, pxResults );
|
||||
}
|
||||
}
|
||||
#else /* if ( ipconfigMULTI_INTERFACE != 0 ) */
|
||||
FreeRTOS_gethostbyname_a( pcServerName, vDNS_callback, ( void * ) NULL, 1200 );
|
||||
#endif /* if ( ipconfigMULTI_INTERFACE != 0 ) */
|
||||
}
|
||||
else
|
||||
{
|
||||
xStatus = EStatusAsking;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EStatusAsking:
|
||||
prvNTPPacketInit();
|
||||
uxSendTime = xTaskGetTickCount();
|
||||
#if ( ipconfigUSE_IPv6 != 0 )
|
||||
if( memcmp( xIPAddressFound.sin_address.xIP_IPv6.ucBytes, FreeRTOS_in6addr_any.ucBytes, ipSIZE_OF_IPv6_ADDRESS ) != 0 )
|
||||
{
|
||||
FreeRTOS_printf( ( "Sending UDP message to %pip:%u\n",
|
||||
xIPAddressFound.sin_address.xIP_IPv6.ucBytes,
|
||||
FreeRTOS_ntohs( xIPAddressFound.sin_port ) ) );
|
||||
|
||||
FreeRTOS_sendto( xUDPSocket,
|
||||
( void * ) &xNTPPacket, sizeof( xNTPPacket ),
|
||||
0,
|
||||
( const struct freertos_sockaddr * ) &( xIPAddressFound ),
|
||||
sizeof( xIPAddressFound ) );
|
||||
}
|
||||
else
|
||||
#endif /* ( ipconfigUSE_IPv6 != 0 ) */
|
||||
{
|
||||
xAddress.sin_address.ulIP_IPv4 = ulIPAddressFound;
|
||||
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
|
||||
xAddress.sin_family = FREERTOS_AF_INET;
|
||||
|
||||
FreeRTOS_printf( ( "Sending UDP message to %lxip:%u\n",
|
||||
FreeRTOS_ntohl( ulIPAddressFound ),
|
||||
FreeRTOS_ntohs( xAddress.sin_port ) ) );
|
||||
|
||||
FreeRTOS_sendto( xUDPSocket,
|
||||
( void * ) &xNTPPacket,
|
||||
sizeof( xNTPPacket ),
|
||||
0, &( xAddress ),
|
||||
sizeof( xAddress ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EStatusPause:
|
||||
break;
|
||||
|
||||
case EStatusFailed:
|
||||
break;
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_CALLBACKS != 0 )
|
||||
{
|
||||
xSemaphoreTake( xNTPWakeupSem, 5000 );
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t xAddressSize;
|
||||
BaseType_t xReturned;
|
||||
|
||||
xAddressSize = sizeof( xAddress );
|
||||
xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize );
|
||||
|
||||
switch( xReturned )
|
||||
{
|
||||
case 0:
|
||||
case -pdFREERTOS_ERRNO_EAGAIN:
|
||||
case -pdFREERTOS_ERRNO_EINTR:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if( xReturned < sizeof( xNTPPacket ) )
|
||||
{
|
||||
FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
prvReadTime( ( struct SNtpPacket * ) cRecvBuffer );
|
||||
|
||||
if( xStatus != EStatusPause )
|
||||
{
|
||||
xStatus = EStatusPause;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* if ( ipconfigUSE_CALLBACKS != 0 ) */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* FreeRTOS V202212.00
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* A simple demo for NTP using FreeRTOS+TCP
|
||||
*/
|
||||
|
||||
#ifndef NTPDEMO_H
|
||||
|
||||
#define NTPDEMO_H
|
||||
|
||||
void vStartNTPTask( uint16_t usTaskStackSize,
|
||||
UBaseType_t uxTaskPriority );
|
||||
|
||||
/*
|
||||
* xIPVersion = 4 or 6.
|
||||
* xAsynchronous = true for asynchronous DNS lookups.
|
||||
* xLogging = true to get more logging.
|
||||
*/
|
||||
void vNTPSetNTPType( BaseType_t aIPType,
|
||||
BaseType_t xAsynchronous,
|
||||
BaseType_t xLogging );
|
||||
|
||||
/* Delete the IP-addresses of the NTP server to force a DNS lookup. */
|
||||
void vNTPClearCache( void );
|
||||
|
||||
extern BaseType_t xNTPHasTime;
|
||||
extern uint32_t ulNTPTime;
|
||||
|
||||
#endif /* ifndef NTPDEMO_H */
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* FreeRTOS V202212.00
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/* */
|
||||
/* ntpClient.h */
|
||||
/* */
|
||||
|
||||
#ifndef __NTPCLIENT_H__
|
||||
|
||||
#define __NTPCLIENT_H__
|
||||
|
||||
#define NTP_PORT 123
|
||||
|
||||
typedef uint32_t quint32;
|
||||
typedef int32_t qint32;
|
||||
typedef uint8_t quint8;
|
||||
typedef int8_t qint8;
|
||||
|
||||
typedef union _SNtpFlags SNtpFlags;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__( x )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 64-bit NTP timestamp.
|
||||
*/
|
||||
struct __attribute__( ( __packed__ ) ) _SNtpTimestamp
|
||||
{
|
||||
/** Number of seconds passed since Jan 1 1900, in big-endian format. */
|
||||
quint32 seconds;
|
||||
|
||||
/** Fractional time part, in <tt>1/0xFFFFFFFF</tt>s of a second. */
|
||||
quint32 fraction;
|
||||
};
|
||||
|
||||
typedef struct _SNtpTimestamp SNtpTimestamp;
|
||||
|
||||
/**
|
||||
* Mandatory part of an NTP packet
|
||||
*/
|
||||
struct SNtpPacket
|
||||
{
|
||||
/** Flags. */
|
||||
unsigned char flags; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */
|
||||
|
||||
/** Stratum of the clock. */
|
||||
quint8 stratum; /* value 0 : unspecified */
|
||||
|
||||
/** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */
|
||||
qint8 poll; /* 10 means 1 << 10 = 1024 seconds */
|
||||
|
||||
/** Precision of the clock, in log2 seconds. Note that the value is signed. */
|
||||
qint8 precision; /* 0xFA = 250 = 0.015625 seconds */
|
||||
|
||||
/** Round trip time to the primary reference source, in NTP short format. */
|
||||
qint32 rootDelay; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */
|
||||
|
||||
/** Nominal error relative to the primary reference source. */
|
||||
qint32 rootDispersion; /* 0x0008 CAC8 = 8.7912 seconds */
|
||||
|
||||
/** Reference identifier (either a 4 character string or an IP address). */
|
||||
qint8 referenceID[ 4 ]; /* or just 0000 */
|
||||
|
||||
/** The time at which the clock was last set or corrected. */
|
||||
SNtpTimestamp referenceTimestamp; /* Current time */
|
||||
|
||||
/** The time at which the request departed the client for the server. */
|
||||
SNtpTimestamp originateTimestamp; /* Keep 0 */
|
||||
|
||||
/** The time at which the request arrived at the server. */
|
||||
SNtpTimestamp receiveTimestamp; /* Keep 0 */
|
||||
|
||||
/** The time at which the reply departed the server for client. */
|
||||
SNtpTimestamp transmitTimestamp;
|
||||
};
|
||||
|
||||
/* Add this number to get secs since 1-1-1900 */
|
||||
#define TIME1970 2208988800UL
|
||||
|
||||
#endif /* __NTPCLIENT_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue