⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sntpclib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* sntpcLib.c - Simple Network Time Protocol (SNTP) client library *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history --------------------01k,07jan02,vvv  doc: added errnos for sntpcTimeGet and sntpcFetch (SPR #71557)01j,16mar99,spm  doc: removed references to configAll.h (SPR #25663)01e,14dec97,jdi  doc: cleanup.01d,10dec97,kbw  making man page changes01c,27aug97,spm  corrections for man page generation01b,15jul97,spm  code cleanup, documentation, and integration; entered in                 source code control01a,24may97,kyc  written*//* DESCRIPTIONThis library implements the client side of the Simple Network Time Protocol (SNTP), a protocol that allows a system to maintain the accuracy of its internal clock based on time values reported by one or more remote sources.  The library is included in the VxWorks image if INCLUDE_SNTPC is defined at the time the image is built.USER INTERFACEThe sntpcTimeGet() routine retrieves the time reported by a remote source andconverts that value for POSIX-compliant clocks.  The routine will either send a request and extract the time from the reply, or it will wait until a message isreceived from an SNTP/NTP server executing in broadcast mode.INCLUDE FILES: sntpcLib.hSEE ALSO: clockLib, RFC 1769*//* includes */#include "vxWorks.h"#include "sysLib.h"#include "ioLib.h"#include "inetLib.h"#include "hostLib.h"#include "sockLib.h"#include "errnoLib.h"#include "sntpcLib.h"/* globals */u_short sntpcPort;/* forward declarations */LOCAL STATUS sntpcListen (u_int, struct timespec *);LOCAL STATUS sntpcFetch (struct in_addr *, u_int, struct timespec *);/********************************************************************************* sntpcInit - set up the SNTP client** This routine is called to link the SNTP client module into the VxWorks* image. It assigns the UDP source and destination port according to the* corresponding SNTP_PORT setting.* * RETURNS: OK, always.** ERRNO: N/A** NOMANUAL*/STATUS sntpcInit    (    u_short 	port 	/* UDP source/destination port */    )    {    sntpcPort = htons (port);    return (OK);    }/********************************************************************************* sntpcFractionToNsec - convert time from the NTP format to POSIX time format** This routine converts the fractional part of the NTP timestamp format to a * value in nanoseconds compliant with the POSIX clock.  While the NTP time * format provides a precision of about 200 pico-seconds, rounding error in the * conversion routine reduces the precision to tenths of a micro-second.* * RETURNS: Value for struct timespec corresponding to NTP fractional part** ERRNO:   N/A** INTERNAL** Floating-point calculations can't be used because some boards (notably* the SPARC architectures) disable software floating point by default to * speed up context switching. These boards abort with an exception when* floating point operations are encountered.** NOMANUAL*/LOCAL ULONG sntpcFractionToNsec    (    ULONG sntpFraction      /* base 2 fractional part of the NTP timestamp */    )    {    ULONG factor = 0x8AC72305; /* Conversion factor from base 2 to base 10 */    ULONG divisor = 10;        /* Initial exponent for mantissa. */    ULONG mask = 1000000000;   /* Pulls digits of factor from left to right. */    int loop;    ULONG nsec = 0;    BOOL shift = FALSE;        /* Shifted to avoid overflow? */    /*      * Adjust large values so that no intermediate calculation exceeds      * 32 bits. (This test is overkill, since the fourth MSB can be set      * sometimes, but it's fast).     */     if (sntpFraction & 0xF0000000)        {        sntpFraction /= 10;        shift = TRUE;        }    /*      * In order to increase portability, the following conversion avoids     * floating point operations, so it is somewhat obscure.     *     * Incrementing the NTP fractional part increases the corresponding     * decimal value by 2^(-32). By interpreting the fractional part as an     * integer representing the number of increments, the equivalent decimal     * value is equal to the product of the fractional part and 0.2328306437.     * That value is the mantissa for 2^(-32). Multiplying by 2.328306437E-10     * would convert the NTP fractional part into the equivalent in seconds.     *     * The mask variable selects each digit from the factor sequentially, and     * the divisor shifts the digit the appropriate number of decimal places.      * The initial value of the divisor is 10 instead of 1E10 so that the      * conversion produces results in nanoseconds, as required by POSIX clocks.     */    for (loop = 0; loop < 10; loop++)    /* Ten digits in mantissa */        {	nsec += sntpFraction * (factor/mask)/divisor;  /* Use current digit. */	factor %= mask;    /* Remove most significant digit from the factor. */	mask /= 10;        /* Reduce length of mask by one. */	divisor *= 10;     /* Increase preceding zeroes by one. */        }    /* Scale result upwards if value was adjusted before processing. */    if (shift)        nsec *= 10;    return (nsec);    }/********************************************************************************* sntpcTimeGet - retrieve the current time from a remote source** This routine stores the current time as reported by an SNTP/NTP server in* the location indicated by <pCurrTime>.  The reported time is first converted* to the elapsed time since January 1, 1970, 00:00, GMT, which is the base value* used by UNIX systems.  If <pServerAddr> is NULL, the routine listens for * messages sent by an SNTP/NTP server in broadcast mode.  Otherwise, this* routine sends a request to the specified SNTP/NTP server and extracts the* reported time from the reply.  In either case, an error is returned if no * message is received within the interval specified by <timeout>.  Typically, * SNTP/NTP servers operating in broadcast mode send update messages every 64 * to 1024 seconds.  An infinite timeout value is specified by WAIT_FOREVER.* * RETURNS: OK, or ERROR if unsuccessful.** ERRNO:*  S_sntpcLib_INVALID_PARAMETER, S_sntpcLib_INVALID_ADDRESS, S_sntpcLib_TIMEOUT,*  S_sntpcLib_SERVER_UNSYNC, S_sntpcLib_VERSION_UNSUPPORTED*/STATUS sntpcTimeGet    (    char * 		pServerAddr, 	/* server IP address or hostname */    u_int 		timeout,	/* timeout interval in ticks */    struct timespec * 	pCurrTime	/* storage for retrieved time value */    )    {    STATUS result;    struct in_addr 	target;    if (pCurrTime == NULL || (timeout < 0 && timeout != WAIT_FOREVER))        {        errnoSet (S_sntpcLib_INVALID_PARAMETER);        return (ERROR);        }    if (pServerAddr == NULL)        result = sntpcListen (timeout, pCurrTime);    else        {        target.s_addr = hostGetByName (pServerAddr);        if (target.s_addr == ERROR)            target.s_addr = inet_addr (pServerAddr);            if (target.s_addr == ERROR)            {            errnoSet (S_sntpcLib_INVALID_ADDRESS);            return (ERROR);            }        result = sntpcFetch (&target, timeout, pCurrTime);         }    return (result);    }/********************************************************************************* sntpcFetch - send an SNTP request and retrieve the time from the reply** This routine sends an SNTP request to the IP address specified by* <pTargetAddr>, converts the returned NTP timestamp to the POSIX-compliant * clock format with the UNIX base value (elapsed time since 00:00 GMT on * Jan. 1, 1970), and stores the result in the location indicated by <pTime>.* * RETURNS: OK, or ERROR if unsuccessful.** ERRNO:*  S_sntpcLib_SERVER_UNSYNC*  S_sntpcLib_VERSION_UNSUPPORTED*  S_sntpcLib_TIMEOUT** NOMANUAL*/LOCAL STATUS sntpcFetch    (    struct in_addr * 	pTargetAddr, 	/* SNTP/NTP server IP address */    u_int 		timeout,	/* timeout in ticks */    struct timespec * 	pCurrTime	/* storage for retrieved time value */    )    {    SNTP_PACKET sntpRequest;     /* sntp request packet for */                                 /* transmission to server */    SNTP_PACKET sntpReply;       /* buffer for server reply */    struct sockaddr_in dstAddr;    struct sockaddr_in servAddr;    struct timeval sockTimeout;    int optval;    int clockRate;    int sntpSocket;    fd_set readFds;    int result;    int servAddrLen;      /* Set destination for request. */      bzero ( (char *)&dstAddr, sizeof (dstAddr));    dstAddr.sin_addr.s_addr = pTargetAddr->s_addr;    dstAddr.sin_family = AF_INET;    dstAddr.sin_port = sntpcPort;      /* Create socket for transmission. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -