当前位置: 首页 > 工具软件 > reSIProcate > 使用案例 >

reSIProcate实现GB28181服务——注册、心跳、已注册用户存储、catalog、invite、info、subscribe

史淳
2023-12-01

为什么是reSIProcate

	我最初使用的是exosip2,但是个人感觉作为sipserver并不是很合适,因此找到了reSIProcate,
代码封装很好,就是资料比较少,在阅读demo和源码后先整理一份用于注册和心跳的demo,希望能帮助到大家。

特别说明

	我这个demo是stack和dum在独立的线程中,transport也在单独的线程中处理,因为是demo,
只测试了和海康摄像机的通信,也没有处理资源的销毁,只是作为参考,如果代码有不妥之处希望留言指正。
	好,废话不多说,上代码!

代码

.h:

/*
 * @Description: reSIProcate dum and stack code
 * @Version: 1.0
 * @Autor: gy
 * @Date: 2021-12-23 16:16:00
 * @LastEditors: gy
 * @LastEditTime: 2021-12-23 18:38:19
 * @FilePath: \txSIP\include\private\tx_reSIProcate.h
 */
#pragma once

#include "resip/stack/Dispatcher.hxx"
#include "resip/stack/EventStackThread.hxx"
#include "resip/stack/InteropHelper.hxx"
#include "resip/stack/SipStack.hxx"
#include "resip/stack/TransportThread.hxx"
#include "resip/stack/PlainContents.hxx"
#include "resip/stack/Contents.hxx"
#include "resip/stack/InvalidContents.hxx"
#include "resip/stack/EventStackThread.hxx"

#include "resip/dum/DumThread.hxx"
#include "resip/dum/InviteSessionHandler.hxx"
#include "resip/dum/KeepAliveManager.hxx"
#include "resip/dum/MasterProfile.hxx"
#include "resip/dum/PagerMessageHandler.hxx"
#include "resip/dum/RegistrationHandler.hxx"
#include "resip/dum/RegistrationPersistenceManager.hxx"
#include "resip/dum/ServerAuthManager.hxx"
#include "resip/dum/ServerInviteSession.hxx"
#include "resip/dum/ClientInviteSession.hxx"
#include "resip/dum/ServerPagerMessage.hxx"
#include "resip/dum/ServerRegistration.hxx"
#include "resip/dum/UserAuthInfo.hxx"
#include "resip/dum/InMemorySyncRegDb.hxx"
#include "resip/dum/ClientPagerMessage.hxx"
#include "resip/dum/OutOfDialogHandler.hxx"
#include "resip/dum/ServerOutOfDialogReq.hxx"
#include "resip/dum/SubscriptionHandler.hxx"

#include "rutil/DnsUtil.hxx"
#include "rutil/GeneralCongestionManager.hxx"
#include "rutil/Inserter.hxx"
#include "rutil/Logger.hxx"
#include "rutil/MD5Stream.hxx"
#include "rutil/SelectInterruptor.hxx"
#include "rutil/WinLeakCheck.hxx"

#include <algorithm>

#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST

class TestInviteSessionHandler : public resip::InviteSessionHandler, public resip::OutOfDialogHandler
{
public:
   resip::Data name;
   resip::ClientInviteSessionHandle m_ci;

   TestInviteSessionHandler(const resip::Data& n) : name(n)
   {
   }

   virtual ~TestInviteSessionHandler()
   {
   }

   void SendInfo() {
      resip::Data infoStr("PAUSE MANRTSP/1.0\r\n"
         "CSeq: 1\r\n"
         "PauseTime: now\r\n");

      static resip::Mime type("Application", "MANSRTSP");
      resip::InvalidContents info = resip::InvalidContents(infoStr, type, type);
      m_ci.get()->info(info);
   }

   void ByeTer() {
      this->terminate(m_ci);
   }

   virtual void onNewSession(resip::ClientInviteSessionHandle ci, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg)
   {
      std::cout << name << ": ClientInviteSession-onNewSession - " << msg.brief() << std::endl;
      m_ci = ci;
   }

   virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg)
   {
      std::cout << name << ": ServerInviteSession-onNewSession - " << msg.brief() << std::endl;
   }

   virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": ClientInviteSession-onFailure - " << msg.brief() << std::endl;
   }

   virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": ClientInviteSession-onProvisional - " << msg.brief() << std::endl;
   }

   virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": ClientInviteSession-onConnected - " << msg.brief() << std::endl;
   }

   virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle handle)
   {
      std::cout << name << ": ClientInviteSession-onStaleCallTimeout" << std::endl;
   }

   virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onConnected - " << msg.brief() << std::endl;
   }

   virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": ClientInviteSession-onRedirected - " << msg.brief() << std::endl;
   }

   virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg)
   {
      std::cout << name << ": -----------------------------------------------------InviteSession-onTerminated - " << msg->brief() << std::endl;
      //assert(0); // This is overriden in UAS and UAC specific handlers
   }

   virtual void onAnswer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp)
   {
      std::cout << name << ":------------------------------------------------------------------------  InviteSession-onAnswer(SDP)" << std::endl;
      sdp.encode(std::cout);
   }

   virtual void onOffer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp)
   {
      std::cout << name << ":InviteSession-onOffer(SDP)" << std::endl;
      //sdp.encode(cout);
   }

   virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp)
   {
      std::cout << name << ": InviteSession-onEarlyMedia(SDP)" << std::endl;
      //sdp->encode(cout);
   }

   virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onOfferRequired - " << msg.brief() << std::endl;
   }

   virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg)
   {
      std::cout << name << ": InviteSession-onOfferRejected" << std::endl;
   }

   virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onRefer - " << msg.brief() << std::endl;
   }

   virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onReferAccepted - " << msg.brief() << std::endl;
   }

   virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onReferRejected - " << msg.brief() << std::endl;
   }

   virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onReferNoSub - " << msg.brief() << std::endl;
   }

   virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onInfo - " << msg.brief() << std::endl;
   }

   virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onInfoSuccess - " << msg.brief() << std::endl;
   }

   virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onInfoFailure - " << msg.brief() << std::endl;
   }

   virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onMessage - " << msg.brief() << std::endl;
   }

   virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onMessageSuccess - " << msg.brief() << std::endl;
   }

   virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg)
   {
      std::cout << name << ": InviteSession-onMessageFailure - " << msg.brief() << std::endl;
   }

   virtual void onForkDestroyed(resip::ClientInviteSessionHandle)
   {
      std::cout << name << ": ClientInviteSession-onForkDestroyed" << std::endl;
   }

   // Out-of-Dialog Callbacks
   virtual void onSuccess(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& successResponse)
   {
      std::cout << name << ": ClientOutOfDialogReq-onSuccess - " << successResponse.brief() << std::endl;
   }
   virtual void onFailure(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& errorResponse)
   {
      std::cout << name << ": ClientOutOfDialogReq-onFailure - " << errorResponse.brief() << std::endl;
   }
   virtual void onReceivedRequest(resip::ServerOutOfDialogReqHandle ood, const resip::SipMessage& request)
   {
      std::cout << name << ": ServerOutOfDialogReq-onReceivedRequest - " << request.brief() << std::endl;
      // Add SDP to response here if required
      std::cout << name << ": Sending 200 response to OPTIONS." << std::endl;
      ood->send(ood->answerOptions());
   }
};

class ClientMessageHandler : public  resip::ClientPagerMessageHandler {
public:
   ClientMessageHandler() : _ended(false) {};
   virtual void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status)
   {
      InfoLog(<< "ClientMessageHandler::onSuccess\n");
      _ended = true;
   }
   virtual void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents)
   {
      InfoLog(<< "ClientMessageHandler::onFailure\n");
      _ended = true;
   }
   bool isEnded() { return _ended; };
private:
   bool _ended;
};

class ServerMessageHandler : public resip::ServerPagerMessageHandler {
public:
   ServerMessageHandler() : _rcvd(false) {};
   bool isRcvd() { return _rcvd; };
   virtual void onMessageArrived(resip::ServerPagerMessageHandle handle,
      const resip::SipMessage &message) {
      std::cout << "Message rcv #############: " << message << "\n";

      auto ok = handle->accept();
      handle->send(std::move(ok));

      resip::Contents *body = message.getContents();
      std::cout << "Message rcv $$$$$$$$$$$$$$: " << *body << "\n";

      _rcvd = true;
   }

private:
   bool _rcvd;
};

class UserAuthGrabber : public resip::Worker
{
public:
   UserAuthGrabber() {}
   virtual ~UserAuthGrabber() {}

