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

📄 cmcallcid.c

📁 基于h323协议的软phone
💻 C
字号:
/***********************************************************************
        Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..

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

#include "rvinternal.h"
#include "rvstdio.h"
#include "rvmemory.h"
#include "rvtimestamp.h"
#include "rvlock.h"
#include "cmcallcid.h"

#ifdef __cplusplus
extern "C" {
#endif

#if defined(RV_DEBUG)
#define RV_CALLCID_DEBUG
#endif


#define RV_H323_UNIQUE_ID_CLOCKSEQ_SIZE RvUint16Const(16384) /* 16384 - '0100000000000000b' */

typedef struct
{
#ifdef RV_CALLCID_DEBUG
    RvUint      lastCid[16]; /* Last CID value that was generated */
#endif
    RvUint16    clockSequence; /* Monotone clock sequence for the GUIDs */
    RvInt64     lastTimestamp; /* The last timestamp used */
    RvLock      lock; /* Lock protecting the clock sequence */
    RvUint8     randomNode[6]; /* Node field of a GUID (set to a random value) */
} RvH323UniqueIdGenerator;







/************************************************************************
 *
 *                          Public functions
 *
 ************************************************************************/

/************************************************************************
 * RvH323UniqueIdGeneratorConstruct
 * purpose: Create a globally unique identifier generator. This is needed
 *          to create call identifiers and conference identifiers in H.323
 *          calls.
 * input  : randomGenerator - Random numbers generator
 * output : none
 * return : pointer to GUID generator on success, NULL on failure
 ************************************************************************/
RvH323UniqueIdGeneratorHandle RvH323UniqueIdGeneratorConstruct(IN RvRandomGenerator *randomGenerator)
{
    RvH323UniqueIdGenerator* guidGen;
    RvStatus res;
    RvRandom randomValue;
    int i;

    res = RvMemoryAlloc(NULL, (void**)&guidGen, sizeof(RvH323UniqueIdGenerator));
    if (res != RV_OK)
        return NULL;

    memset(guidGen, 0, sizeof(RvH323UniqueIdGenerator));
    RvRandomGeneratorGetValue(randomGenerator, &randomValue);
    guidGen->clockSequence = (RvUint16)(randomValue % RV_H323_UNIQUE_ID_CLOCKSEQ_SIZE);
    guidGen->lastTimestamp = RvTimestampGet();

    /* Generate a random value for the node field */
    for (i = 0; i < 6; i++)
    {
        RvRandomGeneratorGetValue(randomGenerator, &randomValue);
        guidGen->randomNode[i] = (RvUint8)randomValue;
    }
    guidGen->randomNode[5] |= 0x01; /* Indicate a random generated value and not a MAC address */

    res = RvLockConstruct(&guidGen->lock);
    if (res != RV_OK)
    {
        RvMemoryFree(guidGen);
        return NULL;
    }

    return (RvH323UniqueIdGeneratorHandle)guidGen;
}


/************************************************************************
 * RvH323UniqueIdGeneratorDestruct
 * purpose: Delete a globally unique identifier generator.
 * input  : uidGenerator    - GUID generator
 * output : none
 * return : RV_OK on success, other on failure
 ************************************************************************/
RvStatus RvH323UniqueIdGeneratorDestruct(IN RvH323UniqueIdGeneratorHandle uidGenerator)
{
    RvH323UniqueIdGenerator* guidGen = (RvH323UniqueIdGenerator *)uidGenerator;

    RvLockDestruct(&guidGen->lock);
    return RvMemoryFree(guidGen);
}


/************************************************************************
 * RvH323UniqueIdGeneratorGet
 * purpose: Delete a globally unique identifier generator.
 * input  : uidGenerator    - GUID generator
 * output : guid            - The generated globally unique ID.
 *                            This string must be with at least 16 characters
 * return : RV_OK on success, other on failure
 ************************************************************************/
RvStatus RvH323UniqueIdGeneratorGet(
    IN  RvH323UniqueIdGeneratorHandle   uidGenerator,
    OUT RvUint8*                        guid)
{
    /* The GUID structure:
     * 0-3      low field of the timestamp
     * 4-5      middle field of the timestamp
     * 6-7      high field of the timestamp multiplexed with the version number
     * 8        high field of the clock sequence multiplexed with the variant
     * 9        low field of the clock sequence
     * 10-15    spatially unique node identifier (MAC)
     */
    RvH323UniqueIdGenerator* guidGen = (RvH323UniqueIdGenerator *)uidGenerator;
    RvInt64 timestamp;

    /* Put the timestamp in */
    timestamp = RvTimestampGet();
    guid[0] = (RvUint8)timestamp;
    guid[1] = (RvUint8)(timestamp >> 8);
    guid[2] = (RvUint8)(timestamp >> 16);
    guid[3] = (RvUint8)(timestamp >> 24);
#if (RV_OS_TYPE == RV_OS_TYPE_PSOS) && (RV_OS_VERSION == RV_OS_PSOS_2_0)
    /* just to get rid of PSOS v2.0 annoying warnings */
    /* (partition to 16-chunks shifts for speed) */
    guid[4] = (RvUint8)((timestamp >> 16) >> 16);
    guid[5] = (RvUint8)((timestamp >> 24) >> 16);
    guid[6] = (RvUint8)((timestamp >> 24) >> 24);
    guid[7] = (RvUint8)( (((timestamp >> 16) >> 16) >>16) & RvUint64Const(0x0f)); /* Remove 4 bits for the version number */
#else
    guid[4] = (RvUint8)(timestamp >> 32);
    guid[5] = (RvUint8)(timestamp >> 40);
    guid[6] = (RvUint8)(timestamp >> 48);
    guid[7] = (RvUint8)((timestamp >> 56) & RvUint64Const(0x0f)); /* Remove 4 bits for the version number */
#endif

    /* Put the version number in the 8th byte */
    guid[7] |= 0x10; /* '0001' in binary for the msb of this byte */

    /* Let's see if we have to change the clock sequence */
    RvLockGet(&guidGen->lock);
    if (timestamp == guidGen->lastTimestamp)
    {
        /* Change the clock sequence */
        guidGen->clockSequence++;
        guidGen->clockSequence %= RV_H323_UNIQUE_ID_CLOCKSEQ_SIZE;
    }
    guid[8] = (RvUint8)(guidGen->clockSequence >> 8); /* set clock_seq_hi */
    guid[9] = (RvUint8)(guidGen->clockSequence); /* set clock_seq_low to the 8 LSBs*/
    RvLockRelease(&guidGen->lock);

    /* Set the variant field to DCE */
    guid[8] &= 0xbf; /* Set 2 MSBs to '10b' */

    /* Set the MAC address to default value */
    memcpy(&guid[10], guidGen->randomNode, sizeof(guidGen->randomNode));

#ifdef RV_CALLCID_DEBUG
    /* Check to see if the last CID generated has the same value */
    RvLockGet(&guidGen->lock);
    if (memcmp(guidGen->lastCid, guid, sizeof(guidGen->lastCid)) == 0)
    {
        RvFprintf(stderr, "identical cids were generated!!!\n");
        return RV_ERROR_UNKNOWN;
    }
    memcpy(guidGen->lastCid, guid, sizeof(guidGen->lastCid));
    RvLockRelease(&guidGen->lock);
#endif /* RV_CALLCID_DEBUG */

    return RV_OK;
}




#ifdef __cplusplus
}
#endif



⌨️ 快捷键说明

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