#include "platform_sys.h"
#include <iterator>
#include <fstream>
#include "srt.h"
#include "common.h"
#include "packet.h"
#include "core.h"
#include "utilities.h"
using namespace std;
extern "C" {
int srt_startup() { return CUDT::startup(); }
int srt_cleanup() { return CUDT::cleanup(); }
SRTSOCKET srt_socket(int , int , int ) { return CUDT::socket(); }
SRTSOCKET srt_create_socket() { return CUDT::socket(); }
#if ENABLE_EXPERIMENTAL_BONDING
SRTSOCKET srt_create_group(SRT_GROUP_TYPE gt) { return CUDT::createGroup(gt); }
int srt_include(SRTSOCKET socket, SRTSOCKET group) { return CUDT::addSocketToGroup(socket, group); }
int srt_exclude(SRTSOCKET socket) { return CUDT::removeSocketFromGroup(socket); }
SRTSOCKET srt_groupof(SRTSOCKET socket) { return CUDT::getGroupOfSocket(socket); }
int srt_group_data(SRTSOCKET socketgroup, SRT_SOCKGROUPDATA* output, size_t* inoutlen)
{
return CUDT::getGroupData(socketgroup, output, inoutlen);
}
int srt_group_configure(SRTSOCKET socketgroup, const char* str)
{
return CUDT::configureGroup(socketgroup, str);
}
SRT_SOCKOPT_CONFIG* srt_create_config()
{
return new SRT_SocketOptionObject;
}
void srt_delete_config(SRT_SOCKOPT_CONFIG* in)
{
delete in;
}
int srt_config_add(SRT_SOCKOPT_CONFIG* config, SRT_SOCKOPT option, const void* contents, int len)
{
if (!config)
return -1;
if (!config->add(option, contents, len))
return -1;
return 0;
}
#endif
int srt_bind(SRTSOCKET u, const struct sockaddr * name, int namelen) { return CUDT::bind(u, name, namelen); }
int srt_bind_acquire(SRTSOCKET u, UDPSOCKET udpsock) { return CUDT::bind(u, udpsock); }
int srt_listen(SRTSOCKET u, int backlog) { return CUDT::listen(u, backlog); }
SRTSOCKET srt_accept(SRTSOCKET u, struct sockaddr * addr, int * addrlen) { return CUDT::accept(u, addr, addrlen); }
SRTSOCKET srt_accept_bond(const SRTSOCKET lsns[], int lsize, int64_t msTimeOut) { return CUDT::accept_bond(lsns, lsize, msTimeOut); }
int srt_connect(SRTSOCKET u, const struct sockaddr * name, int namelen) { return CUDT::connect(u, name, namelen, SRT_SEQNO_NONE); }
int srt_connect_debug(SRTSOCKET u, const struct sockaddr * name, int namelen, int forced_isn) { return CUDT::connect(u, name, namelen, forced_isn); }
int srt_connect_bind(SRTSOCKET u,
const struct sockaddr* source,
const struct sockaddr* target, int target_len)
{
return CUDT::connect(u, source, target, target_len);
}
#if ENABLE_EXPERIMENTAL_BONDING
SRT_SOCKGROUPCONFIG srt_prepare_endpoint(const struct sockaddr* src, const struct sockaddr* adr, int namelen)
{
SRT_SOCKGROUPCONFIG data;
data.errorcode = SRT_SUCCESS;
data.id = -1;
data.token = -1;
data.weight = 0;
data.config = NULL;
if (src)
memcpy(&data.srcaddr, src, namelen);
else
{
memset(&data.srcaddr, 0, sizeof data.srcaddr);
data.srcaddr.ss_family = adr->sa_family;
}
memcpy(&data.peeraddr, adr, namelen);
return data;
}
int srt_connect_group(SRTSOCKET group,
SRT_SOCKGROUPCONFIG name [], int arraysize)
{
return CUDT::connectLinks(group, name, arraysize);
}
#endif
int srt_rendezvous(SRTSOCKET u, const struct sockaddr* local_name, int local_namelen,
const struct sockaddr* remote_name, int remote_namelen)
{
bool yes = 1;
CUDT::setsockopt(u, 0, SRTO_RENDEZVOUS, &yes, sizeof yes);
if ( (local_name->sa_family != AF_INET && local_name->sa_family != AF_INET6)
|| local_name->sa_family != remote_name->sa_family)
return CUDT::APIError(MJ_NOTSUP, MN_INVAL, 0);
const int st = srt_bind(u, local_name, local_namelen);
if (st != 0)
return st;
return srt_connect(u, remote_name, remote_namelen);
}
int srt_close(SRTSOCKET u)
{
SRT_SOCKSTATUS st = srt_getsockstate(u);
if ((st == SRTS_NONEXIST) ||
(st == SRTS_CLOSED) ||
(st == SRTS_CLOSING) )
{
return 0;
}
return CUDT::close(u);
}
int srt_getpeername(SRTSOCKET u, struct sockaddr * name, int * namelen) { return CUDT::getpeername(u, name, namelen); }
int srt_getsockname(SRTSOCKET u, struct sockaddr * name, int * namelen) { return CUDT::getsockname(u, name, namelen); }
int srt_getsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, void * optval, int * optlen)
{ return CUDT::getsockopt(u, level, optname, optval, optlen); }
int srt_setsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, const void * optval, int optlen)
{ return CUDT::setsockopt(u, level, optname, optval, optlen); }
int srt_getsockflag(SRTSOCKET u, SRT_SOCKOPT opt, void* optval, int* optlen)
{ return CUDT::getsockopt(u, 0, opt, optval, optlen); }
int srt_setsockflag(SRTSOCKET u, SRT_SOCKOPT opt, const void* optval, int optlen)
{ return CUDT::setsockopt(u, 0, opt, optval, optlen); }
int srt_send(SRTSOCKET u, const char * buf, int len) { return CUDT::send(u, buf, len, 0); }
int srt_recv(SRTSOCKET u, char * buf, int len) { return CUDT::recv(u, buf, len, 0); }
int srt_sendmsg(SRTSOCKET u, const char * buf, int len, int ttl, int inorder) { return CUDT::sendmsg(u, buf, len, ttl, 0!= inorder); }
int srt_recvmsg(SRTSOCKET u, char * buf, int len) { int64_t ign_srctime; return CUDT::recvmsg(u, buf, len, ign_srctime); }
int64_t srt_sendfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block)
{
if (!path || !offset )
{
return CUDT::APIError(MJ_NOTSUP, MN_INVAL, 0);
}
fstream ifs(path, ios::binary | ios::in);
if (!ifs)
{
return CUDT::APIError(MJ_FILESYSTEM, MN_READFAIL, 0);
}
int64_t ret = CUDT::sendfile(u, ifs, *offset, size, block);
ifs.close();
return ret;
}
int64_t srt_recvfile(SRTSOCKET u, const char* path, int64_t* offset, int64_t size, int block)
{
if (!path || !offset )
{
return CUDT::APIError(MJ_NOTSUP, MN_INVAL, 0);
}
fstream ofs(path, ios::binary | ios::out);
if (!ofs)
{
return CUDT::APIError(MJ_FILESYSTEM, MN_WRAVAIL, 0);
}
int64_t ret = CUDT::recvfile(u, ofs, *offset, size, block);
ofs.close();
return ret;
}
extern const SRT_MSGCTRL srt_msgctrl_default = {
0, SRT_MSGTTL_INF,
false, PB_SUBSEQUENT,
0, SRT_SEQNO_NONE,
SRT_MSGNO_NONE,
NULL, 0 };
void srt_msgctrl_init(SRT_MSGCTRL* mctrl)
{
*mctrl = srt_msgctrl_default;
}
int srt_sendmsg2(SRTSOCKET u, const char * buf, int len, SRT_MSGCTRL *mctrl)
{
if (mctrl)
return CUDT::sendmsg2(u, buf, len, (*mctrl));
SRT_MSGCTRL mignore = srt_msgctrl_default;
return CUDT::sendmsg2(u, buf, len, (mignore));
}
int srt_recvmsg2(SRTSOCKET u, char * buf, int len, SRT_MSGCTRL *mctrl)
{
if (mctrl)
return CUDT::recvmsg2(u, buf, len, (*mctrl));
SRT_MSGCTRL mignore = srt_msgctrl_default;
return CUDT::recvmsg2(u, buf, len, (mignore));
}
const char* srt_getlasterror_str() { return UDT::getlasterror().getErrorMessage(); }
int srt_getlasterror(int* loc_errno)
{
if ( loc_errno )
*loc_errno = UDT::getlasterror().getErrno();
return CUDT::getlasterror().getErrorCode();
}
const char* srt_strerror(int code, int err)
{
static CUDTException e;
e = CUDTException(CodeMajor(code/1000), CodeMinor(code%1000), err);
return(e.getErrorMessage());
}
void srt_clearlasterror()
{
UDT::getlasterror().clear();
}
int srt_bstats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear) { return CUDT::bstats(u, perf, 0!= clear); }
int srt_bistats(SRTSOCKET u, SRT_TRACEBSTATS * perf, int clear, int instantaneous) { return CUDT::bstats(u, perf, 0!= clear, 0!= instantaneous); }
SRT_SOCKSTATUS srt_getsockstate(SRTSOCKET u) { return SRT_SOCKSTATUS((int)CUDT::getsockstate(u)); }
int srt_epoll_create() { return CUDT::epoll_create(); }
int srt_epoll_clear_usocks(int eit) { return CUDT::epoll_clear_usocks(eit); }
int srt_epoll_add_usock(int eid, SRTSOCKET u, const int * events) { return CUDT::epoll_add_usock(eid, u, events); }
int srt_epoll_add_ssock(int eid, SYSSOCKET s, const int * events)
{
int flag = 0;
if (events) {
flag = *events;
} else {
flag = SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR;
}
return CUDT::epoll_add_ssock(eid, s, &flag);
}
int srt_epoll_remove_usock(int eid, SRTSOCKET u) { return CUDT::epoll_remove_usock(eid, u); }
int srt_epoll_remove_ssock(int eid, SYSSOCKET s) { return CUDT::epoll_remove_ssock(eid, s); }
int srt_epoll_update_usock(int eid, SRTSOCKET u, const int * events)
{
return CUDT::epoll_update_usock(eid, u, events);
}
int srt_epoll_update_ssock(int eid, SYSSOCKET s, const int * events)
{
int flag = 0;
if (events) {
flag = *events;
} else {
flag = SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR;
}
return CUDT::epoll_update_ssock(eid, s, &flag);
}
int srt_epoll_wait(
int eid,
SRTSOCKET* readfds, int* rnum, SRTSOCKET* writefds, int* wnum,
int64_t msTimeOut,
SYSSOCKET* lrfds, int* lrnum, SYSSOCKET* lwfds, int* lwnum)
{
return UDT::epoll_wait2(
eid,
readfds, rnum, writefds, wnum,
msTimeOut,
lrfds, lrnum, lwfds, lwnum);
}
int srt_epoll_uwait(int eid, SRT_EPOLL_EVENT* fdsSet, int fdsSize, int64_t msTimeOut)
{
return UDT::epoll_uwait(
eid,
fdsSet,
fdsSize,
msTimeOut);
}
int32_t srt_epoll_set(int eid, int32_t flags) { return CUDT::epoll_set(eid, flags); }
int srt_epoll_release(int eid) { return CUDT::epoll_release(eid); }
void srt_setloglevel(int ll)
{
UDT::setloglevel(srt_logging::LogLevel::type(ll));
}
void srt_addlogfa(int fa)
{
UDT::addlogfa(srt_logging::LogFA(fa));
}
void srt_dellogfa(int fa)
{
UDT::dellogfa(srt_logging::LogFA(fa));
}
void srt_resetlogfa(const int* fara, size_t fara_size)
{
UDT::resetlogfa(fara, fara_size);
}
void srt_setloghandler(void* opaque, SRT_LOG_HANDLER_FN* handler)
{
UDT::setloghandler(opaque, handler);
}
void srt_setlogflags(int flags)
{
UDT::setlogflags(flags);
}
int srt_getsndbuffer(SRTSOCKET sock, size_t* blocks, size_t* bytes)
{
return CUDT::getsndbuffer(sock, blocks, bytes);
}
int srt_getrejectreason(SRTSOCKET sock)
{
return CUDT::rejectReason(sock);
}
int srt_setrejectreason(SRTSOCKET sock, int value)
{
return CUDT::rejectReason(sock, value);
}
int srt_listen_callback(SRTSOCKET lsn, srt_listen_callback_fn* hook, void* opaq)
{
if (!hook)
return CUDT::APIError(MJ_NOTSUP, MN_INVAL);
return CUDT::installAcceptHook(lsn, hook, opaq);
}
int srt_connect_callback(SRTSOCKET lsn, srt_connect_callback_fn* hook, void* opaq)
{
if (!hook)
return CUDT::APIError(MJ_NOTSUP, MN_INVAL);
return CUDT::installConnectHook(lsn, hook, opaq);
}
uint32_t srt_getversion()
{
return SrtVersion(SRT_VERSION_MAJOR, SRT_VERSION_MINOR, SRT_VERSION_PATCH);
}
int64_t srt_time_now()
{
return srt::sync::count_microseconds(srt::sync::steady_clock::now().time_since_epoch());
}
int64_t srt_connection_time(SRTSOCKET sock)
{
return CUDT::socketStartTime(sock);
}
}