   virtual bool process(resip::ApplicationMessage* msg);
   virtual UserAuthGrabber* clone() const;
protected:
};

//A1=(user):(realm):(password)
bool UserAuthGrabber::process(resip::ApplicationMessage* msg) {
   resip::UserAuthInfo* uainf = dynamic_cast<resip::UserAuthInfo*>(msg);
   if (uainf)
   {
      resip::MD5Stream md5s;
      md5s << uainf->getUser() << resip::Symbols::COLON << uainf->getRealm() << resip::Symbols::COLON << "123456";
      uainf->setA1(md5s.getHex());
      if (uainf->getA1().empty()) {
         uainf->setMode(resip::UserAuthInfo::UserUnknown);
      }
      DebugLog(<< "Grabbed user info for " << uainf->getUser() << "@" << uainf->getRealm() << " : " << uainf->getA1());
      return true;
   }
   return false;
}

UserAuthGrabber* UserAuthGrabber::clone() const {
   return new UserAuthGrabber();
}

class ReproServerAuthManager : public resip::ServerAuthManager
{
public:
   ReproServerAuthManager(resip::DialogUsageManager& dum,
      resip::Dispatcher* authRequestDispatcher,
      bool useAuthInt,
      bool rejectBadNonces,
      bool challengeThirdParties,
      const resip::Data& staticRealm = resip::Data::Empty);

   ~ReproServerAuthManager();

protected:
   //this call back should async cause a post of UserAuthInfo
   virtual void requestCredential(const resip::Data& user,
      const resip::Data& realm,
      const resip::SipMessage& msg,
      const resip::Auth& auth,
      const resip::Data& transactionId);

   virtual bool useAuthInt() const;
   virtual bool rejectBadNonces() const;

   //不是proxy,proxy回407,uas回401
   virtual bool proxyAuthenticationMode() const {
      return false;
   }

   virtual resip::AsyncBool requiresChallenge(const resip::SipMessage& msg);

   bool authorizedForThisIdentity(const resip::Data &user,
      const resip::Data &realm,
      resip::Uri &fromUri);

private:
   resip::DialogUsageManager& mDum;
   resip::Dispatcher* mAuthRequestDispatcher;
   bool mUseAuthInt;
   bool mRejectBadNonces;
};

ReproServerAuthManager::ReproServerAuthManager(resip::DialogUsageManager& dum,
   resip::Dispatcher* authRequestDispatcher,
   bool useAuthInt,
   bool rejectBadNonces,
   bool challengeThirdParties,
   const resip::Data& staticRealm) :
   resip::ServerAuthManager(dum, dum.dumIncomingTarget(), challengeThirdParties, staticRealm),
   mDum(dum),
   mAuthRequestDispatcher(authRequestDispatcher),
   mUseAuthInt(useAuthInt),
   mRejectBadNonces(rejectBadNonces) {
}

ReproServerAuthManager::~ReproServerAuthManager() {
}

bool ReproServerAuthManager::useAuthInt() const {
   return mUseAuthInt;
}

bool ReproServerAuthManager::rejectBadNonces() const {
   return mRejectBadNonces;
}

resip::AsyncBool ReproServerAuthManager::requiresChallenge(const resip::SipMessage& msg) {
   //resip_assert(msg.isRequest());
   //控制哪些命令需要鉴权
   if (msg.header(resip::h_RequestLine).method() == resip::REGISTER) {
      return resip::True;
   }
   return resip::False;
}

bool ReproServerAuthManager::authorizedForThisIdentity(const resip::Data &user,
   const resip::Data &realm,
   resip::Uri &fromUri)
{
   // !rwm! good enough for now.  TODO eventually consult a database to see what
   // combinations of user/realm combos are authorized for an identity

   // First try the form where the username parameter in the auth
   // header is just the username component of the fromUri
   //
   //if ((fromUri.user() == user) && (fromUri.host() == realm))
   //不检查了
      return true;

   // Now try the form where the username parameter in the auth
   // header is the full fromUri, e.g.
   //    Proxy-Authorization: Digest username="user@domain" ...
   //
   if (fromUri.getAorNoPort() == user)
      return true;

   // catch-all: access denied
   return false;
}


