cmpreservation.c
来自「基于h323协议的软phone」· C语言 代码 · 共 1,152 行 · 第 1/3 页
C
1,152 行
{
/* call was already activated. big error. */
return RV_ERROR_UNKNOWN;
}
isNewCall = RV_FALSE;
/* remove the previous control */
ctrl = (H245Control *) cmiGetControl((HCALL)newCall);
if(ctrl->outCap.termNodeId >= 0)
{
pvtDelete(app->hVal, ctrl->outCap.termNodeId);
}
if(ctrl->inCap.termNodeId >= 0)
{
pvtDelete(app->hVal, ctrl->inCap.termNodeId);
}
/* remove the previous property */
if(newCall->property >= 0)
{
pvtDelete(app->hVal, newCall->property);
}
/* remove the previous session */
if(newCall->hsTransSession)
{
emaDelete((EMAElement)newCall->hsTransSession);
}
/* remove the previous channels */
nextChan = curChan = (H245Channel *) cmiGetChannelListForCall((HCALL)newCall);
while(nextChan != NULL)
{
nextChan = curChan->pNext;
emaDelete(curChan);
}
break;
}
}
if(newCall == NULL)
{
/* if no call yet, get a new call from the EMA */
newCall = (callElem *)emaAdd(app->hCalls,(void*)haCall);
if (!newCall)
{
/* no calls in EMA - exit */
return RV_ERROR_UNKNOWN;
}
}
/* copy the preserved call into the new Call */
memcpy((void*)newCall,(void*)&call,sizeof(callElem));
emaSetApplicationHandle((EMAElement) newCall, (void*) haCall);
m_callset(newCall,preservedCall,RV_TRUE);
/* now get the preserved control element */
if((length-lenDone) >= sizeof(H245Control))
memcpy((void*)&control, (void*)(buffer+lenDone), sizeof(H245Control));
else
{
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
lenDone += sizeof(H245Control);
/* rebuild the capabilities, if needed */
if(control.outCap.termNodeId >= 0)
{
if(decodeFromBuffer(app->hVal, NULL, &control.outCap.termNodeId, buffer, length, &lenDone) < 0)
{
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
}
if(control.inCap.termNodeId >= 0)
{
if(decodeFromBuffer(app->hVal, NULL, &control.inCap.termNodeId, buffer, length, &lenDone) < 0)
{
pvtDelete(app->hVal, control.outCap.termNodeId);
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
}
/* set the timers to NULL */
control.outCap.timer = NULL;
control.msd.timer = NULL;
control.roundTrip.timer = NULL;
control.outRequestMode.timer = NULL;
/* copy into the control element */
newControl = (H245Control *) cmiGetControl((HCALL)newCall);
memcpy((void*)newControl, (void*)&control, sizeof(H245Control));
/* Get the session, if needed */
if(call.hsTransSession)
{
if((length-lenDone) >= sizeof(cmTransSession))
memcpy((void*)&session, (void*)(buffer+lenDone), sizeof(cmTransSession));
else
{
pvtDelete(app->hVal, control.inCap.termNodeId);
pvtDelete(app->hVal, control.outCap.termNodeId);
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
lenDone += sizeof(cmTransSession);
}
/* decode the property, if needed*/
if(call.property >= 0)
{
if(decodeFromBuffer(app->hVal, app->hSyn, &property, buffer, length, &lenDone) < 0)
{
pvtDelete(app->hVal, control.inCap.termNodeId);
pvtDelete(app->hVal, control.outCap.termNodeId);
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
}
newCall->property = property;
{
int t303, t304, t301;
/* Get the timeout values for call setup related timeouts */
pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(connectTimeOut), NULL),NULL,NULL,&t301,NULL);
t301*=1000;
if(isNewCall)
{
pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(responseTimeOut),NULL),NULL,NULL,&t304,NULL);
t303=t304*1000;
pvtGet(app->hVal,pvtGetChild(app->hVal,app->q931Conf,__q931(t304),NULL),NULL,NULL,&t304,NULL);
t304*=1000;
/* Create the Q931 "object" of the call */
q931CallCreate((HQ931)cmiGetQ931((HCALL)newCall), t301, -1, t303, t304, t301, 100000);
}
/* See if the call has timers */
if(newCall->timer)
{
/* check the call state to see if a timer should be set */
if( (newCall->state == cmCallStateDialtone) ||
(newCall->state == cmCallStateProceeding) ||
(newCall->state == cmCallStateRingBack) ||
(newCall->state == cmCallStateOffering) ||
(newCall->state == cmCallStateOffering) ||
(newCall->state == cmCallStateTransfering) ||
(newCall->state == cmCallStateIncompleteAddress) ||
(newCall->state == cmCallStateWaitAddressAck) )
{
/* set a connect timer for disconnection */
newCall->timer = RvH323TimerStart(cmGetTimersHandle(hApp),q931T301Timeout,(void*)cmiGetQ931((HCALL)newCall),t301*1000);
}
}
}
/* add the new session to the call */
if(newCall->hsTransSession)
{
newSession = emaAdd(transGlobals->hEmaSessions, (void*)newCall);
if(!newSession)
{
pvtDelete(app->hVal, property);
pvtDelete(app->hVal, control.inCap.termNodeId);
pvtDelete(app->hVal, control.outCap.termNodeId);
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
newCall->hsTransSession = (HSTRANSSESSION) newSession;
memcpy((void*)newSession, (void*)&session, sizeof(cmTransSession));
/* set a few session parameters */
if(newSession->Q931Connection) newSession->Q931Connection = (cmTransHost*)0xffffffff;
if(newSession->annexEConnection) newSession->annexEConnection = (cmTransHost*)0xffffffff;
if(newSession->H245Connection) newSession->H245Connection = (cmTransHost*)0xffffffff;
newSession->nextPending = NULL;
newSession->prevPending = NULL;
newSession->nextSession = NULL;
newSession->prevSession = NULL;
}
/* now for the channels */
if(lenDone < length)
{
memcpy((void*)&chanArraySize, (void*)(buffer+lenDone), sizeof(int));
lenDone += sizeof(int);
/* see if this call has channels */
if(chanArraySize > 0)
{
memcpy((void*)chanPtrArray, (void*)(buffer+lenDone+sizeof(int)), chanArraySize*sizeof(H245Channel *));
lenDone += chanArraySize*sizeof(H245Channel *);
memcpy((void*)chanArray, (void*)(buffer+lenDone), chanArraySize*sizeof(H245Channel));
lenDone += chanArraySize*sizeof(H245Channel);
}
}
/* create the channel referance array */
for(i=0; i<(int)chanArraySize; i++)
{
int j;
newChannelArray[i] = (H245Channel *)emaAdd(app->hChannels, NULL);
if (newChannelArray[i])
{
memcpy((void*)newChannelArray[i], (void*)&chanArray[i], sizeof(H245Channel));
if (((newChannelArray[i]->pChannelParams.data.h225Params.redEncID < 0) || (decodeFromBuffer(app->hVal, app->h245RedEnc, &newChannelArray[i]->pChannelParams.data.h225Params.redEncID, buffer, length, &lenDone) >= 0)) &&
((newChannelArray[i]->pChannelParams.data.h225Params.transCapID < 0) || (decodeFromBuffer(app->hVal, app->h245TransCap, &newChannelArray[i]->pChannelParams.data.h225Params.transCapID, buffer, length, &lenDone) >= 0)) &&
((newChannelArray[i]->requestCloseParamID < 0) || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->requestCloseParamID, buffer, length, &lenDone) >= 0)) &&
((newChannelArray[i]->dataTypeID < 0) || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->dataTypeID, buffer, length, &lenDone) >= 0)) &&
((newChannelArray[i]->pChannelParams.data.h225Params.separateStackID < 0) || (decodeFromBuffer(app->hVal, app->h245DataType, &newChannelArray[i]->pChannelParams.data.h225Params.separateStackID, buffer, length, &lenDone) >= 0)))
{
/* all ok, skip the deleting process */
continue;
}
/* if we are here, we must delete this channel... */
pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.redEncID);
pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.transCapID);
pvtDelete(app->hVal, newChannelArray[i]->requestCloseParamID);
pvtDelete(app->hVal, newChannelArray[i]->dataTypeID);
pvtDelete(app->hVal, newChannelArray[i]->pChannelParams.data.h225Params.separateStackID);
emaDelete((EMAElement)newChannelArray[i]);
}
/* ...and all those before it... */
for(j=0; j < i; j++)
{
pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.redEncID);
pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.transCapID);
pvtDelete(app->hVal, newChannelArray[j]->requestCloseParamID);
pvtDelete(app->hVal, newChannelArray[j]->dataTypeID);
pvtDelete(app->hVal, newChannelArray[j]->pChannelParams.data.h225Params.separateStackID);
emaDelete((EMAElement)newChannelArray[j]);
}
/* ...and the call itself */
emaDelete((EMAElement)newSession);
pvtDelete(app->hVal, property);
pvtDelete(app->hVal, control.inCap.termNodeId);
pvtDelete(app->hVal, control.outCap.termNodeId);
emaDelete((EMAElement)newCall);
return RV_ERROR_UNKNOWN;
}
/* set the channel pointers to the correct chanels */
for(i=0; i<(int)chanArraySize; i++)
{
if(newChannelArray[i]->pPartner)
{
for(j=0; j<(int)chanArraySize; j++)
{
if(chanPtrArray[j] == newChannelArray[i]->pPartner)
{
newChannelArray[i]->pPartner = newChannelArray[j];
break;
}
}
if(j==(int)chanArraySize)
newChannelArray[i]->pPartner = NULL;
}
if(newChannelArray[i]->pBase)
{
for(j=0; j<(int)chanArraySize; j++)
{
if(chanPtrArray[j] == newChannelArray[i]->pBase)
{
newChannelArray[i]->pBase = newChannelArray[j];
break;
}
}
if(j==(int)chanArraySize)
newChannelArray[i]->pBase = NULL;
}
if(newChannelArray[i]->pAssociated)
{
for(j=0; j<(int)chanArraySize; j++)
{
if(chanPtrArray[j] == newChannelArray[i]->pAssociated)
{
newChannelArray[i]->pAssociated = newChannelArray[j];
break;
}
}
if(j==(int)chanArraySize)
newChannelArray[i]->pAssociated = NULL;
}
if(newChannelArray[i]->pReplacementCh)
{
for(j=0; j<(int)chanArraySize; j++)
{
if(chanPtrArray[j] == newChannelArray[i]->pReplacementCh)
{
newChannelArray[i]->pReplacementCh = newChannelArray[j];
break;
}
}
if(j==(int)chanArraySize)
newChannelArray[i]->pReplacementCh = NULL;
}
if(i==0) newChannelArray[i]->pPrev = NULL;
else newChannelArray[i]->pPrev = newChannelArray[i-1];
if(i==(int)chanArraySize) newChannelArray[i]->pNext = NULL;
else newChannelArray[i]->pNext = newChannelArray[i+1];
if(newChannelArray[i]->pTimer)
{
int timeout;
pvtGetChildValue(app->hVal, app->h245Conf, __h245(channelsTimeout), &timeout, NULL);
newChannelArray[i]->pTimer = RvH323TimerStart(cmGetTimersHandle((HAPP)app), channelTimeoutEventsHandler, (void*)&newChannelArray[i], timeout * 1000);
}
newChannelArray[i]->pRequestCloseTimer = NULL;
newChannelArray[i]->pMediaLoopTimer = NULL;
newChannelArray[i]->hCtrl = (HCONTROL)newControl;
}
if(chanArraySize > 0)
cmiSetChannelListForCall((HCALL)newCall, (HCHAN)newChannelArray[0]);
else
cmiSetChannelListForCall((HCALL)newCall, (HCHAN)NULL);
return RV_OK;
}
void delCall(cmElem * app, callElem * call)
{
/* delete the call */
H245Channel * curChan, * nextChan;
/* remove the previous property */
if(call->property >= 0)
pvtDelete(app->hVal, call->property);
/* remove the previous cat entry */
if(call->hCatCall)
catDelete(app->hCat, call->hCatCall);
/* remove the previous session */
if(call->hsTransSession)
{
cmTransSession * session = (cmTransSession *)call->hsTransSession;
if(session->hashEntry)
{
cmTransGlobals * transGlobals = (cmTransGlobals *)app->hTransport;
hashDelete(transGlobals->hHashSessions, session->hashEntry);
if(session->H245Connection)
closeHostInternal((HSTRANSHOST)session->H245Connection, RV_FALSE);
if(session->Q931Connection)
closeHostInternal((HSTRANSHOST)session->Q931Connection, RV_FALSE);
if(session->annexEConnection)
closeHostInternal((HSTRANSHOST)session->annexEConnection, RV_FALSE);
emaDelete((EMAElement)call->hsTransSession);
}
}
/* remove the previous channels */
nextChan = curChan = (H245Channel *) cmiGetChannelListForCall((HCALL)call);
while(nextChan != NULL)
{
nextChan = curChan->pNext;
emaDelete((EMAElement)curChan);
}
emaDelete((EMAElement)call);
}
RVAPI RvStatus RVCALLCONV RvH323HaDelCall(
IN HAPP hApp,
IN HAPPCALL haCall
)
{
cmElem * app = (cmElem *) hApp;
EMAElement emaElem = NULL;
callElem * call;
/* go over all the calls in the EMA */
while((emaElem = emaGetNext(app->hCalls, emaElem)) != NULL)
{
/* see if this is the call we want */
if(haCall == (HAPPCALL)emaGetApplicationHandle(emaElem))
{
call = (callElem *) emaElem;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?