⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmq931.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:

        /* 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 + -