Skip to content

Instantly share code, notes, and snippets.

@NeverLuckyKg
Created August 25, 2016 10:36
Show Gist options
  • Save NeverLuckyKg/fa8a652afdb15677e28788aa8f9a09b4 to your computer and use it in GitHub Desktop.
Save NeverLuckyKg/fa8a652afdb15677e28788aa8f9a09b4 to your computer and use it in GitHub Desktop.
#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