📄 cmchan.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 "rvh323timer.h"
#include "cmictrl.h"
#include "cmintr.h"
#include "cmdebprn.h"
#include "cmConf.h"
#include "cmCall.h"
#include "caputils.h"
#include "cmchan.h"
#include "h245.h"
#include "cmutils.h"
#include "cmChanGetByXXX.h"
#include "transpcap.h"
#include "cmCrossReference.h"
#include "pvaltreeStackApi.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ifE(a) if(a)(a)
void deriveChannels(HCONTROL ctrl);
static void setFirstChannels(IN H245Channel* channel);
/************************************************************************
* channelFreeMemory
* purpose: Free any PVT nodes held by a channel when not necessary
* anymore. This function is called only when working without
* a properties database.
* input : hsChan - H245Channel object
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
static
int channelFreeMemory(
IN HCHAN hsChan)
{
cmElem* app=(cmElem *)emaGetInstance((EMAElement)hsChan);
HPVT hVal;
if (!app)
return RV_ERROR_UNKNOWN;
if (emaLock((EMAElement)hsChan))
{
H245Channel* channel=(H245Channel*)hsChan;
hVal = app->hVal;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.redEncID); channel->pChannelParams.data.h225Params.redEncID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->dataTypeID); channel->dataTypeID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.transCapID); channel->pChannelParams.data.h225Params.transCapID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.recvRtpAddressID); channel->pChannelParams.data.h225Params.recvRtpAddressID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.recvRtcpAddressID); channel->pChannelParams.data.h225Params.recvRtcpAddressID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.sendRtpAddressID); channel->pChannelParams.data.h225Params.sendRtpAddressID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.sendRtcpAddressID); channel->pChannelParams.data.h225Params.sendRtcpAddressID=RV_ERROR_UNKNOWN;
pvtDelete(hVal,channel->pChannelParams.data.h225Params.separateStackID); channel->pChannelParams.data.h225Params.separateStackID=RV_ERROR_UNKNOWN;
emaUnlock((EMAElement)hsChan);
}
return RV_TRUE;
}
/************************************************************************
* notifyChannelState
* purpose: Notify the application about the state of a channel
* input : channel - H245Channel object
* state - State of channel
* stateMode - State mode of channel
* output : none
* return : none
************************************************************************/
int notifyChannelState(
IN H245Channel* channel,
IN cmChannelState_e state,
IN cmChannelStateMode_e stateMode)
{
HCONTROL ctrl;
cmElem* app;
HAPP hApp;
int nesting;
if (!channel) return RV_ERROR_UNKNOWN;
if (!emaWasDeleted((EMAElement)channel))
{
ctrl=channel->hCtrl;
if (!ctrl) return RV_ERROR_UNKNOWN;
hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl(ctrl));
if (!hApp) return RV_ERROR_UNKNOWN;
app=(cmElem*)hApp;
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ENTER)
{
static char *cmChannelStateA[] = {
(char*)"cmChannelStateDialtone",
(char*)"cmChannelStateRingBack",
(char*)"cmChannelStateConnected",
(char*)"cmChannelStateDisconnected",
(char*)"cmChannelStateIdle",
(char*)"cmChannelStateOffering",
};
static char *cmChannelStateModeA[] = {
(char*)"cmChannelStateModeOn",
(char*)"cmChannelStateModeOff",
(char*)"cmChannelStateModeDisconnectedLocal",
(char*)"cmChannelStateModeDisconnectedRemote",
(char*)"cmChannelStateModeDisconnectedMasterSlaveConflict",
(char*)"cmChannelStateModeDuplex",
(char*)"cmChannelStateModeDisconnectedReasonUnknown",
(char*)"cmChannelStateModeDisconnectedReasonReopen",
(char*)"cmChannelStateModeDisconnectedReasonReservationFailure"
};
cmiCBEnter(hApp, "cmEvChannelStateChanged(haChan=0x%p, hsChan=0x%p,state=%s,stateMode=%s)",
emaGetApplicationHandle((EMAElement)channel), channel, nprn(cmChannelStateA[state]),nprn(cmChannelStateModeA[stateMode]));
}
#endif
if (state == cmChannelStateIdle)
{
/* free the default channel Ids. if needed */
setFirstChannels(channel);
}
nesting = emaPrepareForCallback((EMAElement)channel);
if (app->cmMyChannelEvent.cmEvChannelStateChanged)
{
app->cmMyChannelEvent.cmEvChannelStateChanged((HAPPCHAN)emaGetApplicationHandle((EMAElement)channel), (HCHAN)channel, state, stateMode);
}
else if (state == cmChannelStateIdle)
{
/* We automatically close the channel if application doesn't handle this callback */
cmChannelClose((HCHAN)channel);
}
emaReturnFromCallback((EMAElement)channel, nesting);
if ((state==cmChannelStateConnected) && (app->callPropertyMode==pmodeDoNotUseProperty))
{
/* Since we're not using a properties database, we can free information from the
channel when it gets to the connected state. */
channelFreeMemory((HCHAN)channel);
}
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_LEAVE)
cmiCBExit(hApp, "cmEvChannelStateChanged.");
#endif
}
return 0;
}
int
cmcCallDataTypeHandleCallback(
/* Call the data type handle callback */
IN HAPP hApp,
IN HCHAN hsChan, /* channel protocol */
IN int dataType, /* channel data type node id */
IN confDataType type
)
{
cmElem* app=(cmElem*)hApp;
HAPPCHAN haChan;
int dataTypeHandle = -1;
cmCapDataType dataTypeId = (cmCapDataType)0;
HPVT hVal = app->hVal;
int nesting;
/* See if we have to use this callback at all */
if (app->cmMyChannelEvent.cmEvChannelHandle == NULL)
return RV_TRUE;
/* Get the handle to the data type by the data's type */
switch (type)
{
case confNonStandard:
dataTypeId=cmCapNonStandard;
dataTypeHandle = pvtChild(hVal, dataType);
break;
case confNullData:
dataTypeId=(cmCapDataType)0;
dataTypeHandle = pvtChild(hVal, dataType);
break;
case confVideoData:
dataTypeId=cmCapVideo;
dataTypeHandle = pvtChild(hVal, pvtChild(hVal, dataType));
break;
case confAudioData:
dataTypeId=cmCapAudio;
dataTypeHandle = pvtChild(hVal, pvtChild(hVal, dataType));
break;
case confData:
dataTypeId=cmCapData;
dataTypeHandle = pvtChild(hVal, pvtChild(hVal, pvtChild(hVal, dataType)));
break;
}
haChan = (HAPPCHAN)emaGetApplicationHandle((EMAElement)hsChan);
cmiCBEnter(hApp, "cmEvChannelHandle(haChan=0x%p, hsChan=0x%p, handle=%d, type=%d)", haChan, hsChan, dataTypeHandle, dataTypeId);
nesting = emaPrepareForCallback((EMAElement)hsChan);
app->cmMyChannelEvent.cmEvChannelHandle(haChan, hsChan, dataTypeHandle, dataTypeId);
emaReturnFromCallback((EMAElement)hsChan, nesting);
cmiCBExit(hApp, "cmEvChannelHandle.");
return RV_TRUE;
}
int
cmcCallChannelParametersCallback(
/* Call the channel parameter callback */
IN HAPP hApp,
IN HCHAN hsChan, /* channel protocol */
IN int dataType, /* channel data type node id */
OUT confDataType* type)
{
cmElem* app=(cmElem *)hApp;
H245Channel* channel = (H245Channel *)hsChan;
char channelName[64];
RvUint32 rate=0;
confDataType _type;
HCHAN hsSameSessionH, hsAssociatedH;
HAPPCHAN haChan, haSameSessionH = NULL, haAssociatedH = NULL;
HPVT hVal=app->hVal;
int nesting;
/* if the cmEvChannelParameters callback isn't set, we don't really need anything more
than the data type of this channel */
if (app->cmMyChannelEvent.cmEvChannelParameters == NULL)
{
if (type != NULL)
*type = (confDataType)pvtGetSyntaxIndex(hVal, pvtChild(hVal, dataType));
return 0;
}
/* find out the channel's name by its data type */
strcpy(channelName, "null");
if(confGetDataTypeName(hVal, dataType, sizeof(channelName), channelName, &_type, NULL) < 0)
{
RvLogError(&app->log, (&app->log, "cmcCallChannelParametersCallback: error in confGetDataTypeName(), dataType=%d", dataType));
if (type != NULL)
*type = (confDataType)-1;
return RV_ERROR_UNKNOWN;
}
RvLogDebug(&app->log,
(&app->log, "cmcCallChannelParametersCallback: new channel with name %s", channelName));
/* -- bit rate */
if (_type == confData)
{
int nid;
__pvtGetByFieldIds(nid,hVal, dataType,
{_h245(data)
_h245(maxBitRate)
LAST_TOKEN},
NULL, (RvInt32*)&rate, NULL);
}
/* Get same session and associated channel handles */
hsAssociatedH = (HCHAN)channel->pAssociated;
if (hsAssociatedH != NULL)
haAssociatedH = (HAPPCHAN)emaGetApplicationHandle((EMAElement)hsAssociatedH);
hsSameSessionH = (HCHAN)channel->pPartner;
if (hsSameSessionH != NULL)
haSameSessionH = (HAPPCHAN)emaGetApplicationHandle((EMAElement)hsSameSessionH);
haChan = (HAPPCHAN)emaGetApplicationHandle((EMAElement)hsChan);
cmiCBEnter(hApp, "cmEvChannelParameters: haChan=0x%p, hsChan=0x%p, channelName=%s, "
"AppSes=0x%p, Ses=0x%p, AppAso=0x%p, Aso=0x%p, rate=%d.",
haChan, hsChan, channelName, haSameSessionH, hsSameSessionH, haAssociatedH, hsAssociatedH, rate);
nesting = emaPrepareForCallback((EMAElement)hsChan);
app->cmMyChannelEvent.cmEvChannelParameters(
haChan, hsChan, channelName, haSameSessionH, hsSameSessionH, haAssociatedH, hsAssociatedH, rate);
emaReturnFromCallback((EMAElement)hsChan, nesting);
cmiCBExit(hApp, "cmEvChannelParameters.");
if (type) *type = _type;
return RV_TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -