#include "StdAfx.h" #include "SipRegister.h" #include "Config.h" #include "DevVoip.h" CSipRegister::CSipRegister(CDevVoip* pParent, int AccountId) : m_pParent(pParent), m_SerialNo(0) { ASSERT(pParent != NULL); m_pAccount = CConfig::sipAccount().getAccount(AccountId); ASSERT(m_pAccount != NULL); m_RegTimer.SetTimedEvent(this, &CSipRegister::__regTimerFunc); } CSipRegister::~CSipRegister(void) { m_RegTimer.StopSafely(); } /***************************************************************** **【函数名称】 __regTimerFunc **【函数功能】 SIP注册定时器函数 **【参数】 **【返回值】 ****************************************************************/ void CSipRegister::__regTimerFunc( void ) { regist(); } /***************************************************************** **【函数名称】 regist **【函数功能】 注册 **【参数】 **【返回值】 ****************************************************************/ bool CSipRegister::regist( bool IsUnreg /*= false*/ ) { if(m_pAccount == NULL || !m_pAccount->IsReg) return false; SIP_REGISTER sSipRegister; memset(&sSipRegister, 0, sizeof(sSipRegister)); // 填充RegisterId信息 sSipRegister.RegisterId.ucIsxNo = m_pParent->nodeNo(); // 节点号 sSipRegister.RegisterId.ucBrdNo = m_pParent->boardNo(); // SIP 板号 m_SerialNo = m_pParent->makeSerialNo(); sSipRegister.RegisterId.ulSerialNo = m_SerialNo; // 序列号,有效范围 0~4095 #pragma region To头域 //填充To信息 ISXSIP_IE_TO* pTo = &(sSipRegister.To); pTo->Valid = 1; pTo->Addr.Valid = 1; pTo->Addr.AddType = ISXSIP_ADDTYPE_URL; lstrcpy(pTo->Addr.u.AddrUrl.User, m_pAccount->Account); lstrcpy(pTo->Addr.u.AddrUrl.Host, m_pAccount->Proxy); pTo->Addr.u.AddrUrl.PortNum = m_pAccount->ProxyPort; // 端口号;如果为0xFFFF,地址域中没有端口号部分; pTo->Addr.u.AddrUrl.IsSecure = 0; // 是否使用安全SIP,如果为0,未使用TLS,如果为1,使用TLS。 pTo->Addr.u.AddrUrl.MethodType = 0xFF; // SIP方法的类型,如果为0xFF,地址中没有SIP方法类型。 pTo->Addr.u.AddrUrl.TransportType = ISXSIP_TRANSPORT_UDP; // 传输类型,如果为0xFF,地址信息中没有传输类型信息。 pTo->Addr.u.AddrUrl.LrType = 0xFF; // 松散路由的类型;如果为0xFF,地址域中没有LrType部分;LrType可以为: pTo->Addr.u.AddrUrl.Ttl = 0xFFFF; // TTL值;如果为0xFFFF,地址域中没有TTL部分; // lstrcpy(pTo->Tag , "ehang"); //to头域中的tag部分,如果为空字符串,表示没有tag部分; // lstrcpy(pTo->DisplayName , "ehang"); //to 头域中的 display-name 部分,如果为空字符串,表示没有 display-name 部分; /* 如果reg.To.Addr.AddType = =0;则将填充下列字段 lstrcpy(reg.To.Addr.u.AddrUri.Identifier,"+1234567");//URI地址中的Identifier,如URI为"tel:+1234567",identifier为+1234567 lstrcpy(reg.To.Addr.u.AddrUri.Scheme ,"tel");//URI地址中的scheme,如URI为"tel:+1234567",scheme为tel; */ #pragma endregion #pragma region From头域 //填充From信息 ISXSIP_IE_FROM* pFrom = &(sSipRegister.From); pFrom->Valid = 1; pFrom->Addr.Valid = 1; pFrom->Addr.AddType = ISXSIP_ADDTYPE_URL; lstrcpy(pFrom->Addr.u.AddrUrl.User, m_pAccount->Account); lstrcpy(pFrom->Addr.u.AddrUrl.Host, m_pAccount->Proxy); pFrom->Addr.u.AddrUrl.PortNum = m_pAccount->ProxyPort; pFrom->Addr.u.AddrUrl.IsSecure = 0; pFrom->Addr.u.AddrUrl.MethodType = 0xFF; pFrom->Addr.u.AddrUrl.TransportType = ISXSIP_TRANSPORT_UDP; pFrom->Addr.u.AddrUrl.LrType = 0xFF; pFrom->Addr.u.AddrUrl.Ttl = 0xFFFF; #pragma endregion #pragma region RegAddr //填充RegAddr信息 sSipRegister.RegAddr.Valid = 1; sSipRegister.RegAddr.AddType = ISXSIP_ADDTYPE_URL; // lstrcpy(sSipRegister.RegAddr.u.AddrUrl.User, m_pAccount->Account) ; 此处如果赋值在注册时会得到400的错误码 lstrcpy(sSipRegister.RegAddr.u.AddrUrl.Host, m_pAccount->Proxy); sSipRegister.RegAddr.u.AddrUrl.PortNum = m_pAccount->ProxyPort; sSipRegister.RegAddr.u.AddrUrl.IsSecure = 0; sSipRegister.RegAddr.u.AddrUrl.MethodType = 0xFF; sSipRegister.RegAddr.u.AddrUrl.LrType = 0xFF; sSipRegister.RegAddr.u.AddrUrl.TransportType = 0xFF; sSipRegister.RegAddr.u.AddrUrl.Ttl = 0xFFFF; #pragma endregion #pragma region Contact //填充Contact信息 CHAR IpAddr[IP_PORT_LEN] = { 0 }; ISX_sr_getnet2cfg(m_pParent->nodeNo(), m_pParent->boardNo(), BT_SIP, IpAddr, NULL); ISXSIP_IE_CONTACT* pContact = &(sSipRegister.Contact); pContact->Valid = 1; pContact->IsStar = 0; pContact->Action = ISXSIP_CONTACT_ACTION_PROXY; pContact->Addr.Valid = 1; pContact->Addr.AddType = ISXSIP_ADDTYPE_URL; lstrcpy(pContact->Addr.u.AddrUrl.User, m_pAccount->Account); lstrcpy(pContact->Addr.u.AddrUrl.Host, IpAddr); pContact->Addr.u.AddrUrl.PortNum = 0xFFFF; pContact->Addr.u.AddrUrl.MethodType = 0xFF; pContact->Addr.u.AddrUrl.TransportType = 0xFF; pContact->Addr.u.AddrUrl.LrType = 0xFF; pContact->Addr.u.AddrUrl.IsSecure = 0; pContact->Addr.u.AddrUrl.Ttl = 0xFFFF; //下面是Contact头域中的超时部分,如果无效,表示contact头域中没有超时部分; pContact->Expires.Valid = 1; pContact->Expires.Type = ISXSIP_IE_EXPIRES_DELTA; // 0为Delta second,1为Date; if(IsUnreg) pContact->Expires.u.DeltaSeconds = 0; // 0 for unregister else pContact->Expires.u.DeltaSeconds = m_pAccount->RegInterval; #pragma endregion #pragma region Auth //填充u信息用于注册论证 AuthInfo:发送Register消息时使用该域;Author:接收到Register消息时使用该域 char* pUser = sSipRegister.u.LongAuthInfo.AuthStr; lstrcpy(pUser, m_pAccount->AuthAccount); char *pPwd = pUser + strlen(pUser) + 1; lstrcpy(pPwd, m_pAccount->Password); #pragma endregion return ISXE_gc_SIPSendRegister(EV_ASYNC, &sSipRegister) == 0; } /***************************************************************** **【函数名称】 onRegSent **【函数功能】 处理REG发送结果 **【参数】 **【返回值】 ****************************************************************/ void CSipRegister::onRegSent( SEND_SIPREG_RET* pSent ) { ASSERT(pSent != NULL); m_RegTimer.StopSafely(); if(pSent->sRetVal == 0) { #ifdef _DEBUG LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SipReg}: SIP板[%d-%d]账号[%d]发送注册消息成功"), pSent->RegisterId.ucIsxNo, pSent->RegisterId.ucBrdNo, m_pAccount->Id); #endif } else { m_RegTimer.Start(DEVICE_SIP_RETRY_INTERVAL * 1000, false, true); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SipReg}: SIP板[%d-%d]账号[%d]发送注册消息失败, %d秒后重试"), pSent->RegisterId.ucIsxNo, pSent->RegisterId.ucBrdNo, m_pAccount->Id, DEVICE_SIP_RETRY_INTERVAL); } } /***************************************************************** **【函数名称】 processRegResult **【函数功能】 处理REG结果 **【参数】 **【返回值】 ****************************************************************/ void CSipRegister::processRegResult( SIP_REGISTER_ACK* pAck ) { ASSERT(pAck != NULL); m_RegTimer.StopSafely(); if(pAck->usCause == IPEC_SIPReasonStatus200OK) { m_RegTimer.Start(m_pAccount->RegInterval * 1000, false, true); #ifdef _DEBUG LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SipReg}: SIP板[%d-%d]账号[%d]注册成功"), pAck->RegisterId.ucIsxNo, pAck->RegisterId.ucBrdNo, m_pAccount->Id); #endif } else { m_RegTimer.Start(DEVICE_SIP_RETRY_INTERVAL * 1000, false, true); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SipReg}: SIP板[%d-%d]账号[%d]注册失败, %d秒后重试, Cause = %d"), pAck->RegisterId.ucIsxNo, pAck->RegisterId.ucBrdNo, m_pAccount->Id, DEVICE_SIP_RETRY_INTERVAL, pAck->usCause); } }