Created
August 25, 2016 10:36
-
-
Save NeverLuckyKg/fa8a652afdb15677e28788aa8f9a09b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <resip/stack/SipStack.hxx> | |
#include <resip/stack/TransactionUser.hxx> | |
#include <resip/stack/Helper.hxx> | |
#include <resip/stack/ExtensionParameter.hxx> | |
#include <resip/stack/EventStackThread.hxx> | |
#include <iostream> | |
#include <thread> | |
#include <sstream> | |
//g++ resip.cpp --std=c++11 -lpthread -lresip -lrutil -lresipares -o resip | |
class resiprocate_dialog : public resip::TransactionUser | |
{ | |
protected: | |
resip::Data m_name; | |
resip::SipStack& m_stack; | |
virtual void process_message(resip::SipMessage* message); | |
virtual void request_message(resip::SipMessage* message); | |
virtual void response_message(resip::SipMessage* message); | |
public: | |
resiprocate_dialog(const std::string& name, resip::SipStack& stack); | |
virtual const resip::Data& name() const { return m_name; } | |
virtual void process(int max_timeout); | |
virtual ~resiprocate_dialog() {}; | |
}; | |
class resiprocate_server | |
{ | |
resip::EventStackSimpleMgr m_stack_manager; | |
resip::SipStack* m_stack; | |
std::unique_ptr<resiprocate_dialog> m_dialog; | |
size_t m_threads_number; | |
volatile bool m_running; | |
virtual void worker(); | |
public: | |
explicit resiprocate_server(unsigned short port, bool ipv6, size_t threads_number); | |
virtual void run(); | |
virtual void stop(); | |
virtual ~resiprocate_server() {}; | |
}; | |
int main(int argc, char** argv) { | |
if (argc != 3) { | |
std::cout << "Usage: " << argv[0] << " port threads_number" << std::endl; | |
return 1; | |
} | |
try { | |
auto port = static_cast<unsigned short>(std::stoi(argv[1])); | |
auto threads_number = std::stoi(argv[2]); | |
resiprocate_server server(port, false, threads_number); | |
server.run(); | |
} catch (std::exception& e) { | |
std::cout << e.what() << std::endl; | |
} | |
return 0; | |
} | |
void resiprocate_dialog::process_message(resip::SipMessage* message) { | |
if (message->isRequest()) { | |
request_message(message); | |
} | |
if (message->isResponse()) { | |
response_message(message); | |
} | |
} | |
void resiprocate_dialog::request_message(resip::SipMessage* message) { | |
std::auto_ptr<resip::SipMessage> response(new resip::SipMessage()); | |
if (message->method() == resip::MethodTypes::ACK) { | |
return; | |
} | |
int code = message->method() == resip::MethodTypes::INVITE ? 300 : 405; | |
resip::Helper::makeResponse(*response, *message, code); | |
if (code == 300) { | |
auto& contacts = response->header(resip::h_Contacts); | |
for (long long i = 0; i < 2; ++i) { | |
resip::Uri uri; | |
uri.user() = resip::Data("username"); | |
uri.host() = resip::Data("host"); | |
uri.port() = 5060; | |
{ | |
static resip::ExtensionParameter param("dtg"); | |
std::string value = std::to_string(i); | |
uri.param(param) = resip::Data(value.c_str()); | |
} | |
contacts.push_back(resip::NameAddr(uri)); | |
} | |
} | |
m_stack.send(response, this); | |
} | |
void resiprocate_dialog::response_message(resip::SipMessage* message) {} | |
resiprocate_dialog::resiprocate_dialog(const std::string& name, resip::SipStack& stack) : m_name(name), m_stack(stack) {} | |
void resiprocate_dialog::process(int max_timeout) { | |
std::auto_ptr<resip::Message> message; | |
message.reset(mFifo.getNext(max_timeout)); | |
auto sip = dynamic_cast<resip::SipMessage*>(message.get()); | |
if (sip) { | |
process_message(sip); | |
} | |
} | |
void resiprocate_server::worker() { | |
while (m_running) { | |
m_dialog->process(1000); | |
} | |
} | |
resiprocate_server::resiprocate_server(unsigned short port, bool ipv6, size_t threads_number) | |
: m_stack_manager(NULL), m_threads_number(threads_number), m_running(false) { | |
//resip::Timer::T100; | |
resip::SipStackOptions options; | |
options.mStateless = true; | |
m_stack = &m_stack_manager.createStack(options); | |
auto ip_version = ipv6 ? resip::IpVersion::V6 : resip::IpVersion::V4; | |
m_stack->addTransport(resip::TransportType::TCP, port, ip_version, resip::StunSetting::StunEnabled); | |
m_stack->addTransport(resip::TransportType::UDP, port, ip_version, resip::StunSetting::StunEnabled); | |
{ | |
std::stringstream ss; | |
ss << "resip_" << port; | |
m_dialog = std::unique_ptr<resiprocate_dialog>(new resiprocate_dialog(ss.str(), *m_stack)); | |
//m_dialog = std::make_unique<resiprocate_dialog>(ss.str(), *m_stack); | |
} | |
m_stack->registerTransactionUser(*m_dialog); | |
} | |
void resiprocate_server::run() { | |
m_running = true; | |
m_stack_manager.getThread().run(); | |
std::list<std::thread> threads; | |
for (size_t i = 1; i < m_threads_number; i++) | |
threads.push_back(std::thread(std::bind(&resiprocate_server::worker, this))); | |
worker(); | |
for (auto it = threads.begin(); it != threads.end(); ++it) | |
it->join(); | |
m_stack_manager.getThread().shutdown(); | |
} | |
void resiprocate_server::stop() { | |
m_running = false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment