tfSntpUserCreate

Jump to: navigation, search

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.

  • 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