tfSntpUserCreate
Table of Contents >> Application Reference >> Simple Network Time Protocol
| #include <trsocket.h> |
| ttSntpHandle tfSntpUserCreate | ( |
| const struct sockaddr_storage TM_FAR * serverAddrPtr, | |
| ttUserSntpCBFuncPtr userSntpFuncPtr, | |
| int flags, | |
| int TM_FAR * errorPtr | |
| ); |
Function Description
Create a SNTP association with the unicast or broadcast server specified in serverAddrPtr. Notification of time updates and other events will be done via the userSntpFuncPtr function pointer you provide. The mode of operation is selected via the flags parameter (see Flags below). The handle returned from tfSntpUserCreate() is used to identify the association when calling other SNTP functions.
The new SNTP client is inactive, initially. While inactive, you may call other functions to configure the SNTP client, e.g. tfSntpUserBind(), and tfSntpUserSetOption(). Start and run the SNTP client by calling tfSntpUserExecute(). When you no long require time updates, call tfSntpUserClose() to dispose of the descriptor.
You may call tfSntpUserCreate() more than once if you need to communicate with more than one server concurrently or you need to operate in both unicast and broadcast modes. Each SNTP client requires its own call to tfSntpUserExecute(). You can reuse the same userSntpFuncPtr function pointer for multiple instances and maintain separate data for each by using tfSntpUserSetOption() and tfSntpUserGetOption() with the TM_SNTP_OPT_USER_POINTER option.
Flags
Flag Meaning 0 The default mode: - Unicast – Treck SNTP periodically sends a request to the server and the server responds directly back. TM_SNTP_CREATE_BROADCAST is the complement setting.
- Non-blocking – tfSntpUserExecute() returns when idle and must be called periodically to service the SNTP client, e.g. for single-threaded and event loop applications. TM_BLOCKING_ON is the complement setting.
TM_SNTP_CREATE_BROADCAST Broadcast – Treck SNTP does not send to the server; the server periodically broadcasts an update to all clients on the network. TM_BLOCKING_ON Blocking – tfSntpUserExecute() is called once and blocks the thread when idle, e.g. for multithreaded applications using a dedicated thread for the SNTP client.
Example
#include "trsocket.h" char * ntpServerNames[] = { "0.pool.ntp.org", "1.pool.ntp.org" }; struct myData_t myNtpData[2]; /* some user-defined data structure */ /* * User function to spawn two background SNTP tasks. */ int mySntpFunction(void) { struct sockaddr_storage sockAddr; struct addrinfo * aiResult; ttSntpHandle sntpHandle[2]; int i; int errorCode; for (i = 0; i < 2; i++) { /* Get the IP address of the NTP server */ errorCode = getaddrinfo(ntpServerNames[i], NULL, NULL, &aiResult); assert(errorCode == TM_ENOERROR); memcpy(&sockAddr, aiResult->ai_addr, aiResult->ai_addrlen); freeaddrinfo(aiResult); /* Create a unicast SNTP client */ sntpHandle[i] = tfSntpUserCreate(&sockAddr, mySntpNotifyFunc, TM_BLOCKING_ON, &errorCode); assert((sntpHandle[i] != TM_SNTP_INVALID_HANDLE) && (errorCode == TM_ENOERROR)); /* Set my association specific data pointer */ errorCode = tfSntpUserSetOption(sntpHandle[i], TM_SNTP_OPT_USER_POINTER, &myNtpData[i], 0); assert(errorCode == TM_ENOERROR); /* Start a background thread for the SNTP client (O/S specific) */ KernelSpawnTask(mySntpTask, sntpHandle[i]); } . . . } /* * Background SNTP task code. */ void mySntpTask(ttSntpHandle sntpHandle) { int errorCode; /* Run the SNTP client */ errorCode = tfSntpUserExecute(sntpHandle); assert(errorCode == TM_ENOERROR); } /* * A single SNTP event handler for all associations. * Separate user data is kept for each association. */ void mySntpNotifyFunc( ttSntpHandle sntpHandle, const void TM_FAR * paramPtr, int eventId) { struct myData_t * myNtpDataPtr; struct timeval * tvPtr; char * str; int optLength; int errorCode; /* Get my association specific data pointer */ optLength = sizeof(myNtpDataPtr); errorCode = tfSntpUserGetOption(sntpHandle, TM_SNTP_OPT_USER_POINTER, &myNtpDataPtr, &optLength); assert(errorCode == TM_ENOERROR); /* Dispatch based on event */ switch (eventId) { case TM_SNTP_EVENT_STEP: case TM_SNTP_EVENT_PANIC: tvPtr = (struct timeval *)paramPtr; KernelSetTime(tvPtr); /* whatever the call is for your O/S */ break; case TM_SNTP_EVENT_SLEW: break; /* time difference is too small to worry about */ case TM_SNTP_EVENT_KISS: str = (char *)paramPtr; if ( (strcmp(str, "DENY") == 0) || (strcmp(str, "RSTR") == 0) || (strcmp(str, "RATE") == 0)) { /* * The RFC dictates that we cannot ignore some kiss codes. */ } break; case TM_SNTP_EVENT_ERROR: /* * This could be TM_EHOSTUNREACH if the NTP service is not running. * For non-blocking mode, errors codes are returned from tfSntpUserExecute(), instead. */ } . . . }
Parameters
- serverAddrPtr
- The IP address and port number of a unicast or broadcast SNTPv4 or NTPv4 server. Specify port number of zero to use the default NTP port, 123.
- userSntpFuncPtr
- The name of a function of type ttUserSntpCBFuncPtr() that Treck SNTP will call to notify you of time updates and other events.
- flags
- The bitwise OR combination of server mode and blocking mode flags (see the Flags section above).
- errorPtr
- A pointer to an integer variable into which Treck will store the error code.
Returns
- TM_SNTP_INVALID_HANDLE
- If an error occurred. Otherwise, the call was successfully and the handle returned may be used to manage the association.
Check *errorPtr for one of the following possible errors.
- If an error occurred. Otherwise, the call was successfully and the handle returned may be used to manage the association.
- TM_ENOERROR
- Success.
- TM_EINVAL
- Invalid parameter.
- TM_ENOBUFS
- Not enough memory.
- TM_EMFILE
- Cannot create SNTP socket (too many sockets).
Table of Contents >> Application Reference >> Simple Network Time Protocol