ttUserSntpCBFuncPtr
Table of Contents >> Application Reference >> Simple Network Time Protocol
| #include <trsocket.h> |
| void ttUserSntpCBFuncPtr | ( |
| ttSntpHandle sntpHandle, | |
| const void TM_FAR * paramPtr, | |
| int eventId | |
| ); |
Function Description
Prototype for the function you provide to receive notification of SNTP events. Most calls to your function are made from tfSntpUserExecute(), the SNTP workhorse.
The events your function could receive are listed in Events below.
The TM_SNTP_EVENT_KISS event is generated in response to receiving a kiss-o-death message from the server. See the SNTP page for more information.
Events
SNTP Client Callback Events Event Name Context Parameter Type Description TM_SNTP_EVENT_SLEW tfSntpUserExecute struct timeval TM_FAR * (offset from local clock) A time update message was received from the server. The local clock offset was below the step threshold, set with option TM_SNTP_OPT_STEP_TIME, default 0.2s. The parameter contains the relative offset from the local clock—a signed value to be added to the local clock, e.g. clock += (double)(long)tvPtr->tv_sec + ((double)tvPtr->tv_usec * 1e-6). Application note: you may wish to set your step threshold to your maximum clock error tolerance such that you can ignore all slew events.TM_SNTP_EVENT_STEP tfSntpUserExecute struct timeval TM_FAR * (offset from Jan 1, 1970) A time update message was received from the server. The local clock offset was between the step threshold and the panic threshold, set with options TM_SNTP_OPT_STEP_TIME and TM_SNTP_OPT_PANIC_TIME, default 0.2s and 1000s, respectively. The parameter contains the absolute offset from January 1, 1970—the clock value to be set, e.g. clock = (double)(unsigned long)tvPtr->tv_sec + ((double)tvPtr->tv_usec * 1e-6).TM_SNTP_EVENT_PANIC tfSntpUserExecute struct timeval TM_FAR * (offset from Jan 1, 1970) A time update message was received from the server. The local clock offset was above the panic threshold, set with option TM_SNTP_OPT_PANIC_TIME, default 1000s. The parameter contains the absolute offset from January 1, 1970—the clock value to be set, e.g. clock = (double)(unsigned long)tvPtr->tv_sec + ((double)tvPtr->tv_usec * 1e-6). On a typical O/S, a panic event would cause the SNTP client to terminate with an error. Treck SNTP takes no action on a panic event and leaves the decision on what to do up to the application. If an embedded system starts with no knowledge of the current time, you will likely get this event on the first update.TM_SNTP_EVENT_KISS tfSntpUserExecute char TM_FAR * or ttUser32Bit TM_FAR * A kiss-o-death status message was received from the server with a kiss code in the 32-bit Reference Id field of the message. The value should be nul terminated ASCII characters but there is no guarantee. The parameter paramPtr points to the string/value. A full list of kiss codes can be found in RFC 5905, section 7.4. A few important codes can be found in the table below. The RFC dictates that recipients of kiss codes MUST inspect them and take appropriate action (see the Receiving a Kiss-o-Death message section). Treck SNTP takes no action upon receiving a kiss-o-death message and leaves the decision on what to do up to the application. TM_SNTP_EVENT_ERROR tfSntpUserExecute int TM_FAR * (Blocking mode only) An error occurred that is not severe enough to cause an exit from tfSntpUserExecute(). The parameter *paramPtr is the Treck error code. The decision on what action to take is left up to the application. (Note: for non-blocking mode, errors are returned from tfSntpUserExecute().) TM_SNTP_EVENT_SOCKET Receive Task, Socket Callback NULL (Non-blocking mode only) A socket event occurred, e.g. message received. In non-blocking mode, the application calls tfSntpUserExecute() periodically to perform any outstanding work, in which case, you may ignore this event. If you need faster response to events, use this event to know exactly when you need to call tfSntpUserExecute(). However, do not call tfSntpUserExecute() from this context, as it will impact all sockets. Set a flag to tell your main task or event loop to call tfSntpUserExecute(). TM_SNTP_EVENT_TIMER Timer Task, Timer Callback NULL (Non-blocking mode only) A timer event occurred, e.g. poll interval expired. In non-blocking mode, the application calls tfSntpUserExecute() periodically to perform any outstanding work, in which case, you may ignore this event. If you need faster response to events, use this event to know exactly when you need to call tfSntpUserExecute(). However, do not call tfSntpUserExecute() from this context, as it will impact all timers. Set a flag to tell your main task or event loop to call tfSntpUserExecute().
Example
#include "trsocket.h" /* * User function to create and run the SNTP client. */ int mySntpFunction(void) { struct sockaddr_storage sockAddr; ttSntpHandle sntpHandle; int errorCode; . . . #ifdef MY_APP_IS_BLOCKING /* Create a unicast blocking mode SNTP client */ sntpHandle = tfSntpUserCreate(&sockAddr, mySntpNotifyFunc, TM_BLOCKING_ON, &errorCode); assert((sntpHandle != TM_SNTP_INVALID_HANDLE) && (errorCode == TM_ENOERROR)); /* Start a background thread for the SNTP client (O/S specific) */ KernelSpawnTask(mySntpTask, sntpHandle); #else /* MY_APP_IS_BLOCKING */ /* Create a unicast non-blocking mode SNTP client */ sntpHandle = tfSntpUserCreate(&sockAddr, mySntpNotifyFunc, 0, &errorCode); assert((sntpHandle != TM_SNTP_INVALID_HANDLE) && (errorCode == TM_ENOERROR)); /* Run the SNTP client */ for (;;) { errorCode = tfSntpUserExecute(sntpHandle); if (errorCode != TM_ENOERROR) { break; } /* Kernel specific event synchronization */ KernelWaitForEvent(mySntpEvent); } #endif /* MY_APP_IS_BLOCKING */ . . . } #ifdef MY_APP_IS_BLOCKING /* * Background SNTP task code. */ void mySntpTask(ttSntpHandle sntpHandle) { int errorCode; /* Run the SNTP client */ errorCode = tfSntpUserExecute(sntpHandle); assert(errorCode == TM_ENOERROR); } #endif /* MY_APP_IS_BLOCKING */ /* * SNTP event handler for the association. */ void mySntpNotifyFunc( ttSntpHandle sntpHandle, const void TM_FAR * paramPtr, int eventId) { struct timeval * tvPtr; ttUser32Bit * u32Ptr; char * strPtr; int errorCode; /* Dispatch based on event */ switch (eventId) { case TM_SNTP_EVENT_STEP: case TM_SNTP_EVENT_PANIC: /* * Kernel specific settimeofday(). * tvPtr contains the number of seconds offset from Jan. 1, 1970. */ tvPtr = (struct timeval *)paramPtr; KernelSetTime(tvPtr); break; case TM_SNTP_EVENT_SLEW: /* * Kernel specific adjtime(). * tvPtr contains the number of seconds +/- offset from the local clock. */ tvPtr = (struct timeval *)paramPtr; KernelAdjustTime(tvPtr); break; case TM_SNTP_EVENT_KISS: /* * The RFC dictates that we cannot ignore some kiss codes. * The parameter is a 32-bit value that may be ASCII. */ u32Ptr = (ttUser32Bit *)paramPtr; /* reference as 32-bit */ strPtr = (char *)paramPtr; /* reference as string */ break; #ifdef MY_APP_IS_BLOCKING case TM_SNTP_EVENT_ERROR: /* * This could be a TM_EHOSTUNREACH or some other error. * Blocking mode only. */ errorCode = *(int *)paramPtr; /* error code */ break; #else /* MY_APP_IS_BLOCKING */ case TM_SNTP_EVENT_SOCKET: case TM_SNTP_EVENT_TIMER: /* * Signal the main code to call tfSntpUserExecute(). * Non-blocking mode only. */ KernelSignalEvent(mySntpEvent); break; #endif /* MY_APP_IS_BLOCKING */ } . . . }
Parameters
- sntpHandle
- The SNTP client handle passed to tfSntpUserExecute().
- paramPtr
- A pointer to a parameter associated with the event.
- eventId
- The event type.
Table of Contents >> Application Reference >> Simple Network Time Protocol