void ReproServerAuthManager::requestCredential(const resip::Data& user,
   const resip::Data& realm,
   const resip::SipMessage& msg,
   const resip::Auth& auth,
   const resip::Data& transactionId) {
   //Build a UserAuthInfo object and pass to UserAuthGrabber to have a1 password filled in
   resip::UserAuthInfo* async = new resip::UserAuthInfo(user, realm, transactionId, &mDum);
   std::unique_ptr<resip::ApplicationMessage> app(async);
   mAuthRequestDispatcher->post(app);
}

class Registrar : public resip::ServerRegistrationHandler
{
public:
   Registrar(){};
   virtual ~Registrar() {};

   virtual void onRefresh(resip::ServerRegistrationHandle sr, const resip::SipMessage& reg) {
      std::cout << "onRefresh" << std::endl;
      //刷新成功后回复
      sr->accept();
   }
   virtual void onRemove(resip::ServerRegistrationHandle sr, const resip::SipMessage& reg) {
      std::cout << "onRemove" << std::endl;
      //注销成功后回复
      sr->accept();
   }
   virtual void onRemoveAll(resip::ServerRegistrationHandle sr, const resip::SipMessage& reg) {
      std::cout << "onRemoveAll" << std::endl;
   }
   virtual void onAdd(resip::ServerRegistrationHandle sr, const resip::SipMessage& reg) {
      std::cout << "onAdd" << std::endl;
      //认证成功后回复
      //TODO 获取实际ip和端口
      resip::Data remoteIp =  reg.getSource().presentationFormat();
      int remotePort = reg.getSource().getPort();

      resip::SipMessage success;
      resip::Helper::makeResponse(success, reg, 200);
      if (!reg.empty(resip::h_Paths))
      {
         success.header(resip::h_Paths) = reg.header(resip::h_Paths);
         success.header(resip::h_Supporteds).push_back(resip::Token(resip::Symbols::Path));
      }
      
      resip::DateCategory curTime(resip::GB28181Date);
      success.header(resip::h_Date) = curTime;
      sr->accept(success);
   }
   virtual void onQuery(resip::ServerRegistrationHandle sr, const resip::SipMessage& reg) {
      std::cout << "onQuery" << std::endl;
   }
};

class UasKeepAliveManager : public resip::KeepAliveManager {
};

class UasSubscriptionHandler : public resip::ServerSubscriptionHandler {
public:
   UasSubscriptionHandler() {}
   ~UasSubscriptionHandler() {}

   void onNewSubscription(resip::ServerSubscriptionHandle handle, const resip::SipMessage& sub) {
      std::cout << " onNewSubscription  " << std::endl;
      auto ok = handle->accept(200);

      handle->send(std::move(ok));
   }

   void onTerminated(resip::ServerSubscriptionHandle handler) {
      std::cout << " onTerminated  " << std::endl;
   }

};

class GBTest {
public:
   GBTest();
   virtual ~GBTest() {}

   /**
    * @description:
    * @param {*}
    * @return {*}
    * @author: gy
    */
   int Run();

   void SendCatalog() {
      std::list<resip::Uri> mylist;
      m_InMemorySyncRegDb->getAors(mylist);

      auto finduri = [=](resip::Uri uri) {
         std::cout << "finduri" << std::endl;
         //FIXME 海康有些老机型对34020000001320000001@3402000000这种信令的接收支持不好
         //信令会发生处理的延时,原因可能是相机配置了DNS
         //resip::Uri dsturi("sip:34020000001320000001@192.168.12.223:5060");
         //resip::NameAddr destAddr(dsturi);
         resip::NameAddr destAddr(uri);
         resip::ClientPagerMessageHandle msgHandle = m_Dum->makePagerMessage(destAddr);

         static resip::Mime typeXML("Application", "MANSCDP+xml");
         std::unique_ptr<resip::Contents> content(new resip::PlainContents(resip::Data("<?xml version=\"1.0\"?>\r\n<Query>\r\n\
<CmdType>Catalog</CmdType>\r\n<SN>4</SN>\r\n\
<DeviceID>34020000001320000001</DeviceID>\r\n\
</Query>\r\n"), typeXML));
         resip::SipMessage &msg = msgHandle->getMessageRequest();

         resip::Uri duri("sip:34020000001320000001@192.168.12.223:5060");
         msg.setForceTarget(duri);
         msgHandle->page(std::move(content));
      };
      std::for_each(mylist.begin(), mylist.end(), finduri);

   }

   void SendInvite() {
      std::list<resip::Uri> mylist;
      m_InMemorySyncRegDb->getAors(mylist);

      auto finduri = [=](resip::Uri uri) {
         std::cout << "finduri" << std::endl;

         //catalog得到设备后打开设备to要传设备ID,和之前的理解不同
         resip::Uri tduri("sip:34020000001320000005@340200000");
         resip::NameAddr destAddr(tduri);
         resip::Data sdpStr("v=0\r\n"
            "o=34020000001320000005 0 0 IN IP4 192.168.12.118\r\n"
            "s=Play\r\n"
            "c=IN IP4 192.168.12.118\r\n"
            "t=0 0\r\n"
            "m=video 6000 RTP/AVP 96 98 97\r\n"
            "a=recvonly\r\n"
            "a=rtpmap:96 PS/90000\r\n"
            "a=rtpmap:98 H264/90000\r\n"
            "a=rtpmap:97 MPEG4/90000\r\n"
            "y=0000001024\r\n"
            "f=\r\n");

         static  resip::Mime inviteType("Application", "SDP");
         resip::HeaderFieldValue hfv(sdpStr.data(), (unsigned int)sdpStr.size());
         resip::SdpContents sdp = resip::SdpContents(hfv, inviteType);
         auto invitemsg = m_Dum->makeInviteSession(
            destAddr,
            &sdp);

         resip::DateCategory curTime(resip::GB28181Date);
         invitemsg->header(resip::h_Date) = curTime;

         //添加subject
         resip::StringCategory subject("34020000001320000005:4020000001320000005,34020000002000000001:0");
         invitemsg->header(resip::h_Subject) = subject;

         resip::Uri duri("sip:34020000001230000001@192.168.12.115:5060");
         invitemsg->setForceTarget(duri);
         m_Dum->send(std::move(invitemsg));
      };
      std::for_each(mylist.begin(), mylist.end(), finduri);
   }

   void SendInfo() {
      m_TestInviteSessionHandler->SendInfo();
   }

   void SendBye() {
      m_TestInviteSessionHandler->ByeTer();
   }

   void SendSubscribe() {
      std::list<resip::Uri> mylist;
      m_InMemorySyncRegDb->getAors(mylist);

      auto finduri = [=](resip::Uri uri) {
         std::cout << "finduri" << std::endl;

         //catalog得到设备后打开设备to要传设备ID,和之前的理解不同
         resip::Uri tduri("sip:34020000001320000005@3402000000");
         resip::NameAddr destAddr(tduri);

         resip::Data eventType(resip::Symbols::Presence);
         auto msg = m_Dum->makeSubscription(destAddr, eventType, 90);

         static resip::Mime typeXML("Application", "MANSCDP+xml");
         std::unique_ptr<resip::Contents> content(new resip::PlainContents(resip::Data("<?xml version=\"1.0\"?>\r\n<Query>\r\n\
<CmdType>Alarm</CmdType>\r\n<SN>17430</SN>\r\n\
<DeviceID>34020000001320000005</DeviceID>\r\n\
<StartAlarmPriority>1</StartAlarmPriority>\r\n\
<EndAlarmPriority>4</EndAlarmPriority>\r\n\
<AlarmMethod>0</AlarmMethod>\r\n\
<StartTime>2022-03-09T00:00:00</StartTime>\r\n\
<EndTime>2022-03-09T23:59:59</EndTime>\r\n\
</Query>\r\n"), typeXML));
         msg->setContents(std::move(content));

         resip::Uri duri("sip:34020000001230000001@192.168.12.115:5060");
         msg->setForceTarget(duri);
         m_Dum->send(std::move(msg));
      };
      std::for_each(mylist.begin(), mylist.end(), finduri);

   }

private:
   resip::FdPollGrp *m_PollGrp;
   resip::EventThreadInterruptor *m_EventIntr;
   resip::SipStack *m_Stack;
   resip::DialogUsageManager *m_Dum;
   resip::Transport *m_StackTCPTrans;
   resip::Transport *m_StackUDPTrans;
   resip::TransportThread *m_StackTCPThread;
   resip::TransportThread *m_StackUDPThread;
   resip::ServerRegistrationHandler *m_ServerRegHandler;
   resip::Dispatcher *m_Dispatcher;
   resip::InMemorySyncRegDb *m_InMemorySyncRegDb;
   ServerMessageHandler *m_ServerMsgHandler;
   TestInviteSessionHandler *m_TestInviteSessionHandler;
   UasSubscriptionHandler *m_UasSubscriptionHandler;

