| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494 |
- #include "StdAfx.h"
- #include "VoipChannel.h"
- #include "ControlShell.h"
- #include "Config.h"
- #include "MC.h"
- #include "ProxyShell.h"
- #include "ProxyExten.h"
- #include "IpmChannel.h"
- #include "DspChannel.h"
- #include "SessionShell.h"
- CVoipChannel::CImplement4Trunk CVoipChannel::ms_Implement4Trunk;
- CVoipChannel::CImplement4Exten CVoipChannel::ms_Implement4Exten;
- /*****************************************************************
- **【函数名称】 __constructMakeCallBody
- **【函数功能】 构造呼叫SIP协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Trunk::__constructMakeCallBody( GCPARAMEX_MAKECALL* pMakeCallEx, CVoipChannel& Chan, CIpmChannel* pImpChan, SIP_ACCOUNT* pAccount )
- {
- ASSERT(pImpChan != NULL);
- int nIndex;
- pMakeCallEx->Protocol = eGCPro_SIP;
- #pragma region To,From,contact,Auth
- pMakeCallEx->u.SIPInviteExReq.To.Valid = 1;
- pMakeCallEx->u.SIPInviteExReq.From.Valid = 1;
- ISXSIP_IE_ADDR* pMakeCallTo = &pMakeCallEx->u.SIPInviteExReq.To.Addr;
- ISXSIP_IE_ADDR* pMakeCallFrom = &pMakeCallEx->u.SIPInviteExReq.From.Addr;
- //TO域
- pMakeCallTo->Valid = 1;
- pMakeCallTo->AddType= ISXSIP_ADDTYPE_URL;
- pMakeCallTo->u.AddrUrl.PortNum = pAccount->ProxyPort;
- pMakeCallTo->u.AddrUrl.Ttl = 0xFFFF;
- pMakeCallTo->u.AddrUrl.LrType = 0xFF;
- pMakeCallTo->u.AddrUrl.MethodType = 0xFF;
- lstrcpy(pMakeCallTo->u.AddrUrl.User, Chan.m_CalleeNum);
- lstrcpy(pMakeCallTo->u.AddrUrl.Host, pAccount->Proxy);
- //FROM域
- pMakeCallFrom->Valid = 1;
- pMakeCallFrom->AddType = ISXSIP_ADDTYPE_URL;
- pMakeCallFrom->u.AddrUrl.PortNum = 0xFFFF;
- pMakeCallFrom->u.AddrUrl.Ttl = 0xFFFF;
- pMakeCallFrom->u.AddrUrl.LrType = 0xFF;
- pMakeCallFrom->u.AddrUrl.MethodType = 0xFF;
- lstrcpy(pMakeCallFrom->u.AddrUrl.User, Chan.m_CallerNum);
- lstrcpy(pMakeCallFrom->u.AddrUrl.Host, pAccount->Proxy);
- // CONTACT域
- ISXSIP_IE_REFERRED_BY *pReferBy = &pMakeCallEx->u.SIPInviteExReq.RefBy;
- pReferBy->Valid = 2;
- ISXSIP_IE_ADDR_EX *pContact = &pReferBy->cont_ruri.Contact;
- pContact->AddType = ISXSIP_ADDTYPE_URL;
- ISX_sr_default(PARMID_ISXSIP_ADDR_URL_EX, &pContact->u.AddrUrl);
- lstrcpy(pContact->u.AddrUrl.User, pAccount->Account);
- lstrcpy(pContact->u.AddrUrl.Host, CConfig::voipSignallingAddr());
- ISXSIP_IE_ADDR_EX *pRequestURI = &pReferBy->cont_ruri.RequestURI;
- pRequestURI->AddType = ISXSIP_ADDTYPE_URL;
- ISX_sr_default(PARMID_ISXSIP_ADDR_URL_EX, &pRequestURI->u.AddrUrl);
- lstrcpy(pRequestURI->u.AddrUrl.User, Chan.m_CalleeNum);
- lstrcpy(pRequestURI->u.AddrUrl.Host, pAccount->Proxy);
- //Auth
- char* pUser = pMakeCallEx->u.SIPInviteExReq.LongAuthInfo.AuthStr;
- ZeroMemory(pUser, 100);
- lstrcpy(pUser, pAccount->AuthAccount);
- char *pPwd = pUser + strlen(pUser) + 1;
- lstrcpy(pPwd, pAccount->Password);
- #pragma endregion
- #pragma region Media Part
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- getMediaAddr(pImpChan, MediaAddr);
- pMakeCallEx->u.SIPInviteExReq.Body.Valid = 1;
- pMakeCallEx->u.SIPInviteExReq.Body.BodyPartyType = BodyPartyType_SDP;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pMakeCallEx->u.SIPInviteExReq.Body.u.BodySdp;
- pSdp->SdpNum = 0;
- //o
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Connection.Addr, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- int iCodecId;
- int iPayLoad;
- ISXSIP_IE_SDP_MEDIA_DESC_EX DspMediaDescEx;
- DspMediaDescEx.MediaPort = pImpChan->mediaPort();
- DspMediaDescEx.MediaProtocol = ISXSIP_SDPPROTOCOL_RTP;
- DspMediaDescEx.MediaType = ISXSIP_SDPMEDIATYPE_AUDIO;
- int iPLIndex = 0;
- iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- iCodecId = AudioCodec_G729_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- DspMediaDescEx.Payload[iPLIndex++] = 101;
- DspMediaDescEx.PayLoadNum = iPLIndex;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInviteExReq.Body, SIPPARMID_MEDIADESC, sizeof(DspMediaDescEx), &DspMediaDescEx);
- IP_AUDIO_CAPABILITY AudioCodec;
- AudioCodec.iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInviteExReq.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- AudioCodec.iCodecId = AudioCodec_G729_20MS;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInviteExReq.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_RTP_MAP;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_RTP_MAP);
- ISXSIP_IE_SDP_RTP_MAP* pSdpRtpMap = &pSdp->Sdp[nIndex].u.RtpMap;
- pSdpRtpMap->Payload = 101;
- pSdpRtpMap->ClkRate = 8000;
- lstrcpy(pSdpRtpMap->EncodingName, "telephone-event");
- lstrcpy(pSdpRtpMap->EncodingParam, "1");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "fmtp");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "101 0-15");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "ptime");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "20");
- pSdp->SdpNum++;
- #pragma endregion
- }
- /*****************************************************************
- **【函数名称】 __onOffered
- **【函数功能】 处理来电呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Trunk::onOffered( CVoipChannel& Chan, GCPARAMEX_MAKECALL* pMakeCallEx )
- {
- CSessionShell::GetInstance().onLineStateChanged(Chan.m_Id, Chan.m_SessionCode, VIRTUAL_LINE_STATE_ALERTING, Chan.m_CallerNum, Chan.m_CalleeNum);
- //发送TRY
- ISX_gc_SIPSendTrying(Chan.m_CallId, EV_ASYNC);
- //check tel res 2018.4.9
- char t_callee[32] = { 0 };
- strncpy(t_callee, Chan.m_CalleeNum.GetBuffer(0), 31);
- bool t_b_ResExist = CConfig::isContainsExten(t_callee);
- if (t_b_ResExist) {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理中继来电,被叫号码资源存在 Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, t_callee);
- }
- else {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理中继来电,被叫号码资源不存在 Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, t_callee);
- //Chan.__clearCall(IPEC_SIPReasonStatus488NotAcceptableHere);
- }
- //
- ASSERT(Chan.m_pBindIpmCh == NULL);
- if((Chan.m_pBindIpmCh = CMC::GetInstance().allocIpmCh4SipCh(Chan.m_Id.NodeNo, Chan.m_Id.BoardNo)) == NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理中继来电出错, 无可用的IPM资源, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus486BusyHere);
- return;
- }
- Chan.m_pBindIpmCh->bind(&Chan);
- // 协商媒体编解码
- if(!Chan.__getCallMediaDesc(&pMakeCallEx->u.SIPInvite.Body))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理中继来电时协商媒体编解码失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus415UnsupportedMediaType);
- return;
- }
- // 启动媒体
- if(!Chan.m_pBindIpmCh->isStarted())
- {
- if(!Chan.m_pBindIpmCh->startMedia())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理中继来电时IPM资源启动失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- }
- GCPARAMEX_ANSWERCALL AnswerCallEx;
- Chan.__constructAnswerBody(&AnswerCallEx);
- if(ISX_gc_AnswerCall(Chan.m_CallId, 0, EV_ASYNC, &AnswerCallEx) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]应答中继来电失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus486BusyHere);
- }
- }
- /*****************************************************************
- **【函数名称】 onAlerting
- **【函数功能】 处理远端振铃
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Trunk::onAlerting( CVoipChannel& Chan, METAEVENT* pMetaEvent )
- {
- GCPARAMEX_ACCEPTCALL* pAcceptCall = (GCPARAMEX_ACCEPTCALL*)ISX_sr_getevtdatap();
- ASSERT(pAcceptCall != NULL);
- if(pAcceptCall->u.SIPRing.Body.Valid == 1)
- {
- // 协商媒体编解码
- if(!Chan.__getCallMediaDesc(&pAcceptCall->u.SIPRing.Body))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理Alerting时协商媒体编解码失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus415UnsupportedMediaType);
- return;
- }
- // 启动媒体
- ASSERT(Chan.m_pBindIpmCh != NULL);
- if(!Chan.m_pBindIpmCh->isStarted())
- {
- if(!Chan.m_pBindIpmCh->startMedia())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理Alerting时IPM资源启动失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- }
- CSessionShell::GetInstance().onLineStateChanged(Chan.m_Id, Chan.m_SessionCode, VIRTUAL_LINE_STATE_PROGRESSING, Chan.m_CallerNum, Chan.m_CalleeNum);
- }
- CSessionShell::GetInstance().onLineStateChanged(Chan.m_Id, Chan.m_SessionCode, VIRTUAL_LINE_STATE_RING_BACK, Chan.m_CallerNum, Chan.m_CalleeNum);
- }
- /*****************************************************************
- **【函数名称】 makeCall
- **【函数功能】 呼叫
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CVoipChannel::CImplement4Trunk::makeCall( CVoipChannel& Chan, int AccountId )
- {
-
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]中继模式下执行呼叫请求, caller = %s, callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- SIP_ACCOUNT* pAccount = CConfig::sipAccount().getAccount(AccountId);
- ASSERT(pAccount != NULL);
- if(pAccount == NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]进行中继呼叫时查找SIP账户[%d]失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, AccountId, Chan.m_CallerNum, Chan.m_CalleeNum);
- return false;
- }
- ASSERT(Chan.m_pBindIpmCh == NULL);
- if((Chan.m_pBindIpmCh = CMC::GetInstance().allocIpmCh4SipCh(Chan.m_Id.NodeNo, Chan.m_Id.BoardNo)) == NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]进行中继呼叫时分配IPM资源失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- return false;
- }
- Chan.m_pBindIpmCh->bind(&Chan);
- GCPARAMEX_MAKECALL MakeCallEx;
- ISX_sr_default(PARMID_SIP_INVITE, &MakeCallEx.u.SIPInviteExReq);
-
- __constructMakeCallBody(&MakeCallEx, Chan, Chan.m_pBindIpmCh, pAccount);
- return ISXE_gc_MakeCall(Chan.m_Handle, &Chan.m_CallId, NULL, NULL, -1, EV_ASYNC, &MakeCallEx) == 0;
- }
- /*****************************************************************
- **【函数名称】 getMediaAddr
- **【函数功能】 获取媒体地址
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Trunk::getMediaAddr( CIpmChannel* pImpChan, LPTSTR Buffer )
- {
- ASSERT(pImpChan != NULL);
- pImpChan->mediaAddrTrunk(Buffer);
- }
- /*****************************************************************
- **【函数名称】 __constructMakeCallBody
- **【函数功能】 构造呼叫SIP协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Exten::__constructMakeCallBody( GCPARAMEX_MAKECALL* pMakeCallEx, CIpmChannel* pImpChan )
- {
- ASSERT(pImpChan != NULL);
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- getMediaAddr(pImpChan, MediaAddr);
- int nIndex;
- pMakeCallEx->Protocol = eGCPro_SIP;
- pMakeCallEx->u.SIPInvite.Body.Valid = 1;
- pMakeCallEx->u.SIPInvite.Body.BodyPartyType = BodyPartyType_SDP;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pMakeCallEx->u.SIPInvite.Body.u.BodySdp;
- pSdp->SdpNum = 0;
- //o
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- sprintf_s(pSdp->Sdp[nIndex].u.Connection.Addr, 32, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- int iCodecId;
- int iPayLoad;
- ISXSIP_IE_SDP_MEDIA_DESC_EX DspMediaDescEx;
- DspMediaDescEx.MediaPort = pImpChan->mediaPort();
- DspMediaDescEx.MediaProtocol = ISXSIP_SDPPROTOCOL_RTP;
- DspMediaDescEx.MediaType = ISXSIP_SDPMEDIATYPE_AUDIO;
- int iPLIndex = 0;
- iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- iCodecId = AudioCodec_G729_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- DspMediaDescEx.Payload[iPLIndex++] = 101;
- DspMediaDescEx.PayLoadNum = iPLIndex;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInvite.Body, SIPPARMID_MEDIADESC, sizeof(DspMediaDescEx), &DspMediaDescEx);
- IP_AUDIO_CAPABILITY AudioCodec;
- AudioCodec.iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInvite.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- AudioCodec.iCodecId = AudioCodec_G729_20MS;
- ISX_sr_insertparm(&pMakeCallEx->u.SIPInvite.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_RTP_MAP;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_RTP_MAP);
- ISXSIP_IE_SDP_RTP_MAP* pSdpRtpMap = &pSdp->Sdp[nIndex].u.RtpMap;
- pSdpRtpMap->Payload = 101;
- pSdpRtpMap->ClkRate = 8000;
- lstrcpy(pSdpRtpMap->EncodingName, "telephone-event");
- lstrcpy(pSdpRtpMap->EncodingParam, "1");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "fmtp");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "101 0-15");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "ptime");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "20");
- pSdp->SdpNum++;
- }
- /*****************************************************************
- **【函数名称】 __onOffered
- **【函数功能】 处理来电呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Exten::onOffered( CVoipChannel& Chan, GCPARAMEX_MAKECALL* pMakeCallEx )
- {
- //发送TRY
- ISX_gc_SIPSendTrying(Chan.m_CallId, EV_ASYNC);
- //check tel res 2018.4.9
- char t_callee[32] = { 0 };
- strncpy(t_callee, Chan.m_CalleeNum.GetBuffer(0), 31);
- bool t_b_ResExist = CConfig::isContainsExten(t_callee);
- if (t_b_ResExist) {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理分机来电,被叫号码资源存在 Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, t_callee);
- }
- else {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理分机来电,被叫号码资源不存在 Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, t_callee);
- //Chan.__clearCall(IPEC_SIPReasonStatus488NotAcceptableHere);
- }
- //
- Chan.m_ExtenNo = atoi(Chan.m_CallerNum);
- ASSERT(Chan.m_pBindIpmCh == NULL);
- if((Chan.m_pBindIpmCh = CMC::GetInstance().allocIpmCh4SipCh(Chan.m_Id.NodeNo, Chan.m_Id.BoardNo)) == NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理分机来电出错, 无可用的IPM资源, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- Chan.m_pBindIpmCh->bind(&Chan);
- // 协商媒体编解码
- if(!Chan.__getCallMediaDesc(&pMakeCallEx->u.SIPInvite.Body))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理分机来电时协商媒体编解码失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus415UnsupportedMediaType);
- return;
- }
- if(!CSessionShell::GetInstance().onLineChannelEvent(Chan.m_Id, Chan.m_SessionCode, DEV_CH_EVT_FUN_CODE, Chan.m_CalleeNum, Chan.m_ExtenNo))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理座席分机来电失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- Chan.__clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- }
- }
- /*****************************************************************
- **【函数名称】 onAlerting
- **【函数功能】 处理远端振铃
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Exten::onAlerting( CVoipChannel& Chan, METAEVENT* pMetaEvent )
- {
- if(Chan.m_Job == DEV_LINE_CH_JOB_NONE)
- CSessionShell::GetInstance().onLineStateChanged(Chan.m_Id, Chan.m_SessionCode, VIRTUAL_LINE_STATE_ALERTING, Chan.m_CallerNum, Chan.m_CalleeNum);
- }
- /*****************************************************************
- **【函数名称】 makeCall
- **【函数功能】 呼叫
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CVoipChannel::CImplement4Exten::makeCall( CVoipChannel& Chan, int AccountId )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]分机模式下执行呼叫请求, caller = %s, callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- ASSERT(Chan.m_pBindIpmCh == NULL);
- if((Chan.m_pBindIpmCh = CMC::GetInstance().allocIpmCh4SipCh(Chan.m_Id.NodeNo, Chan.m_Id.BoardNo)) == NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]进行分机呼叫时分配IPM资源失败, 呼叫将释放, Caller = %s, Callee = %s"),
- Chan.m_Id.NodeNo, Chan.m_Id.BoardNo, Chan.m_Id.ChanNo, Chan.m_CallerNum, Chan.m_CalleeNum);
- return false;
- }
- Chan.m_pBindIpmCh->bind(&Chan);
- TCHAR Callee[SIP_URI_LEN] = { 0 };
- TCHAR Caller[SIP_URI_LEN] = { 0 };
- TCHAR ProxyIp[MAX_PATH] = { 0 };
- Chan.__getVoipAddr(ProxyIp);
- Chan.m_ExtenNo = atoi(Chan.m_CalleeNum);
- Chan.__getExtenAddrInfo(Chan.m_CalleeNum, Callee, SIP_URI_LEN);
- sprintf_s(Caller, SIP_URI_LEN, _T("%s@%s\0"), Chan.m_CallerNum, ProxyIp);
- GCPARAMEX_MAKECALL MakeCallEx;
- ISX_sr_default(PARMID_SIP_INVITE, &MakeCallEx.u.SIPInvite);
- ISX_sr_setparm(&MakeCallEx.u.SIPInvite, SIPPARMID_DESTADD, strlen(Callee), Callee);
- ISX_sr_setparm(&MakeCallEx.u.SIPInvite, SIPPARMID_SRCADD, strlen(Caller), Caller);
- __constructMakeCallBody(&MakeCallEx, Chan.m_pBindIpmCh);
- return ISX_gc_MakeCall(Chan.m_Handle, &Chan.m_CallId, Callee, NULL, -1, EV_ASYNC, &MakeCallEx) == 0;
- }
- /*****************************************************************
- **【函数名称】 getMediaAddr
- **【函数功能】 获取媒体地址
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::CImplement4Exten::getMediaAddr( CIpmChannel* pImpChan, LPTSTR Buffer )
- {
- ASSERT(pImpChan != NULL);
- pImpChan->mediaAddrBoard(Buffer);
- }
- CVoipChannel::CVoipChannel(DEV_RES_CH_TYPE ChannelNo, DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo)
- : CChannelResource(DEV_RES_TYPE_VOIP, NodeNo, BoardNo, DEVICE_RES_NO_ANY, ChannelNo), m_pImplement(NULL), m_CallId(0), m_IsBlocked(false),
- m_Job(DEV_LINE_CH_JOB_NONE), m_ExtenNo(0), m_Mixer(*this), m_pBindIpmCh(NULL), m_MediaPort(0), m_CodecId(-1)
- {
- }
- CVoipChannel::~CVoipChannel(void)
- {
- close();
- }
- /*****************************************************************
- **【函数名称】 __clearCall
- **【函数功能】 清除呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::__clearCall( int Cause )
- {
- if(m_CallId == 0)
- return false;
- m_State = GCST_DROPCALLING;
- if(m_MeetingInfo.MeetingId != MEETING_ID_INVALID)
- CMC::GetInstance().meetingRemove(this, m_MeetingInfo);
- m_Mixer.release();
- if(ISX_gc_DropCall(m_CallId, Cause, EV_ASYNC) == 0)
- {
- m_CallId = 0;
- return true;
- }
- else return false;
- }
- /*****************************************************************
- **【函数名称】 __getVoipAddr
- **【函数功能】 获取
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CVoipChannel::__getVoipAddr( LPTSTR AddrBuf )
- {
- return ISX_sr_getnet2cfg(m_Id.NodeNo, m_Id.BoardNo, BT_SIP, AddrBuf, NULL) == 0;
- }
- /*****************************************************************
- **【函数名称】 __getExtenAddrInfo
- **【函数功能】 获取SIP分机地址信息
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CVoipChannel::__getExtenAddrInfo( LPCTSTR Exten, LPTSTR pContactAddr, int Len )
- {
- ISXSIP_REGUSER RegUser;
- if(ISXE_gc_SipGetRegisterUser(Exten, &RegUser) == 0)
- {
- if(RegUser.PortNum != 0xffff && RegUser.PortNum != 0)
- sprintf_s(pContactAddr, Len, _T("%s@%s:%d\0"), Exten, RegUser.IpAddr, RegUser.PortNum);
- else
- sprintf_s(pContactAddr, Len, _T("%s@%s\0"), Exten, RegUser.IpAddr);
- return true;
- }
- return false;
- }
- /*****************************************************************
- **【函数名称】 __constructAnswerBody
- **【函数功能】 构造应答SIP协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__constructAnswerBody( GCPARAMEX_ANSWERCALL* pAnswerCallEx )
- {
- memset(pAnswerCallEx, 0, sizeof(*pAnswerCallEx));
- pAnswerCallEx->Protocol = eGCPro_SIP;
- pAnswerCallEx->u.SIPConn.Body.Valid = 1;
- pAnswerCallEx->u.SIPConn.Body.BodyPartyType = BodyPartyType_SDP;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pAnswerCallEx->u.SIPConn.Body.u.BodySdp;
- pSdp->SdpNum = 0;
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- ASSERT(m_pBindIpmCh != NULL);
- m_pImplement->getMediaAddr(m_pBindIpmCh, MediaAddr);
- //o
- int nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Connection.Addr, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- ISXSIP_IE_SDP_MEDIA_DESC_EX DspMediaDescEx;
- DspMediaDescEx.MediaPort = m_pBindIpmCh->mediaPort();
- DspMediaDescEx.MediaProtocol = ISXSIP_SDPPROTOCOL_RTP;
- DspMediaDescEx.MediaType = ISXSIP_SDPMEDIATYPE_AUDIO;
- int iPLIndex = 0;
- int nPayLoad = 0;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &nPayLoad, &m_CodecId);
- DspMediaDescEx.Payload[iPLIndex++] = nPayLoad;
- DspMediaDescEx.Payload[iPLIndex++] = 101;
- DspMediaDescEx.PayLoadNum = iPLIndex;
- ISX_sr_insertparm(&pAnswerCallEx->u.SIPConn.Body, SIPPARMID_MEDIADESC, sizeof(DspMediaDescEx), &DspMediaDescEx);
- IP_AUDIO_CAPABILITY AudioCodec;
- AudioCodec.iCodecId = (eAUDIOCODEC)m_CodecId;
- ISX_sr_insertparm(&pAnswerCallEx->u.SIPConn.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_RTP_MAP;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_RTP_MAP);
- ISXSIP_IE_SDP_RTP_MAP* pSdpRtpMap = &pSdp->Sdp[nIndex].u.RtpMap;
- pSdpRtpMap->Payload = 101;
- pSdpRtpMap->ClkRate = 8000;
- lstrcpy(pSdpRtpMap->EncodingName, "telephone-event");
- lstrcpy(pSdpRtpMap->EncodingParam, "1");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "fmtp");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "101 0-15");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "ptime");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "20");
- pSdp->SdpNum++;
- }
- /*****************************************************************
- **【函数名称】 __constructProgressBody
- **【函数功能】 构造呼叫进展SIP协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__constructProgressBody( GCPARAMEX_CALLPROGRESS* pProgressEx )
- {
- memset(pProgressEx, 0, sizeof(*pProgressEx));
- pProgressEx->Protocol = eGCPro_SIP;
- pProgressEx->u.SIPProgress.Body.Valid = 1;
- pProgressEx->u.SIPProgress.Body.BodyPartyType = BodyPartyType_SDP;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pProgressEx->u.SIPProgress.Body.u.BodySdp;
- pSdp->SdpNum = 0;
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- ASSERT(m_pBindIpmCh != NULL);
- m_pImplement->getMediaAddr(m_pBindIpmCh, MediaAddr);
- int nIndex;
- //o
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Connection.Addr, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- ISXSIP_IE_SDP_MEDIA_DESC_EX DspMediaDescEx;
- DspMediaDescEx.MediaPort = m_pBindIpmCh->mediaPort();
- DspMediaDescEx.MediaProtocol = ISXSIP_SDPPROTOCOL_RTP;
- DspMediaDescEx.MediaType = ISXSIP_SDPMEDIATYPE_AUDIO;
- int iPLIndex = 0;
- int iPayLoad = 0;
- if(m_CodecId != -1)
- {
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &m_CodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- }
- else
- {
- int iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- iCodecId = AudioCodec_G729_20MS;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &iPayLoad, &iCodecId);
- DspMediaDescEx.Payload[iPLIndex++] = iPayLoad;
- }
- DspMediaDescEx.Payload[iPLIndex++] = 101;
- DspMediaDescEx.PayLoadNum = iPLIndex;
- ISX_sr_insertparm(&pProgressEx->u.SIPProgress.Body, SIPPARMID_MEDIADESC, sizeof(DspMediaDescEx), &DspMediaDescEx);
- IP_AUDIO_CAPABILITY AudioCodec;
- if(m_CodecId != -1)
- {
- AudioCodec.iCodecId = (eAUDIOCODEC)m_CodecId;
- ISX_sr_insertparm(&pProgressEx->u.SIPProgress.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- }
- else
- {
- AudioCodec.iCodecId = AudioCodec_G711_ALAW_20MS;
- ISX_sr_insertparm(&pProgressEx->u.SIPProgress.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- AudioCodec.iCodecId = AudioCodec_G729_20MS;
- ISX_sr_insertparm(&pProgressEx->u.SIPProgress.Body, SIPPARMID_CHCAP, sizeof(AudioCodec), &AudioCodec);
- }
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_RTP_MAP;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_RTP_MAP);
- ISXSIP_IE_SDP_RTP_MAP* pSdpRtpMap = &pSdp->Sdp[nIndex].u.RtpMap;
- pSdpRtpMap->Payload = 101;
- pSdpRtpMap->ClkRate = 8000;
- lstrcpy(pSdpRtpMap->EncodingName, "telephone-event");
- lstrcpy(pSdpRtpMap->EncodingParam, "1");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "fmtp");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "101 0-15");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "ptime");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "20");
- pSdp->SdpNum++;
- }
- /*****************************************************************
- **【函数名称】 __constructReinviteBody4Hold
- **【函数功能】 构造ReinviteACK协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__constructReinviteBody4Hold( ISXSIP_IE_BODY_EX* pBody, bool Hold )
- {
- pBody->Valid = 1;
- pBody->BodyPartyType = BodyPartyType_SDP;
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- ASSERT(m_pBindIpmCh != NULL);
- m_pImplement->getMediaAddr(m_pBindIpmCh, MediaAddr);
- int nIndex;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pBody->u.BodySdp;
- pSdp->SdpNum = 0;
- //o
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Connection.Addr, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- int nPLIndex = 0;
- int nPayLoad;
- ISX_sr_convert(CONID_CODECID2PLAYLOAD, &nPayLoad, &m_CodecId);
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_MEDIA_DESC;
- pSdp->Sdp[nIndex].u.MediaDesc.MediaPort = m_pBindIpmCh->mediaPort();
- pSdp->Sdp[nIndex].u.MediaDesc.MediaProtocol = ISXSIP_SDPPROTOCOL_RTP;
- pSdp->Sdp[nIndex].u.MediaDesc.MediaType = ISXSIP_SDPMEDIATYPE_AUDIO;
- pSdp->Sdp[nIndex].u.MediaDesc.Payload[nPLIndex++] = nPayLoad;
- pSdp->Sdp[nIndex].u.MediaDesc.Payload[nPLIndex++] = 101;
- pSdp->Sdp[nIndex].u.MediaDesc.PayLoadNum = nPLIndex;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_MEDIA_DESC) - 1 + pSdp->Sdp[nIndex].u.MediaDesc.PayLoadNum;
- pSdp->SdpNum++;
- // a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_RTP_MAP;
- pSdp->Sdp[nIndex].u.RtpMap.Payload = g_SipSdpRtpMap[m_CodecId].Payload;
- pSdp->Sdp[nIndex].u.RtpMap.ClkRate = g_SipSdpRtpMap[m_CodecId].ClkRate;
- lstrcpy(pSdp->Sdp[nIndex].u.RtpMap.EncodingName, g_SipSdpRtpMap[m_CodecId].EncodingName);
- lstrcpy(pSdp->Sdp[nIndex].u.RtpMap.EncodingParam, g_SipSdpRtpMap[m_CodecId].EncodingParam);
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_RTP_MAP);
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "fmtp");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "101 0-15");
- pSdp->SdpNum++;
- if(Hold)
- {
- // a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONN_MODE;
- pSdp->Sdp[nIndex].u.ConnMode.ConnMode = ISXSIP_SDPCONNECTMODE_RECVONLY;
- pSdp->SdpNum++;
- }
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "ptime");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "20");
- pSdp->SdpNum++;
- }
- /*****************************************************************
- **【函数名称】 __constructReinviteBody4T38
- **【函数功能】 构造ReinviteACK协议体
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__constructReinviteBody4T38( ISXSIP_IE_BODY_EX* pBody )
- {
- pBody->Valid = 1;
- pBody->BodyPartyType = BodyPartyType_SDP;
- TCHAR MediaAddr[MAX_PATH] = { 0 };
- ASSERT(m_pBindIpmCh != NULL);
- m_pImplement->getMediaAddr(m_pBindIpmCh, MediaAddr);
- int nIndex;
- ISXSIP_IE_BODY_SDP_EX* pSdp = &pBody->u.BodySdp;
- pSdp->SdpNum = 0;
- //o
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ORIGIN;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_ORIGIN);
- pSdp->Sdp[nIndex].u.Origin.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Origin.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.SessionId, "20");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.UserName, "EHang");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Version, "001");
- lstrcpy(pSdp->Sdp[nIndex].u.Origin.Addr, MediaAddr);
- pSdp->SdpNum++;
- //s
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION);
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Name, "EH-Call");
- lstrcpy(pSdp->Sdp[nIndex].u.Session.Info, "");
- pSdp->SdpNum++;
- //c
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_CONNECTION;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_CONNECTION);
- pSdp->Sdp[nIndex].u.Connection.NetType = ISXSIP_SDPNETTYPE_IN;
- pSdp->Sdp[nIndex].u.Connection.AddrType = ISXSIP_SDPADDRTYPE_IP4;
- lstrcpy(pSdp->Sdp[nIndex].u.Connection.Addr, MediaAddr);
- pSdp->SdpNum++;
- //t
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_SESSION_TIME;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_SESSION_TIME);
- pSdp->Sdp[nIndex].u.SessionTime.Start = 0;
- pSdp->Sdp[nIndex].u.SessionTime.End = 0;
- pSdp->SdpNum++;
- //m
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_MEDIA_DESC;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_MEDIA_DESC_EX);
- pSdp->Sdp[nIndex].u.MediaDesc.MediaPort = m_pBindIpmCh->mediaPort();
- pSdp->Sdp[nIndex].u.MediaDesc.MediaProtocol = ISXSIP_SDPPROTOCOL_UDPTL;
- pSdp->Sdp[nIndex].u.MediaDesc.MediaType = ISXSIP_SDPMEDIATYPE_IMAGE;
- pSdp->Sdp[nIndex].u.MediaDesc.PayLoadNum = 1;
- pSdp->Sdp[nIndex].u.MediaDesc.Payload[0] = 0;
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "T38FaxVersion");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "0");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "T38MaxBitRate");
- //strcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "14400");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "9600");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "T38FaxFillBitRemoval");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "0");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "T38FaxTranscodingMMR");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "0");
- pSdp->SdpNum++;
- //a
- nIndex = pSdp->SdpNum;
- pSdp->Sdp[nIndex].Tag = ISXSIP_IE_SDP_TAG_ATTRIBUTE;
- pSdp->Sdp[nIndex].Len = sizeof(ISXSIP_IE_SDP_TAG_ATTRIBUTE);
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Name, "T38FaxTranscodingJBIG");
- lstrcpy(pSdp->Sdp[nIndex].u.Attribute.Value, "0");
- pSdp->SdpNum++;
- }
- /*****************************************************************
- **【函数名称】 __getCallNumFromSipAddr
- **【函数功能】 从SIP URI中解析号码
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__getCallNumFromSipAddr( LPCTSTR Called, CString& NumBuf )
- {
- ASSERT(Called != NULL);
- NumBuf = _T("");
- TCHAR szTmpAddr[GC_ADDRSIZE];
- lstrcpy(szTmpAddr, Called);
- TCHAR *p = strstr(szTmpAddr, _T("@"));
- if(p != NULL)
- *p=0;
- p = strstr(szTmpAddr, _T(":"));
- if(p == NULL)
- NumBuf = szTmpAddr;
- else
- NumBuf = p+1;
- }
- /*****************************************************************
- **【函数名称】 __getCallMediaDesc
- **【函数功能】 获取呼叫的媒体描述
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::__getCallMediaDesc( ISXSIP_IE_BODY_EX* pSdp, int CodecId /*= -1*/ )
- {
- if(pSdp->Valid == 0 || pSdp->BodyPartyType == BodyPartyType_TRANS)
- return false;
- int iLoopNum = pSdp->u.BodySdp.SdpNum;
- ISXSIP_IE_BODY_SDP_EX* pSdpex = &pSdp->u.BodySdp;
- for(int i = 0; i < iLoopNum; i++)
- {
- if(pSdpex->Sdp[i].Tag == ISXSIP_IE_SDP_TAG_CONNECTION)
- {
- m_ConnectAddr = pSdpex->Sdp[i].u.Connection.Addr;
- continue;
- }
- if(pSdpex->Sdp[i].Tag != ISXSIP_IE_SDP_TAG_MEDIA_DESC)
- continue;
- if(pSdpex->Sdp[i].u.MediaDesc.MediaType != ISXSIP_SDPMEDIATYPE_AUDIO)
- continue;
- int iPayLoadNum = pSdpex->Sdp[i].u.MediaDesc.PayLoadNum;
- m_MediaPort = pSdpex->Sdp[i].u.MediaDesc.MediaPort;
- ISXSIP_IE_SDP_MEDIA_DESC_EX* pmdex = &pSdpex->Sdp[i].u.MediaDesc;
- if(CodecId >= 0) //如果指定了CODEC
- {
- for(int j = 0; j < iPayLoadNum; j++)
- {
- if(g_SipSdpRtpMap[CodecId].Payload == pmdex->Payload[j])
- {
- //取此指定AUDIO编码作为协商类型
- m_CodecId = CodecId;
- return true;
- }
- }
- }
- else
- {
- for(int j = 0; j < iPayLoadNum; j++)
- {
- for(int k = 0; k < AudioCodec_MaxNum; k++)
- {
- if(g_SipSdpRtpMap[k].Payload == pmdex->Payload[j])
- {
- // 从给出的媒体编码类型中取一个AUDIO编码作为协商类型
- m_CodecId = k;
- return true;
- }
- }
- }
- }
- }
- return false;
- }
- /*****************************************************************
- **【函数名称】 __consultMedia
- **【函数功能】 协商媒体
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::__consultMedia( ISXSIP_IE_BODY_EX* pSdp )
- {
- if(pSdp->Valid == 0 || pSdp->BodyPartyType == BodyPartyType_TRANS)
- return false;
- int iLoopNum = pSdp->u.BodySdp.SdpNum;
- ISXSIP_IE_BODY_SDP_EX* pSdpex = &pSdp->u.BodySdp;
- for(int i = 0; i < iLoopNum; i++)
- {
- if(pSdpex->Sdp[i].Tag != ISXSIP_IE_SDP_TAG_MEDIA_DESC)
- continue;
- if(pSdpex->Sdp[i].u.MediaDesc.MediaType != ISXSIP_SDPMEDIATYPE_AUDIO)
- continue;
- int iPayLoadNum = pSdpex->Sdp[i].u.MediaDesc.PayLoadNum;
- ISXSIP_IE_SDP_MEDIA_DESC_EX* pmdex = &pSdpex->Sdp[i].u.MediaDesc;
- for(int j = 0; j < iPayLoadNum; j++)
- {
- for(int k = 0; k < AudioCodec_MaxNum; k++)
- {
- if(g_SipSdpRtpMap[k].Payload == pmdex->Payload[j])
- {
- pmdex->PayLoadNum = 2;
- pmdex->Payload[0] = pmdex->Payload[j];
- pmdex->Payload[1] = 101;
- return true;
- }
- }
- }
- }
- return false;
- }
- /*****************************************************************
- **【函数名称】 __analyzeReinvite
- **【函数功能】 分析reinvite的目的
- **【参数】
- **【返回值】
- ****************************************************************/
- ReinvitePurpose CVoipChannel::__analyzeReinvite( ISXSIP_IE_BODY_SDP_EX* pSdp )
- {
- for(int i = 0; i < pSdp->SdpNum; ++i)
- {
- USHORT Tag = pSdp->Sdp[i].Tag;
- if(Tag == ISXSIP_IE_SDP_TAG_CONN_MODE)
- {
- UCHAR ConMode = pSdp->Sdp[i].u.ConnMode.ConnMode;
- if(ConMode == ISXSIP_SDPCONNECTMODE_SENDONLY)
- return REINVITE_FOR_HOLD;
- else if(ConMode == ISXSIP_SDPCONNECTMODE_SENDRECV)
- return REINVITE_FOR_TAKEBACK;
- }
- else if(Tag == ISXSIP_IE_SDP_TAG_MEDIA_DESC)
- {
- if(pSdp->Sdp[i].u.MediaDesc.MediaType == ISXSIP_SDPMEDIATYPE_IMAGE)
- return REINVITE_FOR_FAX;
- }
- }
- return REINVITE_FOR_NULL;
- }
- /*****************************************************************
- **【函数名称】 __onOffered
- **【函数功能】 处理来电呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onOffered( METAEVENT* pMetaEvent )
- {
- if(m_State != GCST_NULL)
- {
- ISX_gc_DropCall(pMetaEvent->crn, IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]检测到呼叫, 但通道状态异常, 呼叫将忽略"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return;
- }
- m_State = GCST_OFFERED;
- m_CallId = pMetaEvent->crn;
- GCPARAMEX_MAKECALL* pMakeCallEx = (GCPARAMEX_MAKECALL*)pMetaEvent->evtdatap;
- ASSERT(pMakeCallEx != NULL);
- CHAR DNIZ[GC_ADDRSIZE] = { 0 };
- CHAR ANI[GC_ADDRSIZE] = { 0 };
- ISX_gc_GetCallInfo(m_CallId, DESTINATION_ADDRESS, DNIZ);
- ISX_gc_GetCallInfo(m_CallId, ORIGINATION_ADDRESS, ANI);
- // 获取主、被叫号码
- __getCallNumFromSipAddr(ANI, m_CallerNum);
- __getCallNumFromSipAddr(DNIZ, m_CalleeNum);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]检测到呼叫, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, ANI, DNIZ);
- // 判断主叫是内线还是中继
- if(isInnerSipUser(m_CallerNum)) // 内线
- m_pImplement = &ms_Implement4Exten;
- else // 外线
- m_pImplement = &ms_Implement4Trunk;
- m_pImplement->onOffered(*this, pMakeCallEx);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onAlerting
- **【函数功能】 处理远端振铃
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onAlerting( METAEVENT* pMetaEvent )
- {
- if(m_State == GCST_ALERTING || m_State == GCST_DROPCALLING)
- return;
-
- m_State = GCST_ALERTING;
- ASSERT(m_pImplement != NULL);
- m_pImplement->onAlerting(*this, pMetaEvent);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onProgressing
- **【函数功能】 处理Progressing
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onProgressing( void )
- {
- if(m_State == GCST_PROGRESS || m_State == GCST_DROPCALLING)
- return;
- GCPARAMEX_CALLPROGRESS* pProgress = (GCPARAMEX_CALLPROGRESS*)ISX_sr_getevtdatap();
- ASSERT(pProgress != NULL);
- // 存在收到183而无SDP紧接着又再次收到携带了SDP的183这种情况,所以在if语句判断成功后再将m_State设置为GCST_PROGRESS
- if(pProgress->u.SIPProgress.Body.Valid == 1)
- {
- m_State = GCST_PROGRESS;
- // 协商媒体编解码
- if(!__getCallMediaDesc(&pProgress->u.SIPProgress.Body))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理Progressing时协商媒体编解码失败, 呼叫将释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus415UnsupportedMediaType);
- return;
- }
- // 启动媒体
- ASSERT(m_pBindIpmCh != NULL);
- if(!m_pBindIpmCh->isStarted())
- {
- if(!m_pBindIpmCh->startMedia())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理Progressing时IPM资源启动失败, 呼叫将释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- }
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_PROGRESSING, m_CallerNum, m_CalleeNum);
- }
- }
- /*****************************************************************
- **【函数名称】 __onConnected
- **【函数功能】 处理远端接通
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onConnected( METAEVENT* pMetaEvent )
- {
- if(m_State == GCST_DROPCALLING)
- return;
- m_State = GCST_CONNECTED;
- GCPARAMEX_ANSWERCALL *pOutAnswerCallEx = (GCPARAMEX_ANSWERCALL*)pMetaEvent->evtdatap;
- ASSERT(pOutAnswerCallEx != NULL);
- if(pOutAnswerCallEx->u.SIPConn.Body.Valid == 1)
- {
- // 协商媒体编解码
- if(!__getCallMediaDesc(&pOutAnswerCallEx->u.SIPConn.Body))
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理远端应答时协商媒体编解码失败, 呼叫将释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus415UnsupportedMediaType);
- return;
- }
- }
- // 启动媒体
- ASSERT(m_pBindIpmCh != NULL);
- if(!m_pBindIpmCh->isStarted())
- {
- if(!m_pBindIpmCh->startMedia())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]处理远端应答时启动IPM资源失败, 呼叫将释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- }
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]远端应答, 开始通话, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- if(m_Job == DEV_LINE_CH_JOB_PRE_DIAL)
- {
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_INIT, m_CallerNum, m_CalleeNum);
- m_Job = DEV_LINE_CH_JOB_NONE;
- }
- else if(m_Job == DEV_LINE_CH_JOB_OFF_HOOK)
- {
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_OFF_HOOK, NULL);
- m_Job = DEV_LINE_CH_JOB_NONE;
- }
- else
- {
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
- }
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onAnswered
- **【函数功能】 处理应答成功
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onAnswered( void )
- {
- if(m_State == GCST_DROPCALLING)
- return;
- m_State = GCST_CONNECTED;
- // 启动媒体
- ASSERT(m_pBindIpmCh != NULL);
- if(!m_pBindIpmCh->isStarted())
- {
- if(!m_pBindIpmCh->startMedia())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]应答远端时启动IPM资源失败, 呼叫将释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return;
- }
- }
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]应答成功, 开始通话, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onCallFinish
- **【函数功能】 处理呼叫成功
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onCallFinish( void )
- {
- m_State = GCST_NULL;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]空闲"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- // 因为发现调用__ClearCall之后又收到GCEV_CONNECTED等事件,导致IPM通道stop之后又start,从而使IPM通道
- // 一直处于start状态未释放,后续的呼叫若使用该IPM通道会因为start失败而造成呼叫异常,鉴于此把IPM通道的
- // stop方法从__ClearCall函数移至此处调用。
- if(m_pBindIpmCh != NULL)
- {
- m_pBindIpmCh->stopMedia();
- // 未关联会话则IPM通道无法被会话释放,所以这里提前释放
- if(m_SessionCode == SESSION_INVALID_CALL)
- {
- m_pBindIpmCh->reset();
- m_pBindIpmCh = NULL;
- }
- }
- // 通各线路状态变化
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_FREE, NULL, NULL);
- m_pImplement = NULL;
- m_CallId = 0;
- m_Job = DEV_LINE_CH_JOB_NONE;
- m_ExtenNo = 0;
- m_MediaPort = 0;
- m_CodecId = -1;
- m_ConnectAddr = _T("");
- reset();
- CMC::GetInstance().onDevResState(m_Id);
- }
- /*****************************************************************
- **【函数名称】 __onDiconnected
- **【函数功能】 处理呼叫中断
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onDiconnected( METAEVENT* pMetaEvent )
- {
- GCPARAMEX_DROPCALL* pDropCall = (GCPARAMEX_DROPCALL*)pMetaEvent->evtdatap;
- ASSERT(pDropCall != NULL);
- if(m_State != GCST_CONNECTED) // 非通话中挂机
- {
- int ErrCode;
- switch(pDropCall->u.SIPDrop.usCause)
- {
- case IPEC_SIPReasonStatus404NotFound:
- ErrCode = CALL_FAILED_CAUSE_NUM_INVALID;
- break;
- case IPEC_SIPReasonStatus500ServerInternalError:
- case IPEC_SIPReasonStatus480TemporarilyUnavailable:
- ErrCode = CALL_FAILED_CAUSE_NO_ANSWER;
- break;
- case IPEC_SIPReasonStatus486BusyHere:
- ErrCode = CALL_FAILED_CAUSE_USER_BUSY;
- break;
- case IPEC_SIPReasonStatus410Gone:
- ErrCode = CALL_FAILED_CAUSE_DST_OFF;
- break;
- default:
- ErrCode = CALL_FAILED_CAUSE_NETWORK_ERR;
- break;
- }
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_CALL_FAILD_CAUSE, (LPCTSTR)ErrCode);
- }
- m_State = GCST_DISCONNECTED;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]检测到远端挂机, Caller = %s, Callee = %s, Cause = %d"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum, pDropCall->u.SIPDrop.usCause);
- // 远端挂机,结束两方通道通话
- __clearCall(pDropCall->u.SIPDrop.usCause);
- }
- /*****************************************************************
- **【函数名称】 __onTaskFail
- **【函数功能】 处理通道任务失败
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onTaskFail( void )
- {
- switch(ISX_sr_getevtopertype())
- {
- case OPER_ACCEPTCALL:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]accept呼叫失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- break;
- case OPER_ANSWERCALL:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]应答来电失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- break;
- case OPER_MAKECALL:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus200OK);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]外呼失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- break;
- case OPER_DROPCALL:
- {
- ASSERT(FALSE);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]挂机失败, 已强制释放资源, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __onCallFinish();
- }
- break;
- case OPER_SIP_SENDREINVITE:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]发送Reinvite失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- break;
- case OPER_SIP_SENDREINVITEACK:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]发送ReinviteACK失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 __onRecvInfo
- **【函数功能】 处理收到的SIP消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvInfo( METAEVENT* pMetaEvent )
- {
- SIP_INFO* pSipInfo = (SIP_INFO*)pMetaEvent->evtdatap;
- ASSERT(pSipInfo != NULL);
- SIP_INFO_ACK Ack;
- memcpy(&Ack.Body, &pSipInfo->Body, sizeof(ISXSIP_IE_BODY_EX));
- Ack.ulSerialNo = pSipInfo->ulSerialNo;
- Ack.usCause = IPEC_SIPReasonStatus200OK;
- ISX_gc_SIPSendInfoAck(pMetaEvent->crn, EV_ASYNC, &Ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvReinvite
- **【函数功能】 处理Reinvite消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvReinvite( METAEVENT* pMetaEvent )
- {
- ISXSIP_IE_BODY_EX* pSdp = (ISXSIP_IE_BODY_EX*)pMetaEvent->evtdatap;
- ASSERT(pSdp != NULL);
- if(pSdp->Valid == 0 || pSdp->BodyPartyType == BodyPartyType_TRANS)
- return;
- ReinvitePurpose Purpose = __analyzeReinvite(&pSdp->u.BodySdp);
- SIP_REINVITE_ACK Ack;
- switch(Purpose)
- {
- case REINVITE_FOR_HOLD:
- {
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_HOLD_ON, NULL, m_ExtenNo);
- Ack.usCause = IPEC_SIPReasonStatus200OK;
- __constructReinviteBody4Hold(&Ack.Body, true);
- }
- break;
- case REINVITE_FOR_TAKEBACK:
- {
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_TAKE_BACK, NULL, m_ExtenNo);
- Ack.usCause = IPEC_SIPReasonStatus200OK;
- __constructReinviteBody4Hold(&Ack.Body, false);
- }
- break;
- case REINVITE_FOR_FAX:
- {
- __constructReinviteBody4T38(&Ack.Body);
- ASSERT(m_pBindIpmCh != NULL);
- Ack.usCause = m_pBindIpmCh->switchVF(pSdp) ? IPEC_SIPReasonStatus200OK : IPEC_SIPReasonStatus403Forbidden;
- }
- break;
- default:
- Ack.usCause = IPEC_SIPReasonStatus403Forbidden;
- }
- ISX_gc_SIPSendReinviteAck(m_CallId, EV_ASYNC, &Ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvReinviteAck
- **【函数功能】 处理ReinviteACK消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvReinviteAck( METAEVENT* pMetaEvent )
- {
- SIP_REINVITE_ACK* pReinviteAck = (SIP_REINVITE_ACK*)pMetaEvent->evtdatap;
- ASSERT(pReinviteAck != NULL);
- ISXSIP_IE_BODY_EX* pSdp = &pReinviteAck->Body;
- if(pSdp->Valid == 0 || pSdp->BodyPartyType == BodyPartyType_TRANS)
- return;
- ASSERT(m_pBindIpmCh != NULL);
- if(m_pBindIpmCh->switchVF(pSdp))
- {
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]响应ReinviteAck消息,切换传真模式失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- }
- /*****************************************************************
- **【函数名称】 __onRecvUpdate
- **【函数功能】 处理Update消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvUpdate( METAEVENT* pMetaEvent )
- {
- SIP_UPDATE_IND *pUpdate = (SIP_UPDATE_IND *)pMetaEvent->evtdatap;
- ASSERT(pUpdate != NULL);
- SIP_GENTRANSC_ACK ack;
- memcpy(&ack.Body, &pUpdate->Body, sizeof(ISXSIP_IE_BODY_EX));
- ack.ulSerialNo = pUpdate->ulSerialNo;
- ack.usCause = IPEC_SIPReasonStatus200OK;
- ISX_gc_SIPSendUpdateAck (pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvSubscribe
- **【函数功能】 处理subscribe消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvSubscribe( METAEVENT* pMetaEvent )
- {
- SIP_SUBSCRIBE_IND* pInd = (SIP_SUBSCRIBE_IND *)pMetaEvent->evtdatap;
- ASSERT(pInd != NULL);
- SIP_SUBSCRIBE_ACK ack;
- memcpy(&ack.Expires, &pInd->Expires, sizeof(ISXSIP_IE_EXPIRES));
- memcpy(&ack.Body, &pInd->Body, sizeof(ISXSIP_IE_BODY_EX));
- ack.ulSerialNo = pInd->ulSerialNo;
- ack.usCause = IPEC_SIPReasonStatus406NotAcceptable;
- ISX_gc_SIPSendSubscribeAck(pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvMessage
- **【函数功能】 处理message消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvMessage( METAEVENT* pMetaEvent )
- {
- SIP_MESSAGE_IND* pInd = (SIP_MESSAGE_IND *)pMetaEvent->evtdatap;
- ASSERT(pInd != NULL);
- SIP_GENTRANSC_ACK ack;
- ack.usCause = IPEC_SIPReasonStatus200OK;
- memcpy(&ack.Body, &pInd->Body, sizeof(ISXSIP_IE_BODY_EX));
- ack.ulSerialNo = pInd->ulSerialNo;
- ISX_gc_SIPSendMessageAck (pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvNotify
- **【函数功能】 处理notify消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvNotify( METAEVENT* pMetaEvent )
- {
- SIP_NOTIFY_IND* pInd = (SIP_NOTIFY_IND *)pMetaEvent->evtdatap;
- ASSERT(pInd != NULL);
- SIP_GENTRANSC_ACK ack;
- memcpy(&ack.Body, &pInd->Body, sizeof(ISXSIP_IE_BODY_EX));
- ack.usCause = IPEC_SIPReasonStatus200OK;
- ack.ulSerialNo = pInd->ulSerialNo;
- ISX_gc_SIPSendNotifyAck (pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvRefer
- **【函数功能】 处理refer消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvRefer( METAEVENT* pMetaEvent )
- {
- SIP_REFER_IND* pInd = (SIP_REFER_IND *)ISX_sr_getevtdatap();
- ASSERT(pInd != NULL);
- SIP_REFER_ACK ack;
- memcpy(&ack.Body, &pInd->Body, sizeof(ISXSIP_IE_BODY_EX));
- memcpy(&ack.Contact, &pInd->Contact, sizeof(ISXSIP_IE_CONTACT));
- ack.usCause = IPEC_SIPReasonStatus403Forbidden;
- ack.ulSerialNo = pInd->ulSerialNo;
- ISX_gc_SIPSendReferAck(pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 __onRecvOption
- **【函数功能】 处理option消息
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::__onRecvOption( METAEVENT* pMetaEvent )
- {
- SIP_OPTIONS_IND* pInd = (SIP_OPTIONS_IND *)ISX_sr_getevtdatap();
- ASSERT(pInd != NULL);
- SIP_GENTRANSC_ACK ack;
- ZeroMemory(&ack, sizeof(ack));
- ack.ulSerialNo = pInd->ulSerialNo;
- ack.usCause = IPEC_SIPReasonStatus200OK;
- if(__consultMedia(&pInd->Body))
- memcpy(&ack.Body, &pInd->Body, sizeof(ISXSIP_IE_BODY_EX));
-
- ISX_gc_SIPSendOptionsAck(pMetaEvent->crn, EV_ASYNC, &ack);
- }
- /*****************************************************************
- **【函数名称】 open
- **【函数功能】 打开系统资源
- **【参数】
- **【返回值】 成功true,失败false
- ****************************************************************/
- bool CVoipChannel::open( void )
- {
- ASSERT(m_Handle == DEV_HANDLE_INVALID);
- if(ISX_gc_OpenEx(&m_Handle, m_Id.NodeNo, m_Id.BoardNo, -1, m_Id.ChanNo, EV_SYNC, this, LINETYPE_SIP) < 0)
- {
- m_Handle = DEV_HANDLE_INVALID;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{VOIPCh}: VOIP通道[%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- ISX_gc_SetEvtMsk(m_Handle, GCMSK_PROGRESS, GCACT_ADDMSK);
- if( m_Id.ChanNo % 2 != 0 )
- {
- if(ISX_gc_WaitCall(m_Handle, NULL, NULL, -1, EV_ASYNC) < 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{VOIPCh}: VOIP通道[%d-%d-%d]等待呼叫失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- }
- //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: VOIP通道[%d-%d-%d]打开成功"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return true;
- }
- /*****************************************************************
- **【函数名称】 close
- **【函数功能】 关闭系统资源
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::close( void )
- {
- if(m_Handle != DEV_HANDLE_INVALID)
- {
- ISX_gc_Close(m_Handle);
- m_Handle = DEV_HANDLE_INVALID;
- //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: VOIPCh通道[%d-%d-%d]关闭"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- }
- }
- /*****************************************************************
- **【函数名称】 offhook
- **【函数功能】 内线摘机(只对内线有效)
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::offhook( bool IgnoreSession, LPCTSTR CallerNum )
- {
- ASSERT(CallerNum != NULL);
- if(m_State != GCST_NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]振铃座席分机失败, 通道状态非空闲, Exten = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, CallerNum);
- return false;
- }
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行振铃座席分机请求, Exten = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, CallerNum);
- if(IgnoreSession)
- m_Job = DEV_LINE_CH_JOB_OFF_HOOK;
- else
- m_Job = DEV_LINE_CH_JOB_PRE_DIAL;
- m_CalleeNum = CallerNum;
- m_CallerNum = CallerNum;
- m_pImplement = &ms_Implement4Exten;
- return m_pImplement->makeCall(*this, INVALID_ID_SIP_ACCOUNT);
- }
- /*****************************************************************
- **【函数名称】 dropCall
- **【函数功能】 挂机
- **【参数】 IsPassive 是否为被动挂机
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::dropCall( bool IsPassive )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行挂机请求, caller = %s, callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return __clearCall(IPEC_SIPReasonStatus200OK);
- }
- /*****************************************************************
- **【函数名称】 makeCall
- **【函数功能】 启动线路拨号
- **【参数】 lpCalleeNum 被叫号码
- lpCallerNum 主叫号码
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::makeCall( LPCTSTR Callee, LPCTSTR Caller, int AccountId )
- {
- ASSERT(Callee != NULL);
- ASSERT(Caller != NULL);
- if(m_State != GCST_NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]执行呼叫请求失败, 通道未在空闲状态, caller = %s, callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, Caller, Callee);
- return false;
- }
- m_CalleeNum = Callee;
- m_CallerNum = Caller;
- if(AccountId == INVALID_ID_SIP_ACCOUNT) // 呼叫内线
- m_pImplement = &ms_Implement4Exten;
- else
- m_pImplement = &ms_Implement4Trunk;
- return m_pImplement->makeCall(*this, AccountId);
- }
- /*****************************************************************
- **【函数名称】 answer
- **【函数功能】 应答呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::answer( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行应答请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- if(m_State == GCST_CONNECTED)
- {
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
- return true;
- }
- else
- return false;
- }
- /*****************************************************************
- **【函数名称】 playSound
- **【函数功能】 放音收号
- **【参数】 pContent 放音内容
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::playSound( PlayVoiceContent* pContent )
- {
- ASSERT(pContent != NULL);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行放音请求, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, pContent->szFileName);
- if(m_State != GCST_CONNECTED)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]放音失败, 通道未处于连接状态, AudioFile = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, pContent->szFileName);
- return false;
- }
- return m_Mixer.playSound(pContent);
- }
- /*****************************************************************
- **【函数名称】 playTone
- **【函数功能】 播放信号音
- **【参数】 Type 信号音类型
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::playTone( int Type )
- {
- return m_Mixer.playTone(Type);
- }
- /*****************************************************************
- **【函数名称】 playStop
- **【函数功能】 停止放音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::playStop( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行停止放音请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return m_Mixer.playStop();
- }
- /*****************************************************************
- **【函数名称】 startRecord
- **【函数功能】 开始录音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::startRecord( RecordContent* pContent )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行录音请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- if(m_State == GCST_NULL)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]录音失败, 通道状态空闲"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- return m_Mixer.startRecord(pContent);
- }
- /*****************************************************************
- **【函数名称】 stopRecord
- **【函数功能】 停止录音
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::stopRecord( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行停止录音请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return m_Mixer.stopRecord();
- }
- /*****************************************************************
- **【函数名称】 monitor
- **【函数功能】 监听
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::monitor( COneLeg* pTalker, bool IsStop )
- {
- ASSERT(pTalker != NULL);
- if(IsStop)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行取消监听请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return pTalker->cancelMonitor(this);
- }
- else
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行监听请求"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- if(m_State != GCST_CONNECTED)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]监听失败, 通道未处于连接状态"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- return pTalker->allowMonitor(this);
- }
- }
- /*****************************************************************
- **【函数名称】 allowMonitor
- **【函数功能】 允许监听
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::allowMonitor( COneLeg* pMonitorParty )
- {
- if(m_State != GCST_CONNECTED)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]接受监听失败, 通道未处于连接状态"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- if(!m_Mixer.allowedMonitor())
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]接受监听失败, 无空闲混音发端可连接"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- return false;
- }
- return m_Mixer.setupMonitor(pMonitorParty->routeChannel());
- }
- /*****************************************************************
- **【函数名称】 cancelMonitor
- **【函数功能】 取消监听
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::cancelMonitor( COneLeg* pMonitorParty )
- {
- ASSERT(pMonitorParty != NULL);
- return m_Mixer.undoMonitor(pMonitorParty->routeChannel());
- }
- /*****************************************************************
- **【函数名称】 freeResBinded
- **【函数功能】 释放绑定资源
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::freeResBinded( void )
- {
- if(m_pBindIpmCh != NULL)
- {
- m_pBindIpmCh->reset();
- m_pBindIpmCh = NULL;
- }
- }
- /*****************************************************************
- **【函数名称】 onDevEvent
- **【函数功能】 设备事件处理函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::onDevEvent( METAEVENT* pMetaEvent )
- {
- ASSERT(pMetaEvent != NULL);
- switch(pMetaEvent->evttype)
- {
- case GCEV_OFFERED: // 呼入
- __onOffered(pMetaEvent);
- break;
- case GCEV_DIALING:
- {
- m_State = GCST_DIALING;
- CMC::GetInstance().onDevResState(m_Id);
- }
- break;
- case GCEV_ACCEPT:
- m_State = GCST_ACCEPTED;
- break;
- case GCEV_ALERTING:
- __onAlerting(pMetaEvent);
- break;
- case GCEV_PROGRESSING:
- __onProgressing();
- break;
- case GCEV_CONNECTED:
- __onConnected(pMetaEvent);
- break;
- case GCEV_ANSWERED:
- __onAnswered();
- break;
- case GCEV_DROPCALL:
- __onCallFinish();
- break;
- case GCEV_DISCONNECTED:
- __onDiconnected(pMetaEvent);
- break;
- case GCEV_SIP_RECVREINVITE:
- __onRecvReinvite(pMetaEvent);
- break;
- case GCEV_SIP_RECVREINVITEACK:
- __onRecvReinviteAck(pMetaEvent);
- break;
- case GCEV_SIP_RECVINFO:
- __onRecvInfo(pMetaEvent);
- break;
- case GCEV_SIP_RECVUPDATE:
- __onRecvUpdate(pMetaEvent);
- break;
- case GCEV_SIP_RECVSUBSCRIBE:
- __onRecvSubscribe(pMetaEvent);
- break;
- case GCEV_SIP_RECVMESSAGE:
- __onRecvMessage(pMetaEvent);
- break;
- case GCEV_SIP_RECVNOTIFY:
- __onRecvNotify(pMetaEvent);
- break;
- case GCEV_SIP_RECVREFER:
- __onRecvRefer(pMetaEvent);
- break;
- case GCEV_SIP_RECVOPTIONS:
- __onRecvOption(pMetaEvent);
- break;
- case GCEV_TASKFAIL:
- __onTaskFail();
- break;
- case GCEV_BLOCKED:
- {
- m_IsBlocked = true;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- }
- break;
- case GCEV_UNBLOCKED:
- {
- m_IsBlocked = false;
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]解除阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo);
- }
- break;
- default:
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 isInnerSipUser
- **【函数功能】 判断是否是内线SIP用户
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::isInnerSipUser( LPCTSTR User )
- {
- ASSERT(User != NULL);
- ISXSIP_REGUSER RegUser;
- return ISXE_gc_SipGetRegisterUser(User, &RegUser) == 0;
- }
- /*****************************************************************
- **【函数名称】 reinvite4T38
- **【函数功能】 为T38传真发送reinvite
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::reinvite4T38( void )
- {
- ISXSIP_IE_BODY_EX Body;
- __constructReinviteBody4T38(&Body);
- return ISX_gc_SIPSendReinvite(m_CallId, EV_ASYNC, &Body) == 0;
- }
- /*****************************************************************
- **【函数名称】 reply
- **【函数功能】 响应呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::reply( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行reply, State = %d"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_State);
- if(m_State == GCST_OFFERED) // 话机直接发起的呼叫请求
- {
- if(ISX_gc_AcceptCall(m_CallId, 0, EV_ASYNC) == 0)
- {
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_RING_BACK, m_CallerNum, m_CalleeNum);
- return true;
- }
- else
- {
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]AcceptCall失败, 呼叫释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return false;
- }
- }
- else if(m_State == GCST_CONNECTED) // ocx发出的呼叫请求
- {
- if(!playTone(CHANNEL_TONE_RINGBACK)) // 对a-leg放振铃音
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]播放回铃音失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- }
- return true;
- }
- else
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]响应呼叫时状态异常, 呼叫释放,m_CallId=%ld, Caller = %s, Callee = %s"),
- m_CallId,m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return false;
- }
- }
- /*****************************************************************
- **【函数名称】 progress
- **【函数功能】 呼叫进展
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::progress( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行progress, State = %d"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_State);
- switch(m_State)
- {
- case GCST_OFFERED:
- case GCST_ACCEPTED: // 话机直接发起的呼叫请求
- {
- GCPARAMEX_CALLPROGRESS gcCallProcess;
- __constructProgressBody(&gcCallProcess);
- ASSERT(m_pBindIpmCh != NULL);
- if(ISX_gc_CallProgress(m_CallId, 0, EV_ASYNC, &gcCallProcess) != 0 || !m_pBindIpmCh->startMedia())
- {
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]progress失败, 呼叫释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return false;
- }
- return true;
- }
- break;
- case GCST_CONNECTED: // ocx发出的呼叫请求
- {
- // 停止A-Leg的振铃音
- playTone(CHANNEL_TONE_NULL);
- return true;
- }
- break;
- default:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]progress状态异常, 呼叫释放, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return false;
- }
- }
- }
- /*****************************************************************
- **【函数名称】 accept
- **【函数功能】 应答呼叫
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CVoipChannel::accept( void )
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{VOIPCh}: 通道[%d-%d-%d]执行accept, State = %d"), m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_State);
- // b-leg接通
- switch(m_State)
- {
- case GCST_OFFERED:
- case GCST_ACCEPTED: // 话机直接发起的呼叫请求
- {
- GCPARAMEX_ANSWERCALL AnswerCallEx;
- __constructAnswerBody(&AnswerCallEx);
- if(ISX_gc_AnswerCall(m_CallId, 0, EV_ASYNC, &AnswerCallEx) != 0)
- {
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]呼叫释放, a-leg应答呼叫失败, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- return false;
- }
- }
- break;
- case GCST_CONNECTED: // ocx发出的呼叫请求
- {
- // 停止A-Leg的振铃音
- playTone(CHANNEL_TONE_NULL);
- CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
- }
- break;
- default:
- {
- ASSERT(FALSE);
- __clearCall(IPEC_SIPReasonStatus500ServerInternalError);
- LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{VOIPCh}: 通道[%d-%d-%d]呼叫释放, a-leg应答呼叫时处于异常状态, Caller = %s, Callee = %s"),
- m_Id.NodeNo, m_Id.BoardNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
- return false;
- }
- }
- return true;
- }
- /*****************************************************************
- **【函数名称】 onPlayEnd
- **【函数功能】 放音结束处理函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::onPlayEnd( LPCTSTR lpDtmf )
- {
- // 通知呼叫控制层放音结束事件
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_PLAY_END, lpDtmf);
- }
- /*****************************************************************
- **【函数名称】 onRecEnd
- **【函数功能】 录音结束处理函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::onRecEnd( UINT TaskId )
- {
- // 通知呼叫控制层录音结束事件
- CString strTmp;
- strTmp.Format(_T("%lu"), TaskId);
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_REC_END, strTmp);
- }
- /*****************************************************************
- **【函数名称】 onToneEnd
- **【函数功能】 tone音结束处理函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::onToneEnd( int ToneTp )
- {
- // TODO: do nothing
- }
- /*****************************************************************
- **【函数名称】 onFaxEnd
- **【函数功能】 传真结束处理函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CVoipChannel::onFaxEnd( bool IsSuccess, LPCTSTR Reason )
- {
- CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, IsSuccess ? DEV_CH_EVT_FAX_OK : DEV_CH_EVT_FAX_FAILED, Reason);
- __clearCall(IPEC_SIPReasonStatus200OK);
- }
- /*****************************************************************
- **【函数名称】 getStateStr
- **【函数功能】 返回状态字符串
- **【参数】
- **【返回值】
- ****************************************************************/
- LPCTSTR CVoipChannel::getStateStr( void ) const
- {
- if(m_IsBlocked)
- return _T("block");
- switch(m_State)
- {
- case GCST_NULL: return _T("free");
- case GCST_DIALING: return _T("calling");
- case GCST_OFFERED: return _T("alerting");
- case GCST_ALERTING: return _T("ringback");
- case GCST_CONNECTED: return _T("talking");
- default: return _T("unknown");
- }
- }
|