📄 faststart.c
字号:
************************************************************************/
RVAPI int RVCALLCONV
cmCallFastStartOpenChannels(
IN HCALL hsCall,
IN int* proposed,
IN int* accepted,
IN RvBool origin)
{
callElem* call=(callElem*)hsCall;
HPVT hVal;
cmElem* app;
int i;
int ret = RV_OK;
int rtcpAddressID[MAX_FS_SESSION_ID];
int rtpAddressID[MAX_FS_SESSION_ID];
HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
if (!hApp) return RV_ERROR_UNKNOWN;
app=(cmElem*)hApp;
if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;
if ((call->fastStartState==fssAck) || (call->fastStartState==fssRej))
return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmCallFastStartOpenChannels(hsCall=0x%p)", hsCall);
if (emaLock((EMAElement)hsCall))
{
hVal = app->hVal;
memset(rtcpAddressID, 0xff, sizeof(rtcpAddressID));
memset(rtpAddressID, 0xff, sizeof(rtpAddressID));
/*Go through all proposed channels and collect RTCP addresses*/
/*One RTCP address per sessionID*/
for (i=0;proposed[i]>=0;i++)
{
int inReverseLCPNodeId,inForwardLCPNodeId;
int inH2250ParametersNodeId;
RvBool nullDataType;
int sessionID;
inReverseLCPNodeId=pvtGetChild(hVal, proposed[i], __h245(reverseLogicalChannelParameters),NULL);
inForwardLCPNodeId=pvtGetChild(hVal, proposed[i], __h245(forwardLogicalChannelParameters),NULL);
nullDataType=(pvtGetChild2(hVal, inForwardLCPNodeId, __h245(dataType),__h245(nullData))>=0);
if (inReverseLCPNodeId >= 0)
inH2250ParametersNodeId=pvtGetChild2(hVal, inReverseLCPNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));
else
inH2250ParametersNodeId=pvtGetChild2(hVal, inForwardLCPNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));
if (pvtGetChildValue(hVal, inH2250ParametersNodeId,__h245(sessionID),&sessionID, NULL)>=0)
{
if (sessionID<=MAX_FS_SESSION_ID)
{
/* We've got a session ID - find the remote's RTP and RTCP addresses for it */
if (rtcpAddressID[sessionID]<0)
{
int rtcpNodeID=pvtGetChild(hVal,inH2250ParametersNodeId,__h245(mediaControlChannel),NULL);
if (rtcpNodeID>=0)
{
rtcpAddressID[sessionID]=pvtAddRoot(hVal,app->hAddrSynH245,0,NULL);
pvtSetTree(hVal,rtcpAddressID[sessionID],hVal,rtcpNodeID);
}
}
if (rtpAddressID[sessionID]<0)
{
int rtpNodeID=pvtGetChild(hVal,inH2250ParametersNodeId,__h245(mediaChannel),NULL);
if (rtpNodeID>=0)
{
rtpAddressID[sessionID]=pvtAddRoot(hVal,app->hAddrSynH245,0,NULL);
pvtSetTree(hVal,rtpAddressID[sessionID],hVal,rtpNodeID);
}
}
}
}
}
/* Go through the list of accepted channels and open them locally */
{
RvBool controlReported = RV_FALSE;
HCONTROL control;
control = cmiGetControl((HCALL)call);
call->fastStartState = fssAck;
for (i=0;accepted[i]>=0;i++)
{
int inReverseLCPNodeId, inForwardLCPNodeId;
int inLCPNodeId;
RvBool nullDataType;
H245Channel* channel;
confDataType type = (confDataType)0;
/* Allocate the channel */
channel = allocateChannel(control);
if (!channel)
{
/* Don't continue... */
ret = RV_ERROR_OUTOFRESOURCES;
break;
}
channel->pChannelParams.data.h225Params.fastStartChannelIndex = i;
if (!controlReported)
{
/* Notify application, that the call is in cmControlStateFastStart */
cmiReportControl(hsCall,cmControlStateFastStart,(cmControlStateMode)0);
/* We only do that once, and only after we are sure we have a channel that
we'll open */
controlReported = RV_TRUE;
}
/* check the channel direction: only proposal for outgoing channels have reverse parameters*/
inReverseLCPNodeId = pvtGetChild(hVal, accepted[i], __h245(reverseLogicalChannelParameters),NULL);
inForwardLCPNodeId = pvtGetChild(hVal, accepted[i], __h245(forwardLogicalChannelParameters),NULL);
nullDataType = (pvtGetChild2(hVal, inForwardLCPNodeId, __h245(dataType),__h245(nullData))>=0);
if (nullDataType) /*Incoming channel*/
channel->bOrigin = (origin)?RV_FALSE:RV_TRUE;
else
channel->bOrigin = (origin)?RV_TRUE:RV_FALSE;
/* Check if this channel is a duplex channel */
if (inReverseLCPNodeId>=0 &&
inForwardLCPNodeId>=0 && !nullDataType)
channel->bIsDuplex=RV_TRUE;
/* Get the logical channel number */
pvtGetChildValue(hVal, accepted[i], __h245(forwardLogicalChannelNumber),&(channel->myLogicalChannelNum), NULL);
if (channel->bIsDuplex)
channel->reverseLogicalChannelNum = channel->myLogicalChannelNum;
if (inForwardLCPNodeId >= 0)
pvtGetChildValue(hVal,inForwardLCPNodeId,__h245(portNumber),&channel->remotePortNumber,NULL);
inLCPNodeId=(inReverseLCPNodeId>=0)?inReverseLCPNodeId:inForwardLCPNodeId;
if (inLCPNodeId >= 0)
{
/* Now that we're in the right parameters for this channel -
let's get down to the business of opening this channel for the application */
int inDataTypeId;
int tmpNodeId;
/* Get the dataType of this channel and store it */
inDataTypeId=pvtGetChild(hVal, inLCPNodeId,__h245(dataType),NULL);
channel->dataTypeID=pvtAddRoot(hVal,app->h245DataType,0,NULL);
pvtSetTree(hVal,channel->dataTypeID,hVal, inDataTypeId);
/* Get the session ID of this channel */
__pvtGetByFieldIds(tmpNodeId, hVal, inLCPNodeId,
{_h245(multiplexParameters) _h245(h2250LogicalChannelParameters) _h245(sessionID) LAST_TOKEN}, NULL, &channel->sessionId, NULL);
if ((channel->sessionId > 0) && (channel->sessionId <= MAX_FS_SESSION_ID))
{
int* addrNodeId;
/* Get the proposed RTP and RTCP addresses for this channel, and
insert them into the channel object */
if (rtpAddressID[channel->sessionId] >= 0)
{
if (origin) addrNodeId = &channel->pChannelParams.data.h225Params.recvRtpAddressID;
else addrNodeId = &channel->pChannelParams.data.h225Params.sendRtpAddressID;
if ((*addrNodeId) < 0) *addrNodeId = pvtAddRoot(hVal, app->hAddrSynH245, 0, NULL);
pvtSetTree(hVal, *addrNodeId, hVal, rtpAddressID[channel->sessionId]);
}
if (rtcpAddressID[channel->sessionId] >= 0)
{
if (origin) addrNodeId = &channel->pChannelParams.data.h225Params.recvRtcpAddressID;
else addrNodeId = &channel->pChannelParams.data.h225Params.sendRtcpAddressID;
if ((*addrNodeId) < 0) *addrNodeId = pvtAddRoot(hVal, app->hAddrSynH245, 0, NULL);
pvtSetTree(hVal, *addrNodeId, hVal, rtcpAddressID[channel->sessionId]);
}
}
/* Find a partner for this channel if there is one */
if (channel->bOrigin)
channel->pPartner = getInChanBySID(control, channel->sessionId);
else
channel->pPartner = getOutChanBySID(control, channel->sessionId);
if (channel->pPartner != NULL)
{
/* Link it the other way around as well. No need to lock the second
channel, since the channels are locked by their call already */
channel->pPartner->pPartner = channel;
}
/* Lock this channel - we're about to make callbacks in this place */
if(emaLock((EMAElement)channel))
{
if (app->cmMySessionEvent.cmEvCallNewChannel)
{
HAPPCALL haCall = emaGetApplicationHandle((EMAElement)call);
HAPPCHAN haChan = NULL;
int nesting;
cmiCBEnter(hApp, "cmEvCallNewChannel:%s: haCall=0x%p, hsCall=0x%p. hsChan=0x%p",
(channel->bOrigin ? "OUT" : "IN"), haCall, call, channel);
nesting = emaPrepareForCallback((EMAElement)channel);
app->cmMySessionEvent.cmEvCallNewChannel(haCall, (HCALL)call, (HCHAN)channel, &haChan);
emaSetApplicationHandle((EMAElement)channel, (void*)haChan);
emaReturnFromCallback((EMAElement)channel, nesting);
cmiCBExit(hApp, "cmEvCallNewChannel:%s: haChan=0x%p.",
(channel->bOrigin ? "OUT" : "IN"), haChan);
}
if (!emaWasDeleted((EMAElement)channel))
{
/* Update the MIB with this new channel */
if (app->mibEvent.h341AddNewLogicalChannel)
app->mibEvent.h341AddNewLogicalChannel(app->mibHandle, (HCHAN)channel);
/* Call channel parameters callback if needed */
cmcCallChannelParametersCallback((HAPP)app, (HCHAN)channel, channel->dataTypeID, &type);
}
if (!emaWasDeleted((EMAElement)channel))
{
/* Now call the dataType callback if we still have this channel */
cmcCallDataTypeHandleCallback((HAPP)app, (HCHAN)channel, channel->dataTypeID, type);
}
if (!emaWasDeleted((EMAElement)channel))
{
/* Get the session ID of this channel and the node of the parameters -
we'll need it later for RTP and RTCP addresses */
/* Find the nodeId of the logical channel parameters from the
proposed part of the call - we want to notify the application
about the remote's RTP and RTCP addresses */
int paramsNodeId;
if (!origin)
{
/* This means we're the side that should send the CONNECT - we want the
proposed nodeId */
paramsNodeId = pvtGetChild(hVal, proposed[i], __h245(reverseLogicalChannelParameters), NULL);
if (paramsNodeId < 0)
paramsNodeId = pvtGetChild(hVal, proposed[i], __h245(forwardLogicalChannelParameters), NULL);
}
else
{
/* This means we're the side that received the CONNECT. We already have the parameters
node id in inLCPNodeId. */
paramsNodeId = inLCPNodeId;
}
/* Now let's find the parameters... */
__pvtGetNodeIdByFieldIds(paramsNodeId, hVal, paramsNodeId, {_h245(multiplexParameters) _h245(h2250LogicalChannelParameters) LAST_TOKEN});
/* Notify the application about the remote's RTP and RTCP addresses */
cmcCallAddressCallbacks(app, channel, paramsNodeId, origin);
}
if (!emaWasDeleted((EMAElement)channel))
{
/* Now that we're done - notify the state of this channel is connected */
channel->eState = ChannelStateEstablished;
notifyChannelState(channel,cmChannelStateConnected,cmChannelStateModeOn);
}
/* We're done with all the callbacks for this channel - unlock it */
emaUnlock((EMAElement)channel);
}
/* If someone deleted this call, we should get out of this for loop */
if (emaWasDeleted((EMAElement)hsCall))
break;
}
}
}
/* No need for the addresses anymore - delete them */
for (i = 0; i < MAX_FS_SESSION_ID; i++)
{
if (rtcpAddressID[i] >= 0)
pvtDelete(hVal, rtcpAddressID[i]);
if (rtpAddressID[i] >= 0)
pvtDelete(hVal, rtpAddressID[i]);
}
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmCallFastStartOpenChannels: [%d]", ret);
return ret;
}
int fastStartInit(IN cmElem* app, IN int maxCalls, IN int proposed, IN int accepted)
{
RvLogSourceConstruct(RvLogGet(), &app->logFastStart, RV_LOG_LIBCODE_H323, "FASTSTART", "Fast Start Messages");
/* Allocate the buffer of fast start nodes */
/* add one to values, last in array must be -1 */
RvMemoryAlloc(NULL, (void**)&app->fastStartBuff, (RvSize_t)maxCalls*(proposed+accepted+2)*sizeof(int));
RvMemoryAlloc(NULL, (void**)&app->fastStartBuff2, (RvSize_t)maxCalls*(accepted+1)*sizeof(RvUint8));
/* Set the values in the stack's instance */
app->maxFsProposed=proposed;
app->maxFsAccepted=accepted;
return ((app->fastStartBuff != NULL)&&(app->fastStartBuff2 != NULL));
}
void fastStartEnd(IN cmElem* app)
{
if (app->fastStartBuff)
RvMemoryFree(app->fastStartBuff);
if (app->fastStartBuff2)
RvMemoryFree(app->fastStartBuff2);
RvLogSourceDestruct(RvLogGet(), &app->logFastStart);
}
void fastStartCallInit(IN callElem* call)
{
cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
int callNumber;
/* Set initial fast start values of the call */
call->fastStartState=fssNo;
call->fastStartNodesCount=0;
call->fastStartNodesAckCount=0;
call->lcnOut=0;
/* Find out the call's index: We'll use that to access it's fast start channels */
callNumber = emaGetIndex((EMAElement)call);
/* Set the pointers to the right places inside the fast start buffer */
call->fastStartNodes =
app->fastStartBuff + (callNumber * (app->maxFsProposed + app->maxFsAccepted + 2));
call->fastStartNodesAck = call->fastStartNodes + app->maxFsProposed + 1;
call->fastStartIndexes = app->fastStartBuff2 + (callNumber * (app->maxFsAccepted + 1));
/* Clear the nodes to -1 */
memset(call->fastStartNodes, 0xff, (RvSize_t)sizeof(int)*(app->maxFsProposed + app->maxFsAccepted + 2));
memset(call->fastStartIndexes, 0xff, (RvSize_t)sizeof(RvUint8)*(app->maxFsAccepted + 1));
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -