Implement packet handler support for outgoing frames
uvgRTP can install handler f.ex. for collecting RTCP sender statistics information or to install SRTP encryption handler. This way these unrelated objects don't have to be passed to src/socket.cc and it will only contain code pertaining to actual socket operations
This commit is contained in:
parent
9ee2318384
commit
906f6e6853
|
@ -27,6 +27,18 @@ namespace uvg_rtp {
|
|||
|
||||
const int MAX_BUFFER_COUNT = 256;
|
||||
|
||||
typedef rtp_error_t (*packet_handler_buf)(void *, ssize_t, void *);
|
||||
typedef rtp_error_t (*packet_handler_vec)(void *, std::vector<std::pair<size_t, uint8_t *>>&);
|
||||
|
||||
struct socket_packet_handler {
|
||||
void *arg;
|
||||
|
||||
union {
|
||||
packet_handler_buf buf;
|
||||
packet_handler_vec vec;
|
||||
} handlers;
|
||||
};
|
||||
|
||||
class socket {
|
||||
public:
|
||||
socket(int flags);
|
||||
|
@ -138,6 +150,16 @@ namespace uvg_rtp {
|
|||
/* Get the out address for the socket if it exists */
|
||||
sockaddr_in& get_out_address();
|
||||
|
||||
/* Install a packet handler for buffer- or vector-based send operations.
|
||||
*
|
||||
* These handlers allow the caller to inject extra functionality to the send operation
|
||||
* without polluting src/socket.cc with unrelated code
|
||||
* (such as collecting RTCP session statistics info or encrypting a packet)
|
||||
*
|
||||
* "arg" is an optional parameter that can be passed to the handler when it's called */
|
||||
rtp_error_t install_handler(void *arg, packet_handler_buf handler);
|
||||
rtp_error_t install_handler(void *arg, packet_handler_vec handler);
|
||||
|
||||
private:
|
||||
/* helper function for sending UPD packets, see documentation for sendto() above */
|
||||
rtp_error_t __sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags, int *bytes_sent);
|
||||
|
@ -152,6 +174,12 @@ namespace uvg_rtp {
|
|||
uvg_rtp::srtp *srtp_;
|
||||
int flags_;
|
||||
|
||||
/* __sendto() calls these handlers in order before sending the packet*/
|
||||
std::vector<socket_packet_handler> buf_handlers_;
|
||||
|
||||
/* __sendtov() calls these handlers in order before sending the packet */
|
||||
std::vector<socket_packet_handler> vec_handlers_;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSABUF buffers_[MAX_BUFFER_COUNT];
|
||||
#else
|
||||
|
|
102
src/socket.cc
102
src/socket.cc
|
@ -135,6 +135,36 @@ socket_t& uvg_rtp::socket::get_raw_socket()
|
|||
return socket_;
|
||||
}
|
||||
|
||||
|
||||
rtp_error_t uvg_rtp::socket::install_handler(void *arg, packet_handler_buf handler)
|
||||
{
|
||||
if (!handler)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
socket_packet_handler hndlr;
|
||||
|
||||
hndlr.arg = arg;
|
||||
hndlr.handlers.buf = handler;
|
||||
buf_handlers_.push_back(hndlr);
|
||||
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::install_handler(void *arg, packet_handler_vec handler)
|
||||
{
|
||||
if (!handler)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
|
||||
socket_packet_handler hndlr;
|
||||
|
||||
hndlr.arg = arg;
|
||||
hndlr.handlers.vec = handler;
|
||||
vec_handlers_.push_back(hndlr);
|
||||
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::__sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags, int *bytes_sent)
|
||||
{
|
||||
int nsend = 0;
|
||||
|
@ -172,21 +202,57 @@ rtp_error_t uvg_rtp::socket::__sendto(sockaddr_in& addr, uint8_t *buf, size_t bu
|
|||
|
||||
rtp_error_t uvg_rtp::socket::sendto(uint8_t *buf, size_t buf_len, int flags)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.buf)(handler.arg, buf_len, buf)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet %p %zu %d", buf, buf_len, flags);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendto(addr_, buf, buf_len, flags, nullptr);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::sendto(uint8_t *buf, size_t buf_len, int flags, int *bytes_sent)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.buf)(handler.arg, buf_len, buf)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet %p %zu %d", buf, buf_len, flags);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendto(addr_, buf, buf_len, flags, bytes_sent);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags, int *bytes_sent)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.buf)(handler.arg, buf_len, buf)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet %p %zu %d", buf, buf_len, flags);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendto(addr, buf, buf_len, flags, bytes_sent);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::sendto(sockaddr_in& addr, uint8_t *buf, size_t buf_len, int flags)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.buf)(handler.arg, buf_len, buf)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet %p %zu %d", buf, buf_len, flags);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendto(addr, buf, buf_len, flags, nullptr);
|
||||
}
|
||||
|
||||
|
@ -261,16 +327,43 @@ rtp_error_t uvg_rtp::socket::__sendtov(
|
|||
|
||||
rtp_error_t uvg_rtp::socket::sendto(std::vector<std::pair<size_t, uint8_t *>> buffers, int flags)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.vec)(handler.arg, buffers)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendtov(addr_, buffers, flags, nullptr);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::sendto(std::vector<std::pair<size_t, uint8_t *>> buffers, int flags, int *bytes_sent)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.vec)(handler.arg, buffers)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendtov(addr_, buffers, flags, bytes_sent);
|
||||
}
|
||||
|
||||
rtp_error_t uvg_rtp::socket::sendto(sockaddr_in& addr, std::vector<std::pair<size_t, uint8_t *>> buffers, int flags)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.vec)(handler.arg, buffers)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendtov(addr, buffers, flags, nullptr);
|
||||
}
|
||||
|
||||
|
@ -280,6 +373,15 @@ rtp_error_t uvg_rtp::socket::sendto(
|
|||
int flags, int *bytes_sent
|
||||
)
|
||||
{
|
||||
rtp_error_t ret;
|
||||
|
||||
for (auto& handler : buf_handlers_) {
|
||||
if ((ret = (*handler.handlers.vec)(handler.arg, buffers)) != RTP_OK) {
|
||||
LOG_ERROR("Malfored packet");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return __sendtov(addr, buffers, flags, bytes_sent);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue