/************************************************************************* 【文件名】 VoipChannel.h 【功能模块和目的】 VOIP通道类头文件 【开发者及日期】 郑石诺 2015/04/08 【版本】 V1.0.0 【版权信息】 Copyright (C)2015 河南华谊网络科技有限公司 【更改记录】 *************************************************************************/ #pragma once #include "channelresource.h" #include "OneLeg.h" #include "IpmChannel.h" #include "IMixerHost.h" #include "Mixer.h" class CDspChannel; /************************************************************************* 【类名】 CVoipChannel 【功能】 【接口说明】 VOIP通道类 【开发者及日期】 郑石诺 2015/04/08 【版本】 V1.0.0 【版权信息】 Copyright (C)2015 河南华谊网络科技有限公司 【更改记录】 *************************************************************************/ class CVoipChannel : public CChannelResource, public COneLeg, public IMixerHost { private: class IImplement { public: virtual ~IImplement(void) = 0 {} virtual void onOffered(CVoipChannel& Chan, GCPARAMEX_MAKECALL* pMakeCallEx) = 0; virtual void onAlerting(CVoipChannel& Chan, METAEVENT* pMetaEvent) = 0; virtual bool makeCall(CVoipChannel& Chan, int AccountId) = 0; virtual void getMediaAddr(CIpmChannel* pImpChan, LPTSTR Buffer) = 0; }; class CImplement4Trunk : public IImplement { void onOffered(CVoipChannel& Chan, GCPARAMEX_MAKECALL* pMakeCallEx); void onAlerting(CVoipChannel& Chan, METAEVENT* pMetaEvent); bool makeCall(CVoipChannel& Chan, int AccountId); void getMediaAddr(CIpmChannel* pImpChan, LPTSTR Buffer); private: void __constructMakeCallBody(GCPARAMEX_MAKECALL* pMakeCallEx, CVoipChannel& Chan, CIpmChannel* pImpChan, SIP_ACCOUNT* pAccount); }; class CImplement4Exten : public IImplement { void onOffered(CVoipChannel& Chan, GCPARAMEX_MAKECALL* pMakeCallEx); void onAlerting(CVoipChannel& Chan, METAEVENT* pMetaEvent); bool makeCall(CVoipChannel& Chan, int AccountId); void getMediaAddr(CIpmChannel* pImpChan, LPTSTR Buffer); private: void __constructMakeCallBody(GCPARAMEX_MAKECALL* pMakeCallEx, CIpmChannel* pImpChan); }; public: CVoipChannel(DEV_RES_CH_TYPE ChannelNo, DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo); virtual ~CVoipChannel(void); int getPeerMediaPort(void) const { return m_MediaPort; } int getPeerCodecId(void) const { return m_CodecId; } LPCTSTR getPeerConnectAddr(void) const { return m_ConnectAddr; } // 操作接口 static bool isInnerSipUser(LPCTSTR User); bool reinvite4T38(void); //////////////////////////////////////////////////////////////////////////////// //继承自CChannelResource bool open(void); void close(void); int type(void) const { return SC_XOIP; } bool isBlocked(void) const { return m_IsBlocked; } bool isFree(void) const { return (m_State == GCST_NULL && !m_IsBlocked && m_pBindIpmCh == NULL); } bool isEvenNo(void) const { return m_Id.ChanNo % 2 == 0; } LPCTSTR getStateStr(void) const; void onDevEvent(METAEVENT* pMetaEvent); //////////////////////////////////////////////////////////////////////////////// //继承自COneLeg bool offhook(bool IgnoreSession, LPCTSTR CallerNum); // 内线摘机 bool dropCall(bool IsPassive); // 挂机 bool makeCall(LPCTSTR Callee, LPCTSTR Caller, int AccountId); // 启动线路拨号 bool answer(void); // 应答呼叫 bool playSound(PlayVoiceContent* pContent); // 放音收号 bool playTone(int Type); // 播放信号音 bool playStop(void); // 停止放音 bool startRecord(RecordContent* pContent); // 开始录音 bool stopRecord(void); // 停止录音 bool monitor(COneLeg* pTalker, bool IsStop); // 监听 bool allowMonitor(COneLeg* pMonitorParty) ; // 接受监听 bool cancelMonitor(COneLeg* pMonitorParty); // 取消监听 void freeResBinded(void); // 释放绑定资源 bool reply(void); bool progress(void); bool accept(void); void onFaxEnd(bool IsSuccess, LPCTSTR Reason); CChannelResource* routeChannel(void) { return m_pBindIpmCh; } CChannelResource* resourceAttribute(void) { return this; } //////////////////////////////////////////////////////////////////////////////// //继承自IMixerHost int node(void) const { return m_pBindIpmCh == NULL ? DEVICE_NODE_NO_ANY : m_pBindIpmCh->nodeNo(); } int mixHandle(void) const { return m_pBindIpmCh == NULL ? DEV_HANDLE_INVALID :m_pBindIpmCh->handle(); } int mixType(void) const { return SC_XOIP_MIX; } int normalType(void) const { return SC_XOIP; } void onPlayEnd(LPCTSTR lpDtmf); void onRecEnd(UINT TaskId); void onToneEnd(int ToneTp); private: friend class CImplment4Trunk; friend class CImplement4Exten; bool __clearCall(int Cause); bool __getVoipAddr(LPTSTR AddrBuf); // 呼叫处理相关 bool __getExtenAddrInfo(LPCTSTR Exten, LPTSTR pContactAddr, int Len); void __constructAnswerBody(GCPARAMEX_ANSWERCALL* pAnswerCallEx); void __constructProgressBody(GCPARAMEX_CALLPROGRESS* pProgressEx); void __constructReinviteBody4T38(ISXSIP_IE_BODY_EX* pBody); void __constructReinviteBody4Hold(ISXSIP_IE_BODY_EX* pBody, bool Hold); void __getCallNumFromSipAddr(LPCTSTR Called, CString& NumBuf); bool __getCallMediaDesc(ISXSIP_IE_BODY_EX* pSdp, int CodecId = -1); bool __consultMedia(ISXSIP_IE_BODY_EX* pSdp); ReinvitePurpose __analyzeReinvite(ISXSIP_IE_BODY_SDP_EX* pSdp); // 系统事件处理接口 void __onOffered(METAEVENT* pMetaEvent); void __onAlerting(METAEVENT* pMetaEvent); void __onProgressing(void); void __onConnected(METAEVENT* pMetaEvent); void __onAnswered(void); void __onCallFinish(void); void __onDiconnected(METAEVENT* pMetaEvent); void __onTaskFail(void); void __onRecvInfo(METAEVENT* pMetaEvent); void __onRecvReinvite(METAEVENT* pMetaEvent); void __onRecvReinviteAck(METAEVENT* pMetaEvent); void __onRecvUpdate(METAEVENT* pMetaEvent); void __onRecvSubscribe(METAEVENT* pMetaEvent); void __onRecvMessage(METAEVENT* pMetaEvent); void __onRecvNotify(METAEVENT* pMetaEvent); void __onRecvRefer(METAEVENT* pMetaEvent); void __onRecvOption(METAEVENT* pMetaEvent); private: // VOIP通道既可被用作中继又可用作分机,而两种在实现上有差别, // 目前差别较小,但考虑到后期扩展这里将部分功能实现剥离出来 static CImplement4Trunk ms_Implement4Trunk; static CImplement4Exten ms_Implement4Exten; IImplement* m_pImplement; // 通道属性 DEV_RES_CALL_ID m_CallId; bool m_IsBlocked; DEV_LINE_CH_JOB_TYPE m_Job; UINT m_ExtenNo; // 通道占用资源参数 CMixer m_Mixer; CIpmChannel* m_pBindIpmCh; // SIP媒体协商参数 int m_MediaPort; int m_CodecId; CString m_ConnectAddr; };