📄 faststart.c
字号:
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
RVAPI int RVCALLCONV
cmFastStartGet(
IN HCALL hsCall,
IN int fsChannelId,
OUT cmCapDataType* type,
OUT cmChannelDirection* direction,
OUT cmFastStartChannel* fsChannel)
{
callElem* call=(callElem*)hsCall;
int dirNodeId,paramNodeId,tempNodeId, sid;
HAPP hApp;
HPVT hVal;
if (!hsCall) return RV_ERROR_UNKNOWN;
hApp=(HAPP)emaGetInstance((EMAElement)call);
if (!hApp) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmFastStartGet: hsCall=0x%p",hsCall);
if (emaLock((EMAElement)hsCall))
{
hVal = ((cmElem *)hApp)->hVal;
/* Get the reverse part of the OLC message to determine whether it is
a receiving channel or a transmitting channel (from the viewpoint of
the remote that sent the SETUP) */
dirNodeId=pvtGetChild(hVal, fsChannelId, __h245(reverseLogicalChannelParameters),NULL);
{
/* in or bidirectional channel */
/* Get the forward parameters */
int tmpNodeId=pvtGetChild(hVal, fsChannelId,__h245(forwardLogicalChannelParameters),NULL);
if (pvtGetChild2(hVal, tmpNodeId, __h245(dataType),__h245(nullData))<0)
{ /* Forward DataType is OK */
if (dirNodeId >= 0) /* and there are reverse parameters */
{ /* bidirectional channel */
if (direction)
*direction=dirBoth;
}
else /* no reverse parameters */
{
/* in channel */
dirNodeId = tmpNodeId;
if (direction)
*direction=dirReceive;
}
}
else /* no forward DataType */
{ /* out channel */
if (direction)
*direction=dirTransmit;
}
}
/* Get the H2550 parameters of the channel */
paramNodeId = pvtGetChild2(hVal, dirNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));
sid = 0;
/* according to the dataType determine if it's an Audio or a Video
channel and set the session Id accordingly.
Note: This part needs to be enhanced for support of other types (data, fax etc.)*/
tempNodeId = pvtChild(hVal,pvtGetChild(hVal, dirNodeId, __h245(dataType),NULL));
{
static char const SID_From_Index[]={0,0,0,2,1,3,0,0,0};
int index=pvtGetSyntaxIndex(hVal,tempNodeId);
if (index>=0)
sid=SID_From_Index[index];
}
if (type)
*type=(cmCapDataType)sid;
/* set the pvt of the dataType subtree */
fsChannel->dataTypeHandle=pvtGetChild(hVal, dirNodeId, __h245(dataType),NULL);
/* Get the codec type name and fill it into the table */
{
int capNodeId;
RvPstFieldId fieldId;
/* For Data capabilities, we have to go one step further... */
capNodeId = pvtChild(hVal, pvtChild(hVal, fsChannel->dataTypeHandle));
if ((cmCapDataType)sid == cmCapData)
capNodeId = pvtChild(hVal, capNodeId);
pvtGet(hVal, capNodeId, &fieldId,NULL,NULL,NULL);
fsChannel->channelName = pstGetFieldNamePtr(pvtGetSynTree(hVal, dirNodeId),fieldId);
}
/* Get the rtcp ip address and fill that into the table */
cmVtToTA_H245(hVal,pvtGetChild(hVal,paramNodeId, __h245(mediaControlChannel), NULL) , &fsChannel->rtcp);
/* Get the rtp ip address and fill that into the table */
cmVtToTA_H245(hVal,pvtGetChild(hVal,paramNodeId, __h245(mediaChannel), NULL) , &fsChannel->rtp);
/* We have no way of knowing the channel index when we are here, so we'll just put in with -1 */
fsChannel->index = -1;
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmFastStartGet: [0]");
return 0;
}
/******************************************************************************************
* analyzeFastStartMsg
*
* Purpose: This function is called upon receipt of a setup message.
* The function checks for any fast-start channels in the message,
* decodes the data and builds it into a structure that is passed in a CallBack
* to the application, such that the application may ack some of them.
*
* Input: call - call object instance
* message - The node id to the setup message
*
* Reurned Value: Non-negative value on success
* Negative value on failure
****************************************************************************************/
int
analyzeFastStartMsg(
IN callElem* call,
IN int message)
{
cmFastStartMessage fsMessage;
int nodeId;
int nesting;
RvUint8 lcnAllocationBuff[(MAX_FASTSTART_CHANNELS+1)/sizeof(char)];
int decoded_length, buff_len, freeLoc=0;
int index=0;
int typeLoc[MAX_FS_CHANNELS+1];
int encodedOctedStrings;
cmAlternativeChannels *pAltChannel;
HPVT hVal;
HAPP hApp=(HAPP)emaGetInstance((EMAElement)call);
cmElem* app=(cmElem*)hApp;
if (!app->cmMyCallEvent.cmEvCallFastStartSetup && !app->cmMyCallEvent.cmEvCallFastStart) return RV_TRUE;
if ((call->fastStartState==fssAck) || (call->fastStartState==fssRej)) return RV_TRUE;
hVal=app->hVal;
/* Find out if we've got faststart at all in this message */
__pvtGetNodeIdByFieldIds(encodedOctedStrings,hVal,message,
{_q931(message)
_anyField
_q931(userUser)
_q931(h323_UserInformation)
_q931(h323_uu_pdu)
_q931(h323_message_body)
_anyField
_q931(fastStart)
LAST_TOKEN});
if (encodedOctedStrings<0) return RV_ERROR_UNKNOWN;
call->fastStartState=fssRequest;
/* Initialized the table to be built */
memset(&fsMessage,0,sizeof(cmFastStartMessage));
memset(typeLoc,0xff,sizeof(typeLoc));
memset(lcnAllocationBuff,0,sizeof(lcnAllocationBuff));
/* Go over the received encoded OLC message from the SETUP,
decode them for subsequent analysis */
nodeId = pvtChild(hVal, encodedOctedStrings);
while (nodeId > 0)
{
RvUint8* encodeBuffer;
/* Get a buffer to work with */
getEncodeDecodeBuffer(app->encodeBufferSize, &encodeBuffer);
if (encodeBuffer != NULL)
{
buff_len = pvtGetString(hVal, nodeId, app->encodeBufferSize, (char*)encodeBuffer);
}
else
buff_len = -1; /* Make sure we don't continue */
if (buff_len > 0)
{
/* Decode an OpenLogicalChannel faststart message */
int decodingResult;
int chanMsgId=call->fastStartNodes[index]=pvtAddRoot(hVal, app->synOLC, 0, NULL);
call->fastStartNodesCount++;
decodingResult = cmEmDecode(hVal, chanMsgId, encodeBuffer, buff_len, &decoded_length);
if (decodingResult < 0)
chanMsgId = -1;
RvH323CmPrintMessage(&app->logFastStart, "Suggested faststart channel decoded:",
hVal, chanMsgId, encodeBuffer, decoded_length, RV_TRUE);
if (decodingResult >= 0)
{
/* Make the logical channel's number as taken */
int lcn;
pvtGetChildValue(hVal, chanMsgId,__h245(forwardLogicalChannelNumber),&lcn,NULL);
setBitTrue(lcnAllocationBuff,lcn/MAX_LCN_S);
}
else
{
/* Got an error - try next fs proposal */
nodeId = pvtBrother(hVal, nodeId);
continue;
}
if (app->cmMyCallEvent.cmEvCallFastStartSetup)
{
cmFastStartChannel fsChannel;
cmCapDataType type;
cmChannelDirection direction;
int loc;
/* We now have an offered channel */
/* Go over the OLC message and analyse it */
cmFastStartGet((HCALL)call, chanMsgId, &type, &direction, &fsChannel);
/* Fill the session Id into the channel table being prepared for the user */
if (typeLoc[(int)type] == -1)
{
loc=typeLoc[(int)type] = freeLoc++; /* todo: How is freeLoc used? */
fsMessage.partnerChannels[loc].type = type;
fsMessage.partnerChannelsNum++;
}
else
loc=typeLoc[(int)type];
/* Set a pointer to the right part of the channel tables
according to the channels direction */
if (direction==dirTransmit)
pAltChannel = &(fsMessage.partnerChannels[loc].transmit);
else pAltChannel = &(fsMessage.partnerChannels[loc].receive);
/* Now fill all the data from the OLC message to the table */
if (pAltChannel->altChannelNumber < MAX_ALTERNATIVE_CHANNEL)
{
/* Give the channel an index */
fsChannel.index = index;
pAltChannel->channels[pAltChannel->altChannelNumber]=fsChannel;
/* Advance the channels counter in the table */
pAltChannel->altChannelNumber++;
}
}
}
nodeId = pvtBrother(hVal, nodeId);
index++;
if (index == app->maxFsProposed)
{
/* we were offered more channels than we have room for - ignore the rest */
/* array is maxFsProposed+1 size, must leave the last one -1 */
break;
}
}
/*If the number of fast start proposals was less then MAX_FASTSTART_CHANNELS then at least one range will be available */
call->lcnOut=get1st0BitNumber(lcnAllocationBuff, 0, MAX_FASTSTART_CHANNELS)*MAX_LCN_S;
if (app->cmMyCallEvent.cmEvCallFastStartSetup)
{
/* We call the callback with the table and supply it to the user.
The user is supposed to acke the desired channels from that callback */
cmiCBEnter(hApp,(char*)"cmEvCallFastStartSetup(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
nesting=emaPrepareForCallback((EMAElement)call);
app->cmMyCallEvent.cmEvCallFastStartSetup((HAPPCALL)emaGetApplicationHandle((EMAElement)call), (HCALL)call,&fsMessage);
emaReturnFromCallback((EMAElement)call,nesting);
cmiCBExit(hApp,(char*)"cmEvCallFastStartSetup");
}
if (!emaWasDeleted((EMAElement)call) && app->cmMyCallEvent.cmEvCallFastStart)
{
cmiCBEnter(hApp,(char*)"cmEvCallFastStart(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
nesting=emaPrepareForCallback((EMAElement)call);
app->cmMyCallEvent.cmEvCallFastStart((HAPPCALL)emaGetApplicationHandle((EMAElement)call), (HCALL)call);
emaReturnFromCallback((EMAElement)call,nesting);
cmiCBExit(hApp,(char*)"cmEvCallFastStart");
}
return RV_TRUE;
}
RVAPI int RVCALLCONV
cmFastStartChannelsAckIndex(
IN HCALL hsCall,
IN int index,
IN cmTransportAddress* rtcp,
IN cmTransportAddress* rtp)
{
int ret = -1;
int lcpNodeId;
int h2250ParametersNodeId;
int outOLCNodeId;
callElem* call=(callElem*)hsCall;
HAPP hApp;
HPVT hVal;
cmElem* app;
if (!hsCall) return RV_ERROR_UNKNOWN;
hApp=(HAPP)emaGetInstance((EMAElement)call);
if (!hApp) return RV_ERROR_UNKNOWN;
app=(cmElem*)hApp;
hVal = app->hVal;
cmiAPIEnter(hApp, "cmFastStartChannelsAckIndex: hsCall=0x%p,index = %d",hsCall,index);
if (call->fastStartNodesAckCount == app->maxFsAccepted)
{
/* array is maxFsAccepted+1 size, must leave the last one -1 */
cmiAPIExit(hApp, "cmFastStartChannelsAckIndex: out of room [-1]");
return RV_ERROR_OUTOFRANGE;
}
if (emaLock((EMAElement)hsCall))
{
/* Start build OLC for ack */
outOLCNodeId = pvtAddRoot(hVal, app->synOLC, 0, NULL);
if (outOLCNodeId >= 0)
{
call->fastStartIndexes[call->fastStartNodesAckCount] = (RvUint8) index;
call->fastStartNodesAck[call->fastStartNodesAckCount++] = outOLCNodeId;
/* Copy the OLC*/
pvtSetTree(hVal,outOLCNodeId, hVal, call->fastStartNodes[index]);
/* check the channel direction, only proposal for outgoing and bi-directional channels have reverse parameters*/
lcpNodeId=pvtGetChild(hVal, outOLCNodeId, __h245(reverseLogicalChannelParameters),NULL);
if (lcpNodeId >= 0)
{
/* For outgoing channel do: */
/* Overwrite the fwd LCN */
pvtAdd(hVal, outOLCNodeId, __h245(forwardLogicalChannelNumber),++call->lcnOut, NULL,NULL);
}
else
lcpNodeId=pvtGetChild(hVal, outOLCNodeId, __h245(forwardLogicalChannelParameters),NULL);
h2250ParametersNodeId=pvtGetChild2(hVal, lcpNodeId, __h245(multiplexParameters), __h245(h2250LogicalChannelParameters));
if (h2250ParametersNodeId>=0)
{
int tmpNodeId;
tmpNodeId = pvtAddBranch(hVal, h2250ParametersNodeId, __h245(mediaChannel));
if ((rtp != NULL) && (rtp->ip || rtp->port))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -