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

📄 cmctrl.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
        Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..

RADVISION Ltd. reserve the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
***********************************************************************/

#include "rvinternal.h"
#include "rvh323timer.h"
#include "cm.h"
#include "cmictrl.h"
#include "cmintr.h"
#include "cmCall.h"
#include "cmConf.h"
#include "caputils.h"
#include "cmutils.h"
#include "strutils.h"
#include "prnutils.h"
#include "cmchan.h"
#include "oidutils.h"
#include "h245.h"
#include "cmCtrlCap.h"
#include "cmCtrlMSD.h"
#include "cmCtrlRTD.h"
#include "cmCtrlMMode.h"
#include "cmCtrlRMode.h"
#include "cmCtrlMPoint.h"
#include "cmChanOperations.h"
#include "cmdebprn.h"
#include "pvaltree.h"

#ifdef __cplusplus
extern "C" {
#endif


int userInput(H245Control*ctrl, int message);


/* General __________________________________________________________________________________*/
void notifyControlState(HCALL hsCall);
int cmiReportControl(IN HCALL               hsCall,
                     IN cmControlState      state,
                     IN cmControlStateMode  stateMode)
{
    callElem*call=(callElem*)hsCall;
    cmElem* app;
    int nesting;

    app = (cmElem*)emaGetInstance((EMAElement)hsCall);
    if (app->cmMySessionEvent.cmEvCallControlStateChanged != NULL)
    {
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ENTER)
        static char *stateModes[]=
        {    (char*)"cmControlStateModeNull",(char*)""};

        static char *states[]=
        {
            (char*)"cmControlStateConnected",
            (char*)"cmControlStateConference",
            (char*)"cmControlStateTransportConnected",
            (char*)"cmControlStateTransportDisconnected",
            (char*)"cmControlStateFastStart",
            (char*)"cmControlStateFastStartComplete"
        };

        cmiCBEnter((HAPP)app,(char*)"cmEvCallControlStateChanged(haCall=0x%p,hsCall=0x%p,state=%s,stateMode=%s)",emaGetApplicationHandle((EMAElement)hsCall),hsCall,nprn(states[state]),nprn(stateModes[stateMode+1]));
#endif

        nesting=emaPrepareForCallback((EMAElement)hsCall);
        app->cmMySessionEvent.cmEvCallControlStateChanged((HAPPCALL)emaGetApplicationHandle((EMAElement)hsCall),hsCall,state,stateMode);
        emaReturnFromCallback((EMAElement)hsCall,nesting);

#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_LEAVE)
        cmiCBExit((HAPP)app,(char*)"cmEvCallControlStateChanged");
#endif
    }

    if (call->state == cmCallStateConnected)
        notifyControlState(hsCall);

    if ((app->mibEvent.h341AddControl != NULL) && ((state == cmControlStateConnected) || (state == cmControlStateFastStart)))
          app->mibEvent.h341AddControl(app->mibHandle, hsCall);

    return 0;
}


RVAPI int RVCALLCONV
cmSetSessionEventHandler(
             /* Set user callbacks functions for control session. */
             IN HAPP        hApp,
             IN     CMSESSIONEVENT  cmSessionEvent,
             IN     int     size)
{
  cmElem *app = (cmElem *)hApp;

  if (!app) return RV_ERROR_UNKNOWN;

  cmiAPIEnter((HAPP)app, "cmSetSessionEventHandler: hApp=0x%p, cmSessionEvent=0x%p, size=%d.",
     hApp, cmSessionEvent, size);

  app->dynamicPayloadNumber = 0;

  memset(&(app->cmMySessionEvent), 0, sizeof(app->cmMySessionEvent));
  memcpy(&(app->cmMySessionEvent), cmSessionEvent, (RvSize_t)RvMin((int)sizeof(app->cmMySessionEvent), size));

  cmiAPIExit((HAPP)app, "cmSetSessionEventHandler: [0].");
  return 0;
}


RVAPI int RVCALLCONV
cmGetControlEventHandler(
             /* Set user callbacks functions for control session. */
             IN HAPP        hApp,
             OUT    CMSESSIONEVENT  cmSessionEvent,
             IN     int     size)
{
  cmElem *app = (cmElem *)hApp;

  if (!app) return RV_ERROR_UNKNOWN;

  cmiAPIEnter((HAPP)app, "cmGetControlEventHandler: hApp=0x%p, cmSessionEvent=0x%p, size=%d.",
     hApp, cmSessionEvent, size);

  memset(cmSessionEvent, 0, (RvSize_t)size);
  memcpy(cmSessionEvent,&(app->cmMySessionEvent),  (RvSize_t)RvMin((int)sizeof(app->cmMySessionEvent), size));

  cmiAPIExit((HAPP)app, "cmGetControlEventHandler: [0].");
  return 0;
}


/* returns the value-tree node id of h245 configuration root node */
RVAPI
RvInt32 RVCALLCONV cmGetH245ConfigurationHandle(
                IN  HAPP             hApp)
{
  cmElem *app = (cmElem *)hApp;
  if (!app) return RV_ERROR_UNKNOWN;

  cmiAPIEnter((HAPP)app, "cmGetH245ConfigurationHandle: hApp=0x%p.", hApp);

  cmiAPIExit((HAPP)app, "cmGetH245ConfigurationHandle: [%d].", app->h245Conf);
  return app->h245Conf;
}


int
cmcReadyEvent(
          /* Check if session reached ready state and if so inform application. */
          H245Control* ctrl
          )
{
  callElem *call=(callElem *)cmiGetByControl((HCONTROL)ctrl);
  cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);

  if (!app) return RV_ERROR_UNKNOWN;
  if ((ctrl->eOutCapStatus == CapStatusAcknowledged) && (ctrl->eInCapStatus == CapStatusAcknowledged) &&
      ctrl->bIsMasterSlave && ctrl->eState==ctrlInitialized)
  {
      if ((!cmTransIsParallel(call->hsTransSession) || m_callget(call,fastStartFinished)))
      {
          ctrl->eState=ctrlConnected;
          cmiReportControl(cmiGetByControl((HCONTROL)ctrl),  cmControlStateConnected,(cmControlStateMode)0);
          if (RV_PVT_NODEID_IS_VALID(ctrl->incomingOLCs[0]))
          {
              openLogicalChannel(ctrl, ctrl->incomingOLCs[0]);
              pvtDelete(app->hVal, ctrl->incomingOLCs[0]);
              ctrl->incomingOLCs[0] = RV_PVT_INVALID_NODEID;
          }
          if (RV_PVT_NODEID_IS_VALID(ctrl->incomingOLCs[1]))
          {
              openLogicalChannel(ctrl, ctrl->incomingOLCs[1]);
              pvtDelete(app->hVal, ctrl->incomingOLCs[1]);
              ctrl->incomingOLCs[1] = RV_PVT_INVALID_NODEID;
          }
      }
  }
  return RV_TRUE;
}



void cmH245Start(HAPP hApp)
{
    cmElem *app = (cmElem *)hApp;

    /* Encode the protocol identifier that we'll use in future TCS messages */
    app->h245protocolIDLen =
        oidEncodeOID(sizeof(app->h245protocolID), app->h245protocolID, H245_PROTOCOL_IDENTIFIER);
}

void cmH245Stop(HAPP hApp)
{
    cmElem *app = (cmElem *)hApp;
    if (app);
}


void initControl(HCONTROL ctrl, int lcnOut)
{
    H245Control*ctrlE=(H245Control*)ctrl;

    memset((void *)ctrl,0,sizeof(H245Control));

    ctrlE->logicalChannelOut=lcnOut;
    ctrlE->eOutCapStatus=CapStatusReleased;
    ctrlE->eInCapStatus=CapStatusReleased;
    ctrlE->bIsMasterSlave=0;
    ctrlE->bIsMaster=0;

    ctrlE->conflictChannels=0;

    ctrlE->myTerminalLabel.mcuNumber=255;
    ctrlE->myTerminalLabel.terminalNumber=255;
    capInit(ctrlE);
    msdInit(ctrlE);
    rtdInit(ctrlE);
    ctrlE->multiPointMode=0;
    ctrlE->eState=ctrlInitialized;
    ctrlE->outRequestMode.timer = NULL;
    ctrlE->incomingOLCs[0] = RV_PVT_INVALID_NODEID;
    ctrlE->incomingOLCs[1] = RV_PVT_INVALID_NODEID;
}

void startControl(HCONTROL ctrl)
{
    H245Control*ctrlE=(H245Control*)ctrl;
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)cmiGetByControl(ctrl));
    HPVT hVal=app->hVal;
    int capNodeId, res = 0;

    if (pvtGetChild2(hVal,app->h245Conf,__h245(capabilities),__h245(manualOperation))<0 &&
        (capNodeId=(pvtGetChild2(hVal,app->h245Conf,__h245(capabilities),__h245(terminalCapabilitySet)))))
    {
        int nodeId=pvtAddRoot(hVal,app->synProtH245,0,NULL);
        int tcsNodeId=pvtAddBranch2(hVal,nodeId,__h245(request),__h245(terminalCapabilitySet));
        res = pvtSetTree(hVal,tcsNodeId,hVal,capNodeId);
        if (res >= 0)
            res = outCapTransferRequest(ctrlE, nodeId);
        pvtDelete(hVal,nodeId);
    }
    if ((res >= 0) && (pvtGetChild2(hVal,app->h245Conf,__h245(masterSlave),__h245(manualOperation))<0))
        msdDetermineRequest(ctrlE, -1, -1);
}


/************************************************************************
 * stopControl
 * purpose: Stop the H245 Control connection for a call.
 * input  : ctrl    - Control object
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
void stopControl(IN HCONTROL ctrl)
{
    H245Control*ctrlE=(H245Control*)ctrl;
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)cmiGetByControl(ctrl));
    int nodeId, message;
    HPVT hVal=app->hVal;

    /* Make sure we close all the channels */
    closeChannels(ctrl);

    /* Send an endSession message if we have to */
    if (ctrlE->eState==ctrlConnected || ctrlE->eState==ctrlConference || ctrlE->eState==ctrlInitialized)
    {
        /* Create an endSession command message */
        message=pvtAddRoot(hVal,app->synProtH245,0,NULL);
        nodeId=pvtAddBranch2(hVal,message,__h245(command), __h245(endSessionCommand) );
        pvtAddBranch(hVal,nodeId,__h245(disconnect));

        /* Send the endSession message */
        sendMessageH245(ctrl, message);

        /* Kill the created message */
        pvtDelete(app->hVal,message);

        /* Finish with the capabilities , MSD and RTD procedures */
        capEnd(ctrlE);
        msdEnd(ctrlE);
        rtdEnd(ctrlE);

        if (RV_PVT_NODEID_IS_VALID(ctrlE->incomingOLCs[0]))
        {
            pvtDelete(hVal, ctrlE->incomingOLCs[0]);
            ctrlE->incomingOLCs[0] = RV_PVT_INVALID_NODEID;
        }
        if (RV_PVT_NODEID_IS_VALID(ctrlE->incomingOLCs[1]))
        {
            pvtDelete(hVal, ctrlE->incomingOLCs[1]);
            ctrlE->incomingOLCs[1] = RV_PVT_INVALID_NODEID;
        }
        
        /* Make sure we're in the endSession state */
        ctrlE->eState=ctrlEndSession;
    }

    /* report that the control has disconnected */
    cmiReportControl(cmiGetByControl((HCONTROL)ctrl),cmControlStateTransportDisconnected,(cmControlStateMode)0);

}

controlState controlGetState(HCONTROL ctrl)
{
   H245Control*ctrlE=(H245Control*)ctrl;
   return ctrlE->eState;
}


/************************************************************************
 * endSessionCommand
 * purpose: Handle an incoming endSessionCommand message.
 *          This should stop the control of the call.
 * input  : ctrl    - Control object
 *          message - endSessionCommand message received
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int endSessionCommand(IN H245Control* ctrl, IN int message)
{
    callElem* call=(callElem*)cmiGetByControl((HCONTROL)ctrl);

    RV_UNUSED_ARG(message);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -