📄 cmctrlcap.c
字号:
/************************************************************************
* terminalCapabilitySet
* purpose: Handle an incoming TerminalCapabilitySet message
* input : ctrl - Control object
* message - TCS.Request message node
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int terminalCapabilitySet(IN H245Control* ctrl, IN int message)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
HPVT hVal;
IncomingCapInfo* incap=&ctrl->inCap;
cmElem* app=(cmElem*)hApp;
int nodeId;
int sq=0;
hVal =app->hVal;
/* Get the parameters from the incoming cap */
pvtGetChildValue(hVal,message,__h245(sequenceNumber),&sq,NULL);
incap->seqNum=(RvUint8)sq;
nodeId = pvtGetChildByFieldId(hVal, message, __h245(protocolIdentifier), &incap->pIDLen, NULL);
if ((nodeId >= 0) && (incap->pIDLen > 0))
pvtGetString(hVal, nodeId, incap->pIDLen, incap->pID);
else
incap->pIDLen = -1;
emaMark((EMAElement)cmiGetByControl((HCONTROL)ctrl));
/*if this is TCS0 (it is TCS0 if the node have only 2 childs - sequenceNumber and
protocolIdentifier), we should save the state,change it and close channles*/
if ( pvtNumChilds(hVal, message) == 2 )
{
if ((ctrl->eState!=ctrlTransmittedSidePaused))
{
H245Channel* channel;
void* ptr=NULL;
ctrl->eLastState = ctrl->eState;
ctrl->eState = ctrlTransmittedSidePaused;
/* close every channle that was opened by the endPoint */
while((channel=getNextChan((HCONTROL)ctrl, &ptr)))
{
if (channel->bOrigin)
cmChannelDropReason((HCHAN)channel,cmCloseReasonUnknown);
}
if (app->cmMySessionEvent.cmEvCallCapabilities || app->cmMySessionEvent.cmEvCallCapabilitiesExt)
{
int nesting;
cmiCBEnter(hApp, "cmEvCallCapabilities: haCall=0x%p, hsCall=0x%p, capSet=NULL.",(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)), cmiGetByControl((HCONTROL)ctrl));
nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
ifE(app->cmMySessionEvent.cmEvCallCapabilities)((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),(HCALL)cmiGetByControl((HCONTROL)ctrl), NULL);
emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
cmiCBExit(hApp, "cmEvCallCapabilities.");
if (!emaWasDeleted((EMAElement)cmiGetByControl((HCONTROL)ctrl)) &&
app->cmMySessionEvent.cmEvCallCapabilitiesExt)
{
int nesting;
cmiCBEnter(hApp, "cmEvCallCapabilitiesExt: haCall=0x%p, hsCall=0x%p, capDesc=NULL.",(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),
cmiGetByControl((HCONTROL)ctrl));
nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
app->cmMySessionEvent.cmEvCallCapabilitiesExt((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),(HCALL)cmiGetByControl((HCONTROL)ctrl),(cmCapStruct****)NULL);
emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
cmiCBExit(hApp, "cmEvCallCapabilitiesExt.");
}
}
}
}
else
{
if (incap->termNodeId < 0)
incap->termNodeId=pvtAddRoot(hVal,NULL,0,NULL);
pvtShiftTree(hVal,incap->termNodeId,message);
ctrl->eInCapStatus = CapStatusSent;
/* Handle callbacks of capability exchange message if we have to */
if (app->cmMySessionEvent.cmEvCallCapabilities || app->cmMySessionEvent.cmEvCallCapabilitiesExt)
{
int i;
cmCapStruct capSet[capSetSize];
cmCapStruct *pcapSet[capSetSize];
void* capDesc[capDescSize];
int nesting;
for (i=0; i<capSetSize; i++) pcapSet[i] = capSet+i;
for (i=0; i<capDescSize; i++) capDesc[i] = capDesc-1;
capSetBuild(hVal, incap->termNodeId, capSetSize, pcapSet);
if (ctrl->eState == ctrlTransmittedSidePaused)
ctrl->eState = ctrl->eLastState;
if (app->cmMySessionEvent.cmEvCallCapabilities != NULL)
{
cmiCBEnter(hApp, "cmEvCallCapabilities: haCall=0x%p, hsCall=0x%p, capSet=0x%p.",(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)), cmiGetByControl((HCONTROL)ctrl), pcapSet);
nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
app->cmMySessionEvent.cmEvCallCapabilities((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),(HCALL)cmiGetByControl((HCONTROL)ctrl), pcapSet);
emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
cmiCBExit(hApp, "cmEvCallCapabilities.");
}
if (!emaWasDeleted((EMAElement)cmiGetByControl((HCONTROL)ctrl)) &&
app->cmMySessionEvent.cmEvCallCapabilitiesExt)
{
int nesting;
capDescBuild(hVal, incap->termNodeId, pcapSet, capDescSize, capDesc);
cmiCBEnter(hApp, "cmEvCallCapabilitiesExt: haCall=0x%p, hsCall=0x%p, capDesc=0x%p.",(HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),
cmiGetByControl((HCONTROL)ctrl), capDesc);
nesting=emaPrepareForCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl));
app->cmMySessionEvent.cmEvCallCapabilitiesExt((HAPPCALL)emaGetApplicationHandle((EMAElement)cmiGetByControl((HCONTROL)ctrl)),(HCALL)cmiGetByControl((HCONTROL)ctrl),(cmCapStruct****)capDesc);
emaReturnFromCallback((EMAElement)cmiGetByControl((HCONTROL)ctrl),nesting);
cmiCBExit(hApp, "cmEvCallCapabilitiesExt.");
}
}
}
if ( (!emaWasDeleted((EMAElement)cmiGetByControl((HCONTROL)ctrl))) &&
(!incap->manualResponse) )
{
RvLogInfo(&app->log, (&app->log, "Invoking automatic TCS response %d",incap->manualResponse));
inCapTransferRequest(ctrl);
}
emaRelease((EMAElement)cmiGetByControl((HCONTROL)ctrl));
return RV_TRUE;
}
RVAPI int RVCALLCONV
cmCallCapabilitiesAck(
IN HCALL hsCall)
{
HAPP hApp=NULL;
H245Control* ctrl=NULL;
IncomingCapInfo* incap=NULL;
int ret;
RvBool ok = RV_TRUE;
/* check validity of data */
if (!hsCall) ok = RV_FALSE;
if (ok)
{
hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
if (!hApp) ok = RV_FALSE;
}
cmiAPIEnter(hApp, "cmCallCapabilitiesAck: hsCall=0x%p.", hsCall);
if (ok)
{
ctrl=(H245Control*)cmiGetControl(hsCall);
if (!ctrl) ok = RV_FALSE;
}
if (ok)
{
incap=&ctrl->inCap;
if (!incap) ok = RV_FALSE;
}
/* check if we are in manual response, otherwise this API is forbidden */
if (ok)
{
if (!incap->manualResponse) ok = RV_FALSE;
}
/* send the TCS Ack */
if (ok)
{
if (emaLock((EMAElement)hsCall))
{
emaMark((EMAElement)cmiGetByControl((HCONTROL)ctrl));
inCapTransferRequest(ctrl);
emaRelease((EMAElement)cmiGetByControl((HCONTROL)ctrl));
emaUnlock((EMAElement)hsCall);
}
}
if (ok)
ret = 1;
else
ret = RV_ERROR_UNKNOWN;
cmiAPIExit(hApp, "cmCallCapabilitiesAck: [%d].", ret);
return ret;
}
void inCapTransferRequest(H245Control* ctrl)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)cmiGetByControl((HCONTROL)ctrl));
HPVT hVal;
IncomingCapInfo* incap=&ctrl->inCap;
int res;
int nodeId;
int iSq = incap->seqNum;
hVal = ((cmElem *)hApp)->hVal;
nodeId = pvtAddRoot(hVal,((cmElem*)hApp)->synProtH245,0,NULL);
__pvtBuildByFieldIds(res,hVal,nodeId,{_h245(response) _h245(terminalCapabilitySetAck) _h245(sequenceNumber) LAST_TOKEN},iSq,NULL);
res = sendMessageH245((HCONTROL)ctrl, nodeId);
pvtDelete(hVal,nodeId);
if (res >= 0)
{
ctrl->eInCapStatus = CapStatusAcknowledged;
cmcReadyEvent(ctrl);
}
}
/************************************************************************
* terminalCapabilitySetRelease
* purpose: Handle an incoming TerminalCapabilitySetRelease message
* input : ctrl - Control object
* message - TCS.Release message node
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int terminalCapabilitySetRelease(IN H245Control* ctrl, IN int message)
{
if (message);
ctrl->eInCapStatus = CapStatusReleased;
return RV_TRUE;
}
RVAPI int RVCALLCONV /* RV_TRUE or RV_ERROR_UNKNOWN */
cmCallSendCapability(
/* Send terminal capability set tree to remote terminal */
/* Note: cap tree is not deleted! */
IN HCALL hsCall,
IN int termCapSet /* local terminal capabiliy set Id */
)
{
HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
H245Control* ctrl=(H245Control*)cmiGetControl(hsCall);
int message;
int ret=RV_TRUE;
if (!hsCall || !hApp) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmCallSendCapability: hsCall=0x%p, capSet=%d.", hsCall, termCapSet);
if (emaLock((EMAElement)hsCall))
{
HPVT hVal = ((cmElem *)hApp)->hVal;
message=pvtAddRoot(hVal,((cmElem*)hApp)->synProtH245,0,NULL);
ret=pvtSetTree(hVal, pvtAddBranch2(hVal, message, __h245(request), __h245(terminalCapabilitySet)), hVal, termCapSet);
if (ret >= 0)
ret = outCapTransferRequest(ctrl, message);
pvtDelete(hVal,message);
emaUnlock((EMAElement)hsCall);
}
cmiAPIExit(hApp, "cmCallSendCapability: [%d].", ret);
return ret;
}
RVAPI int RVCALLCONV /* new terminalCapabilitySet node id. */
cmCallCapabilitiesBuild(
/* Build terminalCapabilitySet value tree including the capability set
and capability descriptors. */
IN HCALL hsCall,
IN cmCapStruct* capSet[],
IN cmCapStruct*** capDesc[]
)
{
int rootId=-1;
HAPP hApp=(HAPP)emaGetInstance((EMAElement)hsCall);
if (!hApp || !hsCall || !capSet || !capDesc) return RV_ERROR_UNKNOWN;
cmiAPIEnter(hApp, "cmCallCapabilitiesBuild: hsCall=0x%p, capSet=0x%p, capDesc=0x%p.", hsCall, capSet, capDesc);
if (emaLock((EMAElement)hsCall))
{
HPVT hVal = ((cmElem *)hApp)->hVal;
if ((rootId=pvtAddRootByPath(hVal, ((cmElem*)hApp)->synProtH245, (char*)"request.terminalCapabilitySet", 0, NULL)) <0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -