Commit 989b8dc7 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

rtp: add initial datagram socket abstraction

RTP and RTCP are packet-based. The low-level I/O abstraction needed is
similar but different from that of connection-oriented streams as
provided by `struct vlc_tls'. So this adds a new suitable abstraction
for the RTP plugin(s).
parent 6cf8a7f8
......@@ -6,6 +6,7 @@ librtp_plugin_la_SOURCES = \
access/rtp/xiph.c \
access/rtp/sdp.c access/rtp/sdp.h \
access/rtp/rtpfmt.c \
access/rtp/datagram.c access/rtp/vlc_dtls.h \
access/rtp/rtp.c access/rtp/rtp.h
librtp_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/access/rtp
librtp_plugin_la_CFLAGS = $(AM_CFLAGS)
......
/*****************************************************************************
* datagram.c:
*****************************************************************************
* Copyright (C) 2020 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <vlc_common.h>
#include <vlc_network.h>
#include "vlc_dtls.h"
struct vlc_dgram_sock
{
int fd;
struct vlc_dtls s;
};
static void vlc_datagram_Close(struct vlc_dtls *dgs)
{
struct vlc_dgram_sock *s = container_of(dgs, struct vlc_dgram_sock, s);
#ifndef _WIN32
vlc_close(s->fd);
#else
closesocket(s->fd);
#endif
free(s);
}
/* Note: must not be a cancellation point */
static int vlc_datagram_GetPollFD(struct vlc_dtls *dgs, short *restrict ev)
{
(void) ev; /* no changes there */
return container_of(dgs, struct vlc_dgram_sock, s)->fd;
}
static ssize_t vlc_datagram_Recv(struct vlc_dtls *dgs, struct iovec *iov,
unsigned iovlen, bool *truncated)
{
struct msghdr msg = {
.msg_iov = iov,
.msg_iovlen = iovlen,
};
int fd = container_of(dgs, struct vlc_dgram_sock, s)->fd;
ssize_t ret = recvmsg(fd, &msg, 0);
if (ret >= 0)
*truncated = (msg.msg_flags & MSG_TRUNC) != 0;
return ret;
}
static ssize_t vlc_datagram_Send(struct vlc_dtls *dgs,
const struct iovec *iov, unsigned iovlen)
{
const struct msghdr msg = {
.msg_iov = (struct iovec *)iov,
.msg_iovlen = iovlen,
};
int fd = container_of(dgs, struct vlc_dgram_sock, s)->fd;
return vlc_sendmsg(fd, &msg, 0);
}
static const struct vlc_dtls_operations vlc_datagram_ops = {
vlc_datagram_Close,
vlc_datagram_GetPollFD,
vlc_datagram_Recv,
vlc_datagram_Send,
};
struct vlc_dtls *vlc_datagram_CreateFD(int fd)
{
struct vlc_dgram_sock *s = malloc(sizeof (*s));
if (likely(s != NULL)) {
s->fd = fd;
s->s.ops = &vlc_datagram_ops;
}
return &s->s;
}
/*****************************************************************************
* datagram.h:
*****************************************************************************
* Copyright (C) 2020 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_DATAGRAM_SOCKET_H
# define VLC_DATAGRAM_SOCKET_H
struct iovec;
/**
* Datagram socket
*/
struct vlc_dtls {
const struct vlc_dtls_operations *ops;
};
struct vlc_dtls_operations {
void (*close)(struct vlc_dtls *);
int (*get_fd)(struct vlc_dtls *, short *events);
ssize_t (*readv)(struct vlc_dtls *, struct iovec *iov, unsigned len,
bool *restrict truncated);
ssize_t (*writev)(struct vlc_dtls *, const struct iovec *iov, unsigned len);
};
static inline void vlc_dtls_Close(struct vlc_dtls *dgs)
{
dgs->ops->close(dgs);
}
static inline int vlc_dtls_GetPollFD(struct vlc_dtls *dgs, short *restrict ev)
{
return dgs->ops->get_fd(dgs, ev);
}
static inline ssize_t vlc_dtls_Recv(struct vlc_dtls *dgs, void *buf, size_t len,
bool *restrict truncated)
{
struct iovec iov = { .iov_base = buf, .iov_len = len };
return dgs->ops->readv(dgs, &iov, 1, truncated);
}
static inline ssize_t vlc_dtls_Send(struct vlc_dtls *dgs, const void *buf,
size_t len)
{
struct iovec iov = { .iov_base = (void *)buf, .iov_len = len };
return dgs->ops->writev(dgs, &iov, 1);
}
struct vlc_dtls *vlc_datagram_CreateFD(int fd);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment