2 // Copyright (C) 2008 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef OSC_SERVER_HPP
20 #define OSC_SERVER_HPP
25 #include <boost/asio.hpp>
26 #include <boost/thread.hpp>
27 #include <boost/bind.hpp>
29 #include "branch_hints.hpp"
30 #include "osc_dispatcher.hpp"
32 #include "static_allocator.hpp"
33 #include "nova-tt/semaphore.hpp"
34 #include "nova-tt/thread_priority.hpp"
35 #include "nova-tt/name_thread.hpp"
42 using namespace boost::asio
;
43 using namespace boost::asio::ip
;
48 void start_receive(void)
50 thread_
= boost::thread(network_thread::start
, this);
56 if (!thread_
.joinable())
62 io_service
& get_io_service(void)
67 void send_udp(const char * data
, unsigned int size
, udp::endpoint
const & receiver
)
69 udp::socket
socket(io_service_
);
70 socket
.open(udp::v4());
71 socket
.send_to(boost::asio::buffer(data
, size
), receiver
);
75 static void start(network_thread
* self
)
77 #ifdef NOVA_TT_PRIORITY_RT
78 thread_set_priority_rt(thread_priority_interval_rt().first
);
80 name_thread("Network Receive");
88 io_service::work
work(io_service_
);
93 io_service io_service_
;
97 boost::thread thread_
;
101 private network_thread
,
102 private osc_dispatcher
105 osc_server(unsigned int port
):
106 socket_(network_thread::io_service_
, udp::endpoint(udp::v4(), port
))
108 network_thread::start_receive();
112 void add_responder(std::string
const & address
, osc_responder
* resp
)
114 osc_dispatcher::add_responder(address
, resp
);
117 void remove_responder(std::string
const & address
, osc_responder
* resp
)
119 osc_dispatcher::remove_responder(address
, resp
);
123 void start_receive(void)
125 socket_
.async_receive_from(
126 buffer(recv_buffer_
), remote_endpoint_
,
127 boost::bind(&osc_server::handle_receive
, this,
128 placeholders::error
, placeholders::bytes_transferred
));
131 void handle_receive(const boost::system::error_code
& error
,
132 std::size_t bytes_transferred
)
134 if (unlikely(error
== error::operation_aborted
))
135 return; /* we're done */
137 if (error
== error::message_size
)
139 overflow_vector
.insert(overflow_vector
.end(),
140 recv_buffer_
.begin(), recv_buffer_
.end());
146 std::cout
<< "osc_server received error code " << error
<< std::endl
;
151 if (overflow_vector
.empty())
152 osc_dispatcher::handle_packet(recv_buffer_
.begin(), bytes_transferred
);
155 overflow_vector
.insert(overflow_vector
.end(),
156 recv_buffer_
.begin(), recv_buffer_
.end());
158 osc_dispatcher::handle_packet(overflow_vector
.data(), overflow_vector
.size());
160 overflow_vector
.clear();
168 boost::array
<char, 1<<13 > recv_buffer_
;
169 udp::endpoint remote_endpoint_
;
171 typedef static_allocator
<char, 1<<20> string_allocator
; /* 1 MB memory pool ...
173 * not thread-safe, but that is
177 /* typedef std::basic_string<char, std::char_traits<char>, string_allocator> string; */
178 typedef std::string string
;
179 string overflow_vector
;
184 using detail::network_thread
;
185 using detail::osc_server
;
187 } /* namespace nova */
189 #endif /* OSC_SERVER_HPP */