📄 cmrasinit.c
字号:
case cmiAutoRasEvCallDropForced:
rasCallDrop(call);
break;
case cmiAutoRasEvCallDropped:
callStopOK(call);
break;
case cmiAutoRasEvPrepareIRR:
{
int requestId, responseId, perCallInfoId, nodeId;
requestId = pvtChild(hVal, cmiRASGetRequest(hsRas));
responseId = pvtChild(hVal, cmiRASGetResponse(hsRas));
__pvtBuildByFieldIds(perCallInfoId, hVal, responseId, {_q931(perCallInfo) _anyField LAST_TOKEN}, 0, NULL);
pvtAdd(hVal, perCallInfoId, __q931(callReferenceValue), call->rascrv,NULL,NULL);
pvtAdd(hVal,perCallInfoId,__q931(callIdentifier),16,(char*)call->callId,NULL);
pvtAdd(hVal,perCallInfoId,__q931(conferenceID),16,(char*)call->cId,NULL);
nodeId=pvtAddBranch(hVal,perCallInfoId,__q931(callSignaling));
pvtAddBranch(hVal,perCallInfoId,__q931(h245));
pvtAddBranch(hVal,perCallInfoId,__q931(substituteConfIDs));
pvtAdd(hVal,perCallInfoId,__q931(originator),(RvInt32)m_callget(call,callInitiator),NULL,NULL);
pvtAdd(hVal,perCallInfoId,__q931(bandWidth),call->rate/100,NULL,NULL);
pvtSetTree(hVal,pvtAddBranch(hVal,perCallInfoId,__q931(callType)),
hVal,pvtGetChild(hVal,requestId,__q931(callType),NULL));
pvtSetTree(hVal,pvtAddBranch(hVal,perCallInfoId,__q931(callModel)),
hVal,pvtGetChild(hVal,responseId,__q931(callModel),NULL));
if (m_callget(call,callInitiator))
{
pvtSetTree(hVal,pvtAddBranch(hVal,nodeId,__q931(sendAddress)),
hVal,pvtGetChild(hVal,responseId,__q931(destCallSignalAddress),NULL));
pvtSetTree(hVal,pvtAddBranch(hVal,nodeId,__q931(recvAddress)),
hVal,pvtGetChild(hVal,responseId,__q931(srcCallSignalAddress),NULL));
}
else
{
pvtSetTree(hVal,pvtAddBranch(hVal,nodeId,__q931(sendAddress)),
hVal,pvtGetChild(hVal,responseId,__q931(srcCallSignalAddress),NULL));
pvtSetTree(hVal,pvtAddBranch(hVal,nodeId,__q931(recvAddress)),
hVal,pvtGetChild(hVal,responseId,__q931(destCallSignalAddress),NULL));
}
break;
}
}
return 0;
}
/************************************************************************
* sendRasMessage
* purpose: Callback function called when an outgoing RAS message should
* be sent.
* input : hApp - Stack's instance handle
* chanType - Type of channel to send through
* (for now, always through unicast)
* destAddress - Address to send the message to
* messageBuf - The message buffer to send
* messageLength - The length of the message in bytes
* output : none
* return : If an error occurs, the function returns a negative value.
* If no error occurs, the function returns a non-negative value.
************************************************************************/
static RvStatus RVCALLCONV sendRasMessage(
IN HAPP hApp,
IN rasChanType chanType,
IN cmRASTransport* destAddress,
IN RvUint8* messageBuf,
IN RvSize_t messageLength)
{
cmElem* app;
RvSocket* socket;
RvAddress dest;
RvStatus ret;
RvSize_t sent = 0;
app = (cmElem *)hApp;
if (chanType == rasChanUnicast)
socket = &app->rasUnicastConnection.socket;
else
socket = &app->rasMulticastConnection.socket;
RvAddressConstructIpv4(&dest, destAddress->ip, destAddress->port);
ret = RvSocketSendBuffer(socket, messageBuf, messageLength, &dest, &sent);
if ((ret != RV_OK) || (messageLength != sent))
{
/* ToDo: keep buffer for re-send? */
return RV_ERROR_UNKNOWN;
}
return ret;
}
/********************************************************************************************
* RvRasSelectCb
*
* purpose : Callback that is executed when an event occurs on a file descriptor
* input : selectEngine - Events engine of this fd
* fd - File descriptor that this event occured on
* selectEvent - Event that happened
* error - TRUE if an error occured
* output : None
* return : None
********************************************************************************************/
void RvRasSelectCb(
IN RvSelectEngine* selectEngine,
IN RvSelectFd* fd,
IN RvSelectEvents selectEvent,
IN RvBool error)
{
RvH323Connection * connection = RV_GET_STRUCT(RvH323Connection, fd, fd);
cmElem * app = (cmElem *) connection->context;
RvStatus res;
rasChanType chanType = (rasChanType) -1;
RV_UNUSED_ARG(selectEngine);
if(connection->type == RvH323ConnectionRasUnicast)
chanType = rasChanUnicast;
else if(connection->type == RvH323ConnectionRasMulticast)
chanType = rasChanMulticast;
else
error = RV_TRUE;
if (error)
{
/* ToDo: Destroy stuff? */
rasStop(app);
return;
}
switch(selectEvent)
{
case(RvSelectRead):
{
RvUint8 * buffer;
RvSize_t bytesReceived;
RvAddress remoteAddress;
getEncodeDecodeBuffer(app->encodeBufferSize, &buffer);
res = RvSocketReceiveBuffer(&connection->socket, buffer, (RvSize_t)app->encodeBufferSize, &bytesReceived, &remoteAddress);
if(res == RV_OK)
{
cmRASTransport srcAddress;
RvH323CoreToCmAddress(&remoteAddress, &srcAddress);
cmCallPreCallBack((HAPP)app);
cmiRASReceiveMessage(app->rasManager, chanType, &srcAddress, buffer, bytesReceived);
}
break;
}
default:
break;
}
}
/************************************************************************
*
* Public functions
*
************************************************************************/
/************************************************************************
* rasInit
* purpose: Initialize the RAS module and all the network related with
* RAS.
* input : app - Stack handle
* output : none
* return : Non negative value on success
* Negative value on failure
************************************************************************/
int rasInit(IN cmElem* app)
{
RvInt32 inTx, outTx;
RvInt32 maxCalls = 1;
RvInt32 maxBuffSize = 2048;
/* Make sure we can check these handles later on for validity */
app->rasMulticastConnection.type = RvH323ConnectionNone;
app->rasUnicastConnection.type = RvH323ConnectionNone;
app->rasAddessID = -1;
/* Find out the number of calls - we might need that to calculate the number
of transactions to support */
if (ciGetValue(app->hCfg, "system.maxCalls", NULL, &maxCalls) < 0)
if (ciGetValue(app->hCfg,"Q931.maxCalls",NULL, &maxCalls) < 0)
maxCalls = 20;
/* Check some of the configuration parameters related with RAS */
/* - manual RAS */
app->manualRAS = (pvtGetChild(app->hVal, app->rasConf, __q931(manualRAS), NULL) >= 0);
/* - gatekeeper */
app->gatekeeper = (pvtGetChild(app->hVal, app->rasConf, __q931(gatekeeper), NULL) >= 0);
/* Estimate the number of transactions by the number of calls */
if (app->gatekeeper)
{
outTx = maxCalls;
inTx = maxCalls * 2 + 10;
}
else
{
outTx = maxCalls + 10;
inTx = maxCalls;
}
{
/* Calculate the true value of incoming transactions - this is done by checking
the amount of incoming transactions per second and multiplying that with the
timeout necessary to support */
int timeout = 4;
int maxRetries = 3;
ciGetValue(app->hCfg, "RAS.responseTimeOut",NULL, &timeout);
ciGetValue(app->hCfg, "RAS.maxRetries",NULL, &maxRetries);
if (maxRetries <= 0)
{
RvLogExcep(&app->log,
(&app->log, "Invalid number of RAS.maxRetries in Stack configuration: %d. using 3.", maxRetries));
maxRetries = 3;
}
timeout *= maxRetries;
if (timeout == 0) timeout = 1;
inTx = inTx * timeout + 1;
}
/* Check if we've got explicit number of transactions supported in the configuration */
ciGetValue(app->hCfg, "system.maxRasOutTransactions", NULL, &outTx);
ciGetValue(app->hCfg, "system.maxRasInTransactions", NULL, &inTx);
ciGetValue(app->hCfg, "system.allocations.maxBuffSize", NULL, &maxBuffSize);
/* Initialize the RAS module */
app->rasManager =
cmiRASInitialize((HAPP)app,
app->hCat,
app->hVal,
app->rasConf,
(RvUint32)inTx,
(RvUint32)outTx,
(RvUint32)maxBuffSize,
app->gatekeeper);
if (app->rasManager == NULL)
return RV_ERROR_OUTOFRESOURCES;
/* Initialize automatic RAS if we have to */
if (!app->manualRAS)
{
app->hAutoRas = cmiAutoRASInit((HAPP)app,
app->hTimers,
app->hVal,
app->rasConf,
handleAutoRasEvent);
if (app->hAutoRas == NULL)
return RV_ERROR_OUTOFRESOURCES;
}
cmiRASSetSendEventHandler(app->rasManager, sendRasMessage);
cmiRASSetNewCallEventHandler((HAPP)app, cmEvRASNewCall);
return 0;
}
/************************************************************************
* rasStart
* purpose: Start the RAS module and all the network related with
* RAS.
* input : app - Stack handle
* output : none
* return : Non negative value on success
* Negative value on failure
************************************************************************/
int rasStart(IN cmElem* app)
{
RvStatus res;
int nodeId, multicastPort, udpPort;
RvAddress rasUnicastAddress;
RvInt32 paramLength;
RvRandom randomValue;
/* Find out the port the RAS is working with - we can work without one... */
nodeId = pvtGetChild(app->hVal, app->rasConf, __q931(rasPort), NULL);
udpPort = 0;
if (nodeId >= 0)
pvtGet(app->hVal, nodeId, NULL, NULL, &udpPort, NULL);
/* Set the address for unicast messages */
RvAddressConstructIpv4(&rasUnicastAddress, app->localIPAddress, (RvUint16)udpPort);
/* Open the unicast address for listening */
app->rasUnicastConnection.type = RvH323ConnectionRasUnicast;
app->rasUnicastConnection.context = app;
res = RvSocketConstruct(&app->rasUnicastConnection.socket, RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp);
if (res != RV_OK)
{
/* User wanted a RAS port to listen to, but it seems the port is a little bit taken... */
RvAddressDestruct(&rasUnicastAddress);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -