?? faststart.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 "pvaltree.h"
#include "pvaltreeStackApi.h"
#include "psyntreeStackApi.h"
#include "rvh323timer.h"
#include "msg.h"
#include "cm.h"
#include "cmictrl.h"
#include "cmdebprn.h"
#include "cmintr.h"
#include "cmConf.h"
#include "q931asn1.h"
#include "h245.h"
#include "cmutils.h"
#include "copybits.h"
#include "prnutils.h"
#include "cmCrossReference.h"
#include "cmchan.h"
#include "cmCall.h"
#include "cmChanGetByXXX.h"
#ifdef __cplusplus
extern "C" {
#endif
/*These are theoretical maxima, these numbers are used in the lcn allocation procedure and is assumed to never be changed */
/*The main assumption here is that (MAX_FASTSTART_CHANNELS+1)*MAX_LCN_S <= 64K(the number of possible LCNs)*/
#define MAX_FASTSTART_CHANNELS 511
#define MAX_LCN_S 128
/* Maximum number of session ids that fast start can handle */
#define MAX_FS_SESSION_ID 10
/********************************************************************************************
* Description of THREAD_FSLocalStorage
* This structure holds thread related information for FASTSTART
* bufferSize - The size of allocated buffer. We might need that when we'll have to realloc
* buffer - The encoding/decoding buffer
********************************************************************************************/
typedef struct
{
RvUint32 bufferSize;
RvUint8* buffer;
} THREAD_FSLocalStorage;
int cmcCallAddressCallbacks(
IN cmElem* app,
IN H245Channel* channel,
IN int h225ParamNodeId,
IN RvBool origin);
int notifyChannelState(H245Channel*channel,cmChannelState_e state, cmChannelStateMode_e stateMode);
int cmcReadyEvent (H245Control* ctrl);
static void buildLCParameters(callElem* call, int elemNodeId, cmCapDataType type, cmFastStartChannel* fsChannel)
{
int paramNodeId,nodeId;
cmElem*app=(cmElem*)emaGetInstance((EMAElement)call);
HPVT hVal;
hVal=app->hVal;
/* Build and fill the dataType either from the configuration or from the given
structure */
nodeId=pvtAddBranch(hVal,elemNodeId,__h245(dataType));
if (fsChannel->dataTypeHandle<0)
confGetDataType(hVal, app->h245Conf,fsChannel->channelName, nodeId, NULL, RV_FALSE);
else
pvtMoveTree(hVal,nodeId,fsChannel->dataTypeHandle);
paramNodeId=pvtAddBranch2(hVal,elemNodeId,__h245(multiplexParameters),__h245(h2250LogicalChannelParameters));
/* Build and set the mediaChannel subtree (rtp) */
if (fsChannel->rtp.ip || fsChannel->rtp.port)
{
nodeId=pvtAddBranch(hVal,paramNodeId,__h245(mediaChannel));
getGoodAddressForCall((HCALL)call,&fsChannel->rtp);
cmTAToVt_H245(hVal, nodeId, &fsChannel->rtp);
}
/* Build and set the mediaControlChannel subtree (rtcp) */
if (fsChannel->rtcp.ip || fsChannel->rtcp.port)
{
nodeId=pvtAddBranch(hVal,paramNodeId,__h245(mediaControlChannel));
getGoodAddressForCall((HCALL)call,&fsChannel->rtcp);
cmTAToVt_H245(hVal, nodeId, &fsChannel->rtcp);
}
/* fill in the session id according to the transalation table */
pvtAdd(hVal,paramNodeId,__h245(sessionID),type,NULL,NULL);
}
/************************************************************************
* cmFastStartBuild
* purpose: Build a single OpenLogicalChannel message for use in fast start
* proposals
* input : hsCall - Stack handle for the call
* type - DataType of the proposed channel
* direction - Direction of the proposed channel
* fsChannel - FastStart channel information
* return : Node ID of created OpenLogicalChannel on success
* Negative value on failure
************************************************************************/
RVAPI int RVCALLCONV
cmFastStartBuild(
IN HCALL hsCall,
IN cmCapDataType type,
IN cmChannelDirection direction,
IN cmFastStartChannel* fsChannel)
{
callElem* call=(callElem*)hsCall;
/*H245Control* ctrl=getControl(hsCall);*/
cmElem*app=(cmElem*)emaGetInstance((EMAElement)hsCall);
HPVT hVal;
int outElemId,openMsgId=RV_ERROR_UNKNOWN;
if (!hsCall || !app) return RV_ERROR_UNKNOWN;
hVal=app->hVal;
cmiAPIEnter((HAPP)app, "cmFastStartBuild: hsCall=0x%p",hsCall);
if (emaLock((EMAElement)hsCall))
{
/* Build a OLC message for the channel */
openMsgId = pvtAddRoot(hVal, app->synOLC, 0, NULL);
/* Build the forward logical channel subtree (should be dummy for receiving channel) */
outElemId=pvtAddBranch(hVal,openMsgId,__h245(forwardLogicalChannelParameters));
if (direction==dirBoth)
{
buildLCParameters(call, outElemId, type, fsChannel);
/* Now build the reverse logical channel subtree */
outElemId=pvtAddBranch(hVal,openMsgId,__h245(reverseLogicalChannelParameters));
}
if (direction==dirReceive)
{
pvtAddBranch2(hVal,outElemId, __h245(multiplexParameters),__h245(none));
/* Write nullData in the dataType part and dummy number as lcn */
pvtAddBranch2(hVal,outElemId,__h245(dataType),__h245(nullData));
pvtAdd(hVal,openMsgId,__h245(forwardLogicalChannelNumber),323,NULL,NULL);
/* Now get to business and build the reverse logical channel subtree */
outElemId=pvtAddBranch(hVal,openMsgId,__h245(reverseLogicalChannelParameters));
}
buildLCParameters(call, outElemId, type, fsChannel);
if (direction!=dirReceive)
{
/* allocate a logical channel number for the current channel and write it into the
appEvent message */
pvtAdd(hVal,openMsgId,__h245(forwardLogicalChannelNumber),++call->lcnOut,NULL,NULL);
}
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit((HAPP)app, "cmFastStartBuild: [%d]",openMsgId);
return openMsgId;
}
/************************************************************************
* cmCallAddFastStartMessage
* purpose: Add an OpenLogicalChannel message to the fast start proposal
* on the origin side of the call.
* input : hsCall - Stack handle for the call
* fsMessageId - Node ID of the OpenLogicalChannel to add
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
RVAPI int RVCALLCONV
cmCallAddFastStartMessage(IN HCALL hsCall, IN int fsMessageId)
{
callElem* call=(callElem*)hsCall;
HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmCallAddFastStartMessage: hsCall=0x%p",hsCall);
if (call->fastStartNodesCount == ((cmElem *)hApp)->maxFsProposed)
{
/* array is maxFsProposed+1 size, must leave the last one -1 */
cmiAPIExit(hApp, "cmCallAddFastStartMessage: no more room [-1]");
return RV_ERROR_OUTOFRANGE;
}
if (emaLock((EMAElement)hsCall))
{
if (m_callget(call,callInitiator))
{
call->fastStartNodes[call->fastStartNodesCount++]=fsMessageId;
call->fastStartState=fssRequest;
}
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmCallAddFastStartMessage: [1]");
return RV_TRUE;
}
/******************************************************************************************
* cmFastStartOpenChannels
*
* Purpose: This API function enables the caller to supply a structure with data about
* the offered logical channels for fast start procedure. The structure includes
* all offered channels, both incoming and outgoing, arranged by their type, i.e.
* Audio channels, Video channels, etc.
*
* Input: hsCall - A handle to the call whose setup message shall carry the
* fast start offer.
*
* fsMessage - A pointer to the structure containing the channels data.
*
* Reurned Value: RV_TRUE or negative value on failure.
*
****************************************************************************************/
RVAPI int RVCALLCONV
cmFastStartOpenChannels(IN HCALL hsCall, IN cmFastStartMessage* fsMessage)
{
int openMsgId,index,channelType,ret=1;
callElem* call=(callElem*)hsCall;
/*H245Control* ctrl=getControl(hsCall);*/
HAPP hApp;
HPVT hVal;
if (!hsCall || fsMessage->partnerChannelsNum<=0) return RV_ERROR_UNKNOWN;
hApp=(HAPP)emaGetInstance((EMAElement)call);
if (!hApp) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmFastStartOpenChannels: hsCall=0x%p",hsCall);
if (emaLock((EMAElement)hsCall))
{
hVal = ((cmElem *)hApp)->hVal;
/* This is the main loop that goes over the offered channls in the given structure
and build from it the sub-tree to be saved in the H245 machine and attached to the
SETUP message. The order is acccording to the channel type (Audio, Video etc.) */
for (channelType = 0; channelType< fsMessage->partnerChannelsNum ;channelType++)
{
cmAlternativeChannels* aChannel;
/* We currently handle only audio and video channels in faststart */
if ( (fsMessage->partnerChannels[channelType].type < cmCapEmpty) || (fsMessage->partnerChannels[channelType].type > cmCapData) )
continue;
aChannel=&fsMessage->partnerChannels[channelType].receive;
/* Go over the offered receive channels */
for (index=0;index<aChannel->altChannelNumber;index++)
{
/* Build logicalChannel message */
openMsgId = cmFastStartBuild(hsCall, fsMessage->partnerChannels[channelType].type, dirReceive, &aChannel->channels[index]);
/* The OLC is ready for the receive channel, encode it */
cmCallAddFastStartMessage(hsCall, openMsgId);
}
aChannel=&fsMessage->partnerChannels[channelType].transmit;
/* Now go over the offered transmit channels */
for (index=0;index<aChannel->altChannelNumber;index++)
{
/* Build logicalChannel message */
openMsgId = cmFastStartBuild(hsCall, fsMessage->partnerChannels[channelType].type, dirTransmit, &aChannel->channels[index]);
/* The OLC is ready for the receive channel, encode it */
cmCallAddFastStartMessage(hsCall, openMsgId);
}
}
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmFastStartOpenChannels: [%d]",ret);
return ret;
}
/************************************************************************
* cmFastStartGetByIndex
* purpose: Get faststart information of a single OpenLogicalChannel
* message from the faststart proposal string
* input : hsCall - Stack handle for the call
* index - Index of the faststart proposal to get (0-based)
* return : Node ID of the OpenLogicalChannel message proposal on success
* Negative value on failure
************************************************************************/
RVAPI int RVCALLCONV
cmFastStartGetByIndex(IN HCALL hsCall, IN int index)
{
int nodeId=RV_ERROR_UNKNOWN;
HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
callElem * call = (callElem*)hsCall;
if (!hApp || !hsCall) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmFastStartGetByIndex: hsCall=0x%p, initiator=%d",hsCall, m_callget(call,callInitiator));
if (emaLock((EMAElement)hsCall))
{
if (m_callget(call,callInitiator))
{
/* make sure we got an Ack */
if (call->fastStartState == fssAck)
{
/* bounds check */
if ((index >= 0) && (index < ((callElem*)hsCall)->fastStartNodesAckCount))
nodeId = call->fastStartNodesAck[index];
}
}
else
{
/* bounds check */
if ((index >= 0) && (index < ((callElem*)hsCall)->fastStartNodesCount))
nodeId = call->fastStartNodes[index];
}
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmFastStartGetByIndex: [%d]",nodeId);
return nodeId;
}
/************************************************************************
* cmFastStartGet
* purpose: Get faststart information of a single OpenLogicalChannel
* message from the faststart proposal string
* input : hsCall - Stack handle for the call
* fsChannelId - PVT node ID of the root of the faststart proposal
* of one of the channels
* output : type - DataType of the proposed channel
* direction - Direction of the proposed channel
* fsChannel - FastStart channel information
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -