📄 cmq931.c
字号:
/* Send the ReleaseComplete message */
status = sendCallMessage(cmiGetByQ931(call),message);
/* Release the message if not needed anymore */
callReleaseMessage(cmiGetByQ931(call),cmQ931releaseComplete);
/* Change call's Q931 state to Null */
callE->callState=cs_Null;
}
return status;
}
/************************************************************************
* q931CallStatusEnquiry
* purpose: Send a Q931 STATUS ENQUIRY message
* input : call - Stack handle for the Q931 call
* message - StatusEnquiry message to send
* If -1, then message will be created
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int q931CallStatusEnquiry(IN HQ931 call, IN int message)
{
q931Elem* callE=(q931Elem*)call;
RvH323TimerCancel(cmGetTimersHandle(cmGetAHandle((HPROTOCOL)cmiGetByQ931(call))), &callE->timerSE);
callE->timerSE=RvH323TimerStart(cmGetTimersHandle(cmGetAHandle((HPROTOCOL)cmiGetByQ931(call))),q931T322Timeout,callE,callE->t322);
sendCallMessage(cmiGetByQ931(call),message);
callReleaseMessage(cmiGetByQ931(call),cmQ931statusEnquiry);
return 0;
}
int q931CallFacility(HQ931 call,int message)
{
int ret = 0;
int q931NodeId, reasonNodeId, facilityNodeId, emptyNodeId;
int reasonId;
HAPP hApp = cmGetAHandle((HPROTOCOL)cmiGetByQ931(call));
HPVT hVal;
hVal = ((cmElem*)hApp)->hVal;
if (message<0)
message=callGetMessage(cmiGetByQ931(call),cmQ931facility);
/* check if we have the Q.931 facility IE */
__pvtGetNodeIdByFieldIds(facilityNodeId,hVal,message,
{_q931(message)
_q931(facility)
_q931(facility)
LAST_TOKEN});
if (facilityNodeId < 0)
{
/* build the Q.931 facility IE */
__pvtBuildByFieldIds(facilityNodeId,hVal,message,
{_q931(message)
_q931(facility)
_q931(facility)
LAST_TOKEN},0,NULL);
if (facilityNodeId < 0)
return -1;
}
/* check if we have a reason (valid only in case of non-empty facility message) */
q931NodeId=pvtChild(hVal,pvtGetChild(hVal,message,__q931(message),NULL));
__pvtGetNodeIdByFieldIds(emptyNodeId,hVal,q931NodeId,
{_q931(userUser) _q931(h323_UserInformation)
_q931(h323_uu_pdu) _q931(h323_message_body)
_q931(empty) LAST_TOKEN});
if (emptyNodeId < 0)
{
__pvtGetNodeIdByFieldIds(reasonNodeId,hVal,q931NodeId,
{_q931(userUser) _q931(h323_UserInformation)
_q931(h323_uu_pdu) _q931(h323_message_body)
_q931(facility) _q931(reason) LAST_TOKEN});
/* if we dont have it take the reason from the parameter of the call */
if (reasonNodeId < 0)
{
cmCallGetParam(cmiGetByQ931(call), cmParamFacilityReason, 0, &reasonId, NULL);
if (reasonId >= 0)
{
/* if we have a valid reason build the necessary fields in the message */
__pvtBuildByFieldIds(reasonNodeId,hVal,q931NodeId,
{_q931(userUser) _q931(h323_UserInformation)
_q931(h323_uu_pdu) _q931(h323_message_body)
_q931(facility) _q931(reason) LAST_TOKEN}, 0, NULL);
if (reasonNodeId >= 0)
{
/* convert the reason to the proper fieldId and build it in place */
RvInt32 nameId = getParamFieldName((cmRASParam)cmParamFacilityReason)[reasonId].nameId;
if (pvtAdd(hVal, reasonNodeId, nameId, 0, NULL, NULL)<0)
pvtDelete(hVal,reasonNodeId);
}
}
}
}
ret = sendCallMessage(cmiGetByQ931(call),message);
pvtDelete(hVal, message);
callReleaseMessage(cmiGetByQ931(call),cmQ931facility);
return ret;
}
/****************************/
/* M E S S A G E S */
/****************************/
int q931SimulateSetup(HQ931 call)
{
q931Elem* callE=(q931Elem*)call;
if (callE->callState==cs_Null)
{
callE->callState=cs_Call_present;
}
return 0;
}
int q931Setup(q931Elem*callE, int message)
{
/* process the setup, even if we already sent call-proceeding or alerting on the call */
if (callE->callState==cs_Null || callE->callState==cs_Call_present ||
callE->callState==cs_Incoming_call_proceeding || callE->callState==cs_Call_received)
{
callE->callState=cs_Call_present;
cmIndicate(cmiGetByQ931((HQ931)callE),message, cmQ931setup);
}
return 0;
}
int q931CallProceeding(q931Elem*callE, int message)
{
if (callE->callState==cs_Call_initiated||
callE->callState==cs_Overlap_sending)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
callE->callState = cs_Outgoing_call_proceeding;
RvH323TimerCancel(timers, &callE->timer);
callE->timer=RvH323TimerStart(timers, q931T310Timeout, callE, callE->t310);
cmIndicate(hsCall, message, cmQ931callProceeding);
}
return 0;
}
int q931Alerting(q931Elem*callE, int message)
{
if (callE->callState==cs_Call_initiated||
callE->callState==cs_Overlap_sending||
callE->callState==cs_Outgoing_call_proceeding)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
callE->callState = cs_Call_delivered;
RvH323TimerCancel(timers, &callE->timer);
callE->timer=RvH323TimerStart(timers, q931T301Timeout, callE, callE->t301);
cmIndicate(hsCall, message, cmQ931alerting);
}
return 0;
}
int q931Connect(q931Elem*callE, int message)
{
if (callE->callState==cs_Call_initiated||
callE->callState==cs_Overlap_sending||
callE->callState==cs_Outgoing_call_proceeding||
callE->callState==cs_Call_delivered)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
callE->callState = cs_Active;
RvH323TimerCancel(timers, &callE->timer);
cmIndicate(hsCall, message, cmQ931connect);
}
return 0;
}
int q931ReleaseComplete(q931Elem*callE, int message)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
callE->callState = cs_Null;
RvH323TimerCancel(timers, &callE->timer);
RvH323TimerCancel(timers, &callE->timerSE);
cmIndicate(hsCall, message, cmQ931releaseComplete);
return 0;
}
int q931Status(q931Elem*callE, int message)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
RvH323TimerCancel(timers, &callE->timerSE);
cmIndicate(hsCall, message, cmQ931status);
return 0;
}
int q931Facility(q931Elem*callE, int message)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
cmIndicate(hsCall, message, cmQ931facility);
return 0;
}
/************************************************************************
* q931StatusEnquiry
* purpose: Handles incoming STATUS ENQUIRY message
* This should cause an automatic send of STATUS message reply
* input : callE - Stack handle for the Q931 call
* message - StatusEnquiry message received
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int q931StatusEnquiry(IN q931Elem* callE, IN int message)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
int replyMsg;
RV_UNUSED_ARG(message);
/* Create a STATUS message as a reply */
replyMsg = callGetMessage(hsCall, cmQ931status);
if (replyMsg >= 0)
{
/* Set the cause value and call state on the reply */
int tmpNodeId, tmpNodeId1;
cmElem* app = (cmElem *)cmGetAHandle((HPROTOCOL)hsCall);
HPVT hVal;
hVal = app->hVal;
__pvtGetNodeIdByFieldIds(tmpNodeId,hVal,replyMsg, {_q931(message) _anyField LAST_TOKEN});
__pvtBuildByFieldIds(tmpNodeId1, hVal, tmpNodeId,
{_q931(cause) _q931(octet4) _q931(causeValue) LAST_TOKEN}, 30, NULL);
__pvtBuildByFieldIds(tmpNodeId1, hVal, tmpNodeId,
{_q931(callState) _q931(callStateValue) LAST_TOKEN}, callE->callState, NULL);
/* Send the reply and be done with it */
sendCallMessage(hsCall, replyMsg);
callReleaseMessage(hsCall, cmQ931status);
}
return 0;
}
int q931Progress(q931Elem*callE, int message)
{
if (callE-> callState==cs_Call_initiated ||
callE->callState==cs_Overlap_sending ||
callE->callState==cs_Outgoing_call_proceeding ||
callE->callState==cs_Call_delivered )
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
RvH323TimerCancel(timers, &callE->timer);
cmIndicate(hsCall, message, cmQ931progress);
}
return 0;
}
int q931SetupAcknowledge(q931Elem*callE, int message)
{
if (callE->callState==cs_Call_initiated)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
callE->callState = cs_Overlap_sending;
RvH323TimerCancel(timers, &callE->timer);
callE->timer=RvH323TimerStart(timers, q931T304Timeout, callE, callE->t304);
cmIndicate(hsCall, message, cmQ931setupAcknowledge);
}
return 0;
}
int q931Information(q931Elem*callE, int message)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
if (callE->callState==cs_Overlap_receiving)
{
RvH323TimerPoolHandle timers = cmGetTimersHandle(cmGetAHandle((HPROTOCOL)hsCall));
emaMark((EMAElement)hsCall);
cmIndicate(hsCall, message, cmQ931information);
if (emaWasDeleted((EMAElement)hsCall))
{
emaRelease((EMAElement)hsCall);
return 0;
}
RvH323TimerCancel(timers, &callE->timer);
callE->timer=RvH323TimerStart(timers, q931T302Timeout, callE, callE->t302);
callE->callState = cs_Overlap_receiving;
emaRelease((EMAElement)hsCall);
}
if (callE->callState!=cs_Null &&
callE->callState!=cs_Call_initiated &&
callE->callState!=cs_Call_present &&
callE->callState!=cs_Overlap_receiving)
{
cmIndicate(hsCall, message, cmQ931information);
}
return 0;
}
int q931Notify(q931Elem*callE, int message)
{
if (callE->callState==cs_Active)
{
HCALL hsCall = cmiGetByQ931((HQ931)callE);
cmIndicate(hsCall, message, cmQ931notify);
}
return 0;
}
/************************************************************************
* q931DecodingFailure
* purpose: Handle incoming Q931 messages that can't be decoded
* This automatically sends back a STATUS message
* input : callE - Stack handle for the Q931 call
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int q931DecodingFailure(IN HQ931 call)
{
int message;
q931Elem* callE = (q931Elem *)call;
HCALL hsCall = cmiGetByQ931((HQ931)callE);
/* Create a STATUS message to send back */
message = callGetMessage(hsCall, cmQ931status);
if (message >= 0)
{
/* The causeValue used is 95 - Invalid message, Unspecified */
int tmpNodeId, tmpNodeId1;
cmElem* app = (cmElem *)cmGetAHandle((HPROTOCOL)hsCall);
HPVT hVal;
hVal = app->hVal;
__pvtGetNodeIdByFieldIds(tmpNodeId, hVal, message, {_q931(message) _anyField LAST_TOKEN});
__pvtBuildByFieldIds(tmpNodeId1,hVal, tmpNodeId,
{_q931(cause) _q931(octet4) _q931(causeValue) LAST_TOKEN}, 95, NULL);
__pvtBuildByFieldIds(tmpNodeId1, hVal, tmpNodeId,
{_q931(callState) _q931(callStateValue) LAST_TOKEN}, callE->callState, NULL);
/* Send the STATUS message and wrap things up */
sendCallMessage(hsCall, message);
callReleaseMessage(hsCall, cmQ931status);
}
return 0;
}
/************************************************************************
* q931ProcessMessage
* purpose: Handle incoming Q931 messages
* input : call - Stack handle for the Q931 call
* message - Node Id of the massage to handle
* This function doesn't delete the message's node Id,
* but modifies its value
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int q931ProcessMessage(IN HQ931 call, IN int message)
{
q931Elem* callE=(q931Elem*)call;
cmElem* app = (cmElem *)cmGetAHandle((HPROTOCOL)cmiGetByQ931(call));
int msgType;
msgType = pvtGetChildTagByPath(app->hVal,message,"message",1);
/*Move the message tree into call database*/
if (msgType != cmQ931setup)
message = callSetMessage(cmiGetByQ931(call),(cmCallQ931MsgType)msgType,message);
switch(msgType)
{
case cmQ931setup :q931Setup(callE,message); break;
case cmQ931callProceeding :q931CallProceeding(callE,message); break;
case cmQ931connect :q931Connect(callE,message); break;
case cmQ931alerting :q931Alerting(callE,message); break;
case cmQ931releaseComplete :q931ReleaseComplete(callE,message); break;
case cmQ931status :q931Status(callE,message); break;
case cmQ931facility :q931Facility(callE,message); break;
case cmQ931statusEnquiry :q931StatusEnquiry(callE,message); break;
case cmQ931progress :q931Progress(callE,message); break;
case cmQ931setupAck :q931SetupAcknowledge(callE,message); break;
case cmQ931information :q931Information(callE,message); break;
case cmQ931notify :q931Notify(callE,message); break;
default:
/* Nothing to do here... We don't handle these types of messages :-) */
break;
}
return RV_TRUE;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -