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

📄 rvntptime.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
Filename    : rvntptime.c
Description : NTP time structure definition and manipulation
************************************************************************
        Copyright (c) 2001 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..

RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/
#include "rvntptime.h"

/* difference between NTP epoc (Jan 1, 1900) and time epoch (Jan 1 1970) in seconds */
#define NTPDELTA RvUint32Const(2208988800)

/* Create NTP time from base information */
RvNtpTime *RvNtpTimeConstruct(RvNtpTime *ntime, RvUint32 secs, RvUint32 fraction)
{
#if defined(RV_NULLCHECK)
    if(ntime == NULL) return NULL;
#endif

    ntime->secs = secs;
    ntime->fraction = fraction;
    return ntime;
}

/* Construct an NTP time from a RvTime time. The two formats do not    */
/* have the exact same resolution so there can be some round-off       */
/* error. The timetype parameter indicates wether absolute or relative */
/* time is stored in time. Absolute times are calander times that need */
/* to have the difference in epochs dealt with. Note that time passed  */
/* in can be negative since NTP time epoch is earlier.     */
RVCOREAPI RvNtpTime * RVCALLCONV RvNtpTimeConstructFromTime(RvNtpTime *ntime, const RvTime *t, RvBool timetype)
{
#if defined(RV_NULLCHECK)
    if((ntime == NULL) || (t == NULL)) return NULL;
#endif
#if defined(RV_RANGECHECK)
    if((timetype != RV_NTPTIME_ABSOLUTE) && (timetype != RV_NTPTIME_RELATIVE))
        return NULL;
#endif

    ntime->secs = (RvUint32)RvTimeGetSecs(t);
    if(timetype == RV_NTPTIME_ABSOLUTE)
        ntime->secs += NTPDELTA;
    ntime->fraction = RvNtpTimeNsecsToFraction(RvTimeGetNsecs(t));
    return ntime;
}


/* Construct an NTP time from a 64 bit representation. Obviously the */
/* caller needs to indicate which bit number the decimal point is to */
/* the left of (thus 0 = no decimal, 64 = no whole number portion). */
RvNtpTime *RvNtpTimeConstructFrom64(RvNtpTime *result, RvUint64 ntime, RvUint8 decimal)
{
    RvUint64 temp;
    RvInt shiftnum;


#if defined(RV_NULLCHECK)
    if(result == NULL) return NULL;
#endif
#if defined(RV_RANGECHECK)
    if (decimal > RvUint8Const(64)) return NULL;
#endif

    /* Shift decimal place to get a 32.32 number */
    temp = ntime;
    if(decimal != RvUint8Const(32)) {
        if(decimal < RvUint8Const(32)) {
            temp <<= RvUint8Const(32) - decimal;
        } else temp >>= decimal - RvUint8Const(32);
    }

    /* Botton 32 bits are the fraction */
    result->fraction = (RvUint32)temp;

    /* Get the top 32 bits for the seconds */
    shiftnum = 32; /* compiler workaround */
    result->secs = (RvUint32)(temp >> shiftnum);

    return result;
}

/* Chop NTP resolution. Some applications require smaller NTP */
/* numbers than 32+32 bits. Seconds chop high order bits while */
/* fractions chop low order bits. The bit numbers given are the */
/* number of bits to keep. Bit values over 32 is the same as 32. */
RvNtpTime *RvNtpTimeChop(RvNtpTime *result, const RvNtpTime *ntime, RvUint8 secbits, RvUint8 fracbits)
{
#if defined(RV_NULLCHECK)
    if((result == NULL) || (ntime == NULL)) return NULL;
#endif
#if defined(RV_RANGECHECK)
    if ((secbits + fracbits) > RvUint8Const(64)) return NULL;
#endif

    if(secbits < RvUint8Const(32)) {
        result->secs = ntime->secs & (~(RV_UINT32_MAX << secbits));
    } else result->secs = ntime->secs;
    if(fracbits < RvUint8Const(32)) {
        result->fraction = ntime->fraction & (~(RV_UINT32_MAX >> fracbits));
    } else result->fraction = ntime->fraction;
    return result;
}

/* Subtract NTP times. NTP time starts at 1900 and can not go lower */
/* than that. Note that newtime MUST be larger than oldtime since NTP */
/* time values are unsigned. */
RvNtpTime *RvNtpTimeSubtract(RvNtpTime *result, const RvNtpTime *newtime, const RvNtpTime *oldtime)
{
#if defined(RV_NULLCHECK)
    if((result == NULL) || (newtime == NULL) || (oldtime == NULL)) return NULL;
#endif

    result->secs = newtime->secs - oldtime->secs;
    result->fraction = newtime->fraction - oldtime->fraction;
    if(result->fraction > newtime->fraction)
        result->secs -= RvUint32Const(1);
    return result;
}

/* Add two NTP times. Beware that NTP time wraps after year 2036. */
RvNtpTime *RvNtpTimeAdd(RvNtpTime *result, const RvNtpTime *newtime, const RvNtpTime *oldtime)
{
#if defined(RV_NULLCHECK)
    if((result == NULL) || (newtime == NULL) || (oldtime == NULL)) return NULL;
#endif

    result->secs = newtime->secs + oldtime->secs;
    result->fraction = newtime->fraction + oldtime->fraction;
    if(result->fraction < newtime->fraction)
        result->secs += RvUint32Const(1);
    return result;
}

/* Covert NTP time to standard time structure. The two formats do not have  */
/* the exact same resolution so there can be some round-off error. The      */
/* timetype parameter indicates wether absolute or relative time is stored  */
/* in the NTP time. Absolute times are calander times that need to have the */
/* difference in epochs dealt with. The resulting time can be negative if   */
/* the NTP time is earlier than the standard time epoch.                    */
RvTime *RvNtpTimeToTime(const RvNtpTime *ntime, RvTime *t, RvBool timetype)
{
#if defined(RV_NULLCHECK)
    if((ntime == NULL) || (t == NULL)) return NULL;
#endif

    if(timetype == RV_NTPTIME_ABSOLUTE) {
        RvTimeSetSecs(t, (RvInt32)(ntime->secs - NTPDELTA));
    } else RvTimeSetSecs(t, (RvInt32)(ntime->secs));
    RvTimeSetNsecs(t, RvNtpTimeFractionToNsecs(ntime->fraction));
    return t;
}

/* Put an NTP time into a single 64 bit number. To allow for easy */
/* conversion to various bit sizes, the value may be chopped (see */
/* RvNtpChop). All resulting bits are placed into the low order */
/* bits of the 64 bit result (so the high order bits can be thrown */
/* out). The decimal place of the resulting number will be to the */
/* left of the number of fraction bits requested. Setting secbits */
/* and fracbits to 32 will not chop the number and put the decimal */
/* place to the left of the 32nd bit. */
RVCOREAPI RvUint64 RVCALLCONV RvNtpTimeTo64(const RvNtpTime *ntime, RvUint8 secbits, RvUint8 fracbits)
{
    RvUint64 result;

#if defined(RV_NULLCHECK)
    if(ntime == NULL) return RvUint64Const(0);
#endif
#if defined(RV_RANGECHECK)
    if ((secbits + fracbits) > RvUint8Const(64)) return RvUint64Const(0);
#endif

    /* Get basic 32.32 result first */
#if (RV_OS_TYPE == RV_OS_TYPE_PSOS) && (RV_OS_VERSION == RV_OS_PSOS_2_0)
    /* just to get rid of a PSOS v2.0 annoying warning */
    result = (RvUint64)ntime->fraction | ( ((RvUint64)ntime->secs << 16) << 16);
#else
    result = (RvUint64)ntime->fraction | ((RvUint64)ntime->secs << 32);
#endif

    /* Chop any excess seconds off */
    if(secbits < RvUint8Const(32)) {
        result &= RV_UINT64_MAX >> (RvUint8Const(32) - secbits);
    }

⌨️ 快捷键说明

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