   std::shared_ptr<resip::ThreadIf> m_DumThreadIf;
   std::shared_ptr<resip::ThreadIf> m_StackThreadIf;
   std::shared_ptr<resip::ServerAuthManager> m_ServerAuthManager;
};
/*
 * @Description:
 * @Version: 1.0
 * @Autor: gy
 * @Date: 2021-12-23 10:09:20
 * @LastEditors: gy
 * @LastEditTime: 2022-02-28 18:32:36
 * @FilePath: \resiprocate\GBTest\GBTest.cxx
 */
#include "GBTest.hxx"

#include <iostream>

#ifdef WIN32
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "Dnsapi.lib")
#pragma comment(lib, "rutil.lib")
#pragma comment(lib, "resiprocate.lib")
#pragma comment(lib, "ares.lib")
#pragma comment(lib, "dum.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")
#else
#endif

using namespace std;
using namespace resip;

GBTest::GBTest() {
   m_PollGrp = FdPollGrp::create("event");
   m_EventIntr = new EventThreadInterruptor(*m_PollGrp);

   SipStackOptions options;
   options.mAsyncProcessHandler = m_EventIntr;
   options.mPollGrp = m_PollGrp;
   m_Stack = new SipStack(options);
   m_Dum = new DialogUsageManager(*m_Stack);
}

int GBTest::Run() {
   Data bindAddr("0.0.0.0");
   if (!bindAddr.size()) {
      bindAddr = DnsUtil::getLocalHostName();
   }

   int tpFlags = RESIP_TRANSPORT_FLAG_OWNTHREAD
      | RESIP_TRANSPORT_FLAG_RXALL
      | RESIP_TRANSPORT_FLAG_TXALL
      | RESIP_TRANSPORT_FLAG_KEEP_BUFFER
      | RESIP_TRANSPORT_FLAG_TXNOW;
   m_StackUDPTrans = m_Stack->addTransport(UDP, 5060, V4, StunDisabled, bindAddr, 
                           /*sipDomain*/Data::Empty, 
                           /*keypass*/Data::Empty, 
                           SecurityTypes::NoSSL,
                           tpFlags);
   //m_StackTCPTrans = m_Stack->addTransport(TCP, 5060, V4, StunDisabled, bindAddr);
   m_Stack->setStatisticsInterval(10);

   //单独线程处理transport
   m_StackUDPThread = new TransportThread(*m_StackUDPTrans);
   m_StackUDPThread->run();
   //m_StackTCPThread = new TransportThread(*m_StackTCPTrans);
   //m_StackTCPThread->run();

   //重设拥塞控制
   //std::shared_ptr<CongestionManager> uasCongestionManager;
   //uasCongestionManager.reset(
   //   new GeneralCongestionManager(GeneralCongestionManager::WAIT_TIME, 200));
   //m_Stack->setCongestionManager(uasCongestionManager.get());

   //dum配置
   auto profile = std::make_shared<MasterProfile>();
   profile->clearSupportedMethods();
   profile->addSupportedMethod(resip::REGISTER);
   profile->addSupportedMethod(resip::INVITE);
   profile->addSupportedMethod(resip::BYE);
   profile->addSupportedMethod(resip::UNKNOWN);
   profile->addSupportedMethod(resip::MESSAGE);
   profile->addSupportedMethod(resip::SUBSCRIBE);
   profile->addSupportedMethod(resip::ACK);
   profile->addSupportedMethod(resip::NOTIFY);
   profile->addSupportedMethod(resip::PUBLISH);
   profile->addSupportedMethod(resip::INFO);
   profile->addSupportedMethod(resip::CANCEL);

   //国标特殊设置
   static Mime typeXML("Application", "MANSCDP+xml");
   profile->addSupportedMimeType(resip::MESSAGE, typeXML);
   profile->addSupportedMimeType(resip::SUBSCRIBE, typeXML);
   profile->addSupportedMimeType(resip::PUBLISH, typeXML);
   profile->addSupportedMimeType(resip::NOTIFY, typeXML);
   static Mime typeRTSP("Application", "MANSRTSP");
   profile->addSupportedMimeType(resip::INFO, typeRTSP);

   Token toke("GB2312");
   profile->addSupportedEncoding(toke);
   profile->setRportEnabled(InteropHelper::getRportEnabled());
   profile->allowBadRegistrationEnabled() = true;
   profile->setUserAgent("txce");

   NameAddr uri("sip:34020000002000000001@3402000000");
   profile->setDefaultFrom(uri);

   //设置dum
   m_Dum->setMasterProfile(profile);

   //注册方法
   std::unique_ptr<Worker> userWorker(new UserAuthGrabber);
   m_Dispatcher = new Dispatcher(std::move(userWorker), m_Stack);

   //设置认证管理器
   m_ServerAuthManager.reset(new ReproServerAuthManager(*m_Dum, m_Dispatcher, false, false, true, "3402000000"));
   m_Dum->setServerAuthManager(m_ServerAuthManager);

   //设置注册消息处理
   m_ServerRegHandler = new Registrar;
   m_Dum->setServerRegistrationHandler(m_ServerRegHandler);

   //已注册信息处理
   m_InMemorySyncRegDb = new InMemorySyncRegDb();
   m_Dum->setRegistrationPersistenceManager(m_InMemorySyncRegDb);


   //Install rules so that the registrar only gets REGISTERs
   resip::MessageFilterRuleList ruleList;
   resip::MessageFilterRule::MethodList methodList;
   methodList.push_back(resip::REGISTER);
   ruleList.push_back(MessageFilterRule(resip::MessageFilterRule::SchemeList(),
      resip::MessageFilterRule::DomainIsMe,
      methodList));

   //心跳处理
   std::unique_ptr<KeepAliveManager> uasKaMng(new UasKeepAliveManager);
   m_Dum->setKeepAliveManager(std::move(uasKaMng));

   //设置UAC msg处理类
   ClientMessageHandler *cmh = new ClientMessageHandler();
   m_Dum->setClientPagerMessageHandler(cmh);

   //设置UAS msg处理类
   m_ServerMsgHandler = new ServerMessageHandler();
   m_Dum->setServerPagerMessageHandler(m_ServerMsgHandler);
   
   //invite处理类
   m_TestInviteSessionHandler = new TestInviteSessionHandler("test invite");
   m_Dum->setInviteSessionHandler(m_TestInviteSessionHandler);

   //设置UAS notify接收类, 注意event类型按国标定义为presence
   m_UasSubscriptionHandler = new UasSubscriptionHandler;
   m_Dum->addServerSubscriptionHandler(Symbols::Presence, m_UasSubscriptionHandler);

   //启动
   m_DumThreadIf.reset(new DumThread(*m_Dum));
   m_StackThreadIf.reset(new EventStackThread(*m_Stack, *m_EventIntr, *m_PollGrp));
   //m_Dum->setMessageFilterRuleList(ruleList);
   m_Stack->run();
   m_DumThreadIf->run();
   m_StackThreadIf->run();
   return 0;
}

void GBTest_init() {
   cout << __FUNCTION__ << endl;
   //init reSip log
   const char *logType = "cout";
   const char *logLevel = "DEBUG";
   Log::initialize(logType, logLevel, "reSIProcate");
}

void * GBTest_openstack() {
   cout << __FUNCTION__ << endl;
   GBTest *stack = new GBTest();
   stack->Run();
   return (void *)stack;
}

void GBTest_SendCatalog(GBTest *stack) {
   stack->SendCatalog();
}

void GBTest_SendInvite(GBTest *stack) {
   stack->SendInvite();
}

void GBTest_SendInfo(GBTest *stack) {
   stack->SendInfo();
}

void GBTest_SendBye(GBTest *stack) {
   stack->SendBye();
}

void GBTest_SendSubscribe(GBTest *stack) {
   stack->SendSubscribe();
}

int main(int argc, char *avgv[]) {
   GBTest *stack = NULL;
   GBTest_init();
   stack = (GBTest *)GBTest_openstack();
   getchar();
   GBTest_SendCatalog(stack);
   getchar();
   GBTest_SendInvite(stack);
   getchar();
   GBTest_SendInfo(stack);
   getchar();
   GBTest_SendBye(stack);
   getchar();
   GBTest_SendSubscribe(stack);
   getchar();
   return 0;
}
 类似资料: