mirror of
https://github.com/LX3JL/xlxd.git
synced 2026-03-12 00:03:51 +01:00
add IPv6 UDP transport support (downloading DMR-ID via http still IPv4)
This commit is contained in:
parent
1958afca33
commit
cc92f37a05
|
|
@ -70,9 +70,8 @@ bool CDmrmmdvmProtocol::Init(void)
|
|||
m_LastKeepaliveTime.Now();
|
||||
|
||||
// random number generator
|
||||
time_t t;
|
||||
::srand((unsigned) time(&t));
|
||||
m_uiAuthSeed = (uint32)rand();
|
||||
std::random_device rd;
|
||||
m_uiAuthSeed = rd();
|
||||
|
||||
// done
|
||||
return ok;
|
||||
|
|
|
|||
|
|
@ -63,8 +63,9 @@ bool CDmrplusProtocol::Init(void)
|
|||
m_LastKeepaliveTime.Now();
|
||||
|
||||
// random number generator
|
||||
time_t t;
|
||||
::srand((unsigned) time(&t));
|
||||
std::random_device rd;
|
||||
std::mt19937 mt(rd());
|
||||
m_Random = mt;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
|
|
@ -88,7 +89,7 @@ void CDmrplusProtocol::Task(void)
|
|||
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
|
||||
{
|
||||
// crack the packet
|
||||
if ( IsValidDvFramePacket(Ip, Buffer, Frames) )
|
||||
if ( IsValidDvFramePacket(Buffer, Frames) )
|
||||
{
|
||||
//std::cout << "DMRplus DV frame" << std::endl;
|
||||
//Buffer.DebugDump(g_Reflector.m_DebugFile);
|
||||
|
|
@ -108,7 +109,7 @@ void CDmrplusProtocol::Task(void)
|
|||
}*/
|
||||
}
|
||||
}
|
||||
else if ( IsValidDvHeaderPacket(Ip, Buffer, &Header) )
|
||||
else if ( IsValidDvHeaderPacket(Buffer, &Header) )
|
||||
{
|
||||
//std::cout << "DMRplus DV header:" << std::endl;
|
||||
//std::cout << "DMRplus DV header:" << std::endl << *Header << std::endl;
|
||||
|
|
@ -444,7 +445,7 @@ bool CDmrplusProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign
|
|||
return valid;
|
||||
}
|
||||
|
||||
bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffer, CDvHeaderPacket **Header)
|
||||
bool CDmrplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPacket **Header)
|
||||
{
|
||||
bool valid = false;
|
||||
*Header = NULL;
|
||||
|
|
@ -470,7 +471,7 @@ bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffe
|
|||
rpt1.SetModule(DMRPLUS_MODULE_ID);
|
||||
CCallsign rpt2 = m_ReflectorCallsign;
|
||||
rpt2.SetModule(DmrDstIdToModule(uiDstId));
|
||||
uint32 uiStreamId = IpToStreamId(Ip);
|
||||
uint32 uiStreamId = CreateStreamId();
|
||||
|
||||
// and packet
|
||||
*Header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0);
|
||||
|
|
@ -486,7 +487,7 @@ bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffe
|
|||
return valid;
|
||||
}
|
||||
|
||||
bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer, CDvFramePacket **frames)
|
||||
bool CDmrplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePacket **frames)
|
||||
{
|
||||
bool valid = false;
|
||||
frames[0] = NULL;
|
||||
|
|
@ -528,7 +529,7 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
|
|||
dmrsync[6] = dmrframe[19] & 0xF0;
|
||||
|
||||
// and create 3 dv frames
|
||||
uint32 uiStreamId = IpToStreamId(Ip);
|
||||
uint32 uiStreamId = CreateStreamId();
|
||||
// frame1
|
||||
memcpy(dmrambe, &dmr3ambe[0], 9);
|
||||
frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1);
|
||||
|
|
@ -840,7 +841,7 @@ void CDmrplusProtocol::ReplaceEMBInBuffer(CBuffer *buffer, uint8 uiDmrPacketId)
|
|||
|
||||
|
||||
// uiStreamId helpers
|
||||
uint32 CDmrplusProtocol::IpToStreamId(const CIp &ip) const
|
||||
uint32 CDmrplusProtocol::CreateStreamId(void) const
|
||||
{
|
||||
return ip.GetAddr() ^ (uint32)(MAKEDWORD(ip.GetPort(), ip.GetPort()));
|
||||
return m_Random();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ protected:
|
|||
// packet decoding helpers
|
||||
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, const CIp &);
|
||||
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *, char *);
|
||||
bool IsValidDvHeaderPacket(const CIp &, const CBuffer &, CDvHeaderPacket **);
|
||||
bool IsValidDvFramePacket(const CIp &, const CBuffer &, CDvFramePacket **);
|
||||
bool IsValidDvHeaderPacket(const CBuffer &, CDvHeaderPacket **);
|
||||
bool IsValidDvFramePacket(const CBuffer &, CDvFramePacket **);
|
||||
|
||||
// packet encoding helpers
|
||||
void EncodeConnectAckPacket(CBuffer *);
|
||||
|
|
@ -102,7 +102,7 @@ protected:
|
|||
uint32 ModuleToDmrDestId(char) const;
|
||||
|
||||
// uiStreamId helpers
|
||||
uint32 IpToStreamId(const CIp &) const;
|
||||
uint32 CreateStreamId(void) const;
|
||||
|
||||
// Buffer & LC helpers
|
||||
void AppendVoiceLCToBuffer(CBuffer *, uint32) const;
|
||||
|
|
@ -116,6 +116,9 @@ protected:
|
|||
|
||||
// for queue header caches
|
||||
std::array<CDmrplusStreamCacheItem, NB_OF_MODULES> m_StreamsCache;
|
||||
|
||||
// random number generator
|
||||
mutable std::mt19937 m_Random;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
98
src/cip.cpp
98
src/cip.cpp
|
|
@ -33,44 +33,63 @@
|
|||
|
||||
CIp::CIp()
|
||||
{
|
||||
::memset(&m_Addr, 0, sizeof(m_Addr));
|
||||
m_Addr.sin_family = AF_INET;
|
||||
::memset(&m_Addr, 0, m_AddrLen = sizeof(struct sockaddr_in));
|
||||
m_Addr.ss_family = AF_INET;
|
||||
}
|
||||
|
||||
CIp::CIp(const char *sz)
|
||||
{
|
||||
::memset(&m_Addr, 0, sizeof(m_Addr));
|
||||
m_Addr.sin_family = AF_INET;
|
||||
// try xxx.xxx.xxx.xxxx first
|
||||
m_Addr.sin_addr.s_addr = inet_addr(sz);
|
||||
if ( m_Addr.sin_addr.s_addr == INADDR_NONE )
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
::memset(&m_Addr, 0, m_AddrLen = sizeof(struct sockaddr_in));
|
||||
m_Addr.ss_family = AF_INET;
|
||||
|
||||
::memset(&hints, 0, sizeof(hints));
|
||||
if ( getaddrinfo(sz, NULL, &hints, &res) == 0 )
|
||||
{
|
||||
// otherwise try to resolve via dns
|
||||
hostent *record = gethostbyname(sz);
|
||||
if( record != NULL )
|
||||
{
|
||||
m_Addr.sin_addr.s_addr = ((in_addr * )record->h_addr)->s_addr;
|
||||
}
|
||||
::memcpy(&m_Addr, res->ai_addr, m_AddrLen = res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
}
|
||||
|
||||
CIp::CIp(const struct sockaddr_in *sa)
|
||||
CIp::CIp(const struct sockaddr_storage *ss, socklen_t len)
|
||||
{
|
||||
::memcpy(&m_Addr, sa, sizeof(m_Addr));
|
||||
len = ( len < sizeof(m_Addr) ) ? len : sizeof(m_Addr);
|
||||
::memcpy(&m_Addr, ss, m_AddrLen = len);
|
||||
}
|
||||
|
||||
|
||||
CIp::CIp(const CIp &ip)
|
||||
{
|
||||
::memcpy(&m_Addr, &ip.m_Addr, sizeof(m_Addr));
|
||||
::memcpy(&m_Addr, &ip.m_Addr, m_AddrLen = ip.m_AddrLen);
|
||||
}
|
||||
|
||||
CIp::CIp(const CIp &ip, uint16 port)
|
||||
{
|
||||
::memcpy(&m_Addr, &ip.m_Addr, m_AddrLen = ip.m_AddrLen);
|
||||
|
||||
switch (m_Addr.ss_family) {
|
||||
case AF_INET:
|
||||
((struct sockaddr_in *)&m_Addr)->sin_port = htons(port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
((struct sockaddr_in6 *)&m_Addr)->sin6_port = htons(port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// set
|
||||
// sockaddr
|
||||
|
||||
void CIp::SetSockAddr(struct sockaddr_in *sa)
|
||||
void CIp::SetSockAddr(struct sockaddr_storage *ss, socklen_t len)
|
||||
{
|
||||
::memcpy(&m_Addr, sa, sizeof(m_Addr));
|
||||
len = ( len < sizeof(m_Addr) ) ? len : sizeof(m_Addr);
|
||||
::memcpy(&m_Addr, ss, m_AddrLen = len);
|
||||
}
|
||||
|
||||
struct sockaddr_storage *CIp::GetSockAddr(socklen_t &len)
|
||||
{
|
||||
len = m_AddrLen;
|
||||
return &m_Addr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -78,14 +97,41 @@ void CIp::SetSockAddr(struct sockaddr_in *sa)
|
|||
|
||||
bool CIp::operator ==(const CIp &ip) const
|
||||
{
|
||||
return ( (ip.m_Addr.sin_family == m_Addr.sin_family) &&
|
||||
(ip.m_Addr.sin_addr.s_addr == m_Addr.sin_addr.s_addr) &&
|
||||
(ip.m_Addr.sin_port == m_Addr.sin_port)) ;
|
||||
if (ip.m_Addr.ss_family != m_Addr.ss_family)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_Addr.ss_family) {
|
||||
case AF_INET:
|
||||
struct sockaddr_in *pi4, *pm4;
|
||||
pi4 = (struct sockaddr_in *)&ip.m_Addr;
|
||||
pm4 = (struct sockaddr_in *)&m_Addr;
|
||||
return ( (pi4->sin_addr.s_addr == pm4->sin_addr.s_addr) &&
|
||||
(pi4->sin_port == pm4->sin_port) );
|
||||
case AF_INET6:
|
||||
struct sockaddr_in6 *pi6, *pm6;
|
||||
pi6 = (struct sockaddr_in6 *)&ip.m_Addr;
|
||||
pm6 = (struct sockaddr_in6 *)&m_Addr;
|
||||
return ( IN6_ARE_ADDR_EQUAL(&pi6->sin6_addr, &pm6->sin6_addr) &&
|
||||
(pi6->sin6_port == pm6->sin6_port) );
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
CIp::operator const char *() const
|
||||
{
|
||||
return ::inet_ntoa(m_Addr.sin_addr);
|
||||
switch(m_Addr.ss_family) {
|
||||
case AF_INET:
|
||||
return ::inet_ntop(m_Addr.ss_family,
|
||||
&((struct sockaddr_in *)&m_Addr)->sin_addr.s_addr,
|
||||
m_AddrStr, sizeof(m_AddrStr));
|
||||
case AF_INET6:
|
||||
return ::inet_ntop(m_Addr.ss_family,
|
||||
((struct sockaddr_in6 *)&m_Addr)->sin6_addr.s6_addr,
|
||||
m_AddrStr, sizeof(m_AddrStr));
|
||||
default:
|
||||
return ::strncpy(m_AddrStr, "unknown", sizeof(m_AddrStr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
15
src/cip.h
15
src/cip.h
|
|
@ -35,20 +35,17 @@ public:
|
|||
// constructors
|
||||
CIp();
|
||||
//CIp(uint8, uint8, uint8, uint8);
|
||||
CIp(const struct sockaddr_in *);
|
||||
CIp(const struct sockaddr_storage *, socklen_t);
|
||||
CIp(const char *);
|
||||
CIp(const CIp &);
|
||||
CIp(const CIp &, uint16);
|
||||
|
||||
// destructor
|
||||
virtual ~CIp() {};
|
||||
|
||||
// sockaddr
|
||||
void SetSockAddr(struct sockaddr_in *);
|
||||
struct sockaddr_in *GetSockAddr(void) { return &m_Addr; }
|
||||
|
||||
// convertor
|
||||
uint32 GetAddr(void) const { return m_Addr.sin_addr.s_addr; }
|
||||
uint16 GetPort(void) const { return m_Addr.sin_port; }
|
||||
void SetSockAddr(struct sockaddr_storage *, socklen_t);
|
||||
struct sockaddr_storage *GetSockAddr(socklen_t &);
|
||||
|
||||
// operator
|
||||
bool operator ==(const CIp &) const;
|
||||
|
|
@ -56,7 +53,9 @@ public:
|
|||
|
||||
protected:
|
||||
// data
|
||||
struct sockaddr_in m_Addr;
|
||||
struct sockaddr_storage m_Addr;
|
||||
socklen_t m_AddrLen;
|
||||
mutable char m_AddrStr[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "cprotocols.h"
|
||||
#include "cpacketstream.h"
|
||||
#include "cnotificationqueue.h"
|
||||
#include "cudpsocket.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -57,9 +58,10 @@ public:
|
|||
// settings
|
||||
void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; }
|
||||
const CCallsign &GetCallsign(void) const { return m_Callsign; }
|
||||
void SetListenIp(const CIp &ip) { m_Ip = ip; }
|
||||
void SetListenIp(int i, const CIp &ip) { if (i < UDP_SOCKET_MAX) m_Ip[i] = ip; }
|
||||
void SetTranscoderIp(const CIp &ip) { m_AmbedIp = ip; }
|
||||
const CIp &GetListenIp(void) const { return m_Ip; }
|
||||
const CIp &GetListenIp(void) const { return m_Ip[0]; }
|
||||
const CIp &GetListenIp(int i) const { return m_Ip[i]; }
|
||||
const CIp &GetTranscoderIp(void) const { return m_AmbedIp; }
|
||||
|
||||
// operation
|
||||
|
|
@ -119,7 +121,7 @@ protected:
|
|||
protected:
|
||||
// identity
|
||||
CCallsign m_Callsign;
|
||||
CIp m_Ip;
|
||||
CIp m_Ip[UDP_SOCKET_MAX];
|
||||
CIp m_AmbedIp;
|
||||
|
||||
// objects
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@
|
|||
|
||||
CUdpSocket::CUdpSocket()
|
||||
{
|
||||
m_Socket = -1;
|
||||
for ( int i = 0; i < UDP_SOCKET_MAX; i++ )
|
||||
{
|
||||
m_Socket[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -41,10 +44,7 @@ CUdpSocket::CUdpSocket()
|
|||
|
||||
CUdpSocket::~CUdpSocket()
|
||||
{
|
||||
if ( m_Socket != -1 )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -53,26 +53,29 @@ CUdpSocket::~CUdpSocket()
|
|||
bool CUdpSocket::Open(uint16 uiPort)
|
||||
{
|
||||
bool open = false;
|
||||
struct sockaddr_storage *ss;
|
||||
socklen_t ss_len;
|
||||
|
||||
// create socket
|
||||
m_Socket = socket(PF_INET,SOCK_DGRAM,0);
|
||||
if ( m_Socket != -1 )
|
||||
{
|
||||
// initialize sockaddr struct
|
||||
::memset(&m_SocketAddr, 0, sizeof(struct sockaddr_in));
|
||||
m_SocketAddr.sin_family = AF_INET;
|
||||
m_SocketAddr.sin_port = htons(uiPort);
|
||||
m_SocketAddr.sin_addr.s_addr = inet_addr(g_Reflector.GetListenIp());
|
||||
for ( int i = 0; i < UDP_SOCKET_MAX; i++ ) {
|
||||
m_Ip[i] = CIp(g_Reflector.GetListenIp(i), uiPort);
|
||||
ss = m_Ip[i].GetSockAddr(ss_len);
|
||||
|
||||
if ( bind(m_Socket, (struct sockaddr *)&m_SocketAddr, sizeof(struct sockaddr_in)) == 0 )
|
||||
// create socket
|
||||
// (avoid INADDR_ANY on secondary and later IP address)
|
||||
m_Socket[i] = ( i != 0 && m_Ip[i] == CIp() ) ?
|
||||
-1 : socket(ss->ss_family, SOCK_DGRAM, 0);
|
||||
if ( m_Socket[i] != -1 )
|
||||
{
|
||||
fcntl(m_Socket, F_SETFL, O_NONBLOCK);
|
||||
open = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
close(m_Socket);
|
||||
m_Socket = -1;
|
||||
if ( bind(m_Socket[i], (struct sockaddr *)ss, ss_len) == 0 )
|
||||
{
|
||||
fcntl(m_Socket[i], F_SETFL, O_NONBLOCK);
|
||||
open |= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
close(m_Socket[i]);
|
||||
m_Socket[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,53 +85,92 @@ bool CUdpSocket::Open(uint16 uiPort)
|
|||
|
||||
void CUdpSocket::Close(void)
|
||||
{
|
||||
if ( m_Socket != -1 )
|
||||
for ( int i = 0; i < UDP_SOCKET_MAX; i++ )
|
||||
{
|
||||
close(m_Socket);
|
||||
m_Socket = -1;
|
||||
if ( m_Socket[i] != -1 )
|
||||
{
|
||||
close(m_Socket[i]);
|
||||
m_Socket[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CUdpSocket::GetSocket(const CIp &Ip)
|
||||
{
|
||||
CIp temp(Ip);
|
||||
socklen_t ss_len;
|
||||
struct sockaddr_storage *ss = temp.GetSockAddr(ss_len);
|
||||
sa_family_t ss_family = ss->ss_family;
|
||||
|
||||
for ( int i = 0; i < UDP_SOCKET_MAX; i++ )
|
||||
{
|
||||
ss = m_Ip[i].GetSockAddr(ss_len);
|
||||
if ( ss_family == ss->ss_family )
|
||||
{
|
||||
return m_Socket[i];
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// read
|
||||
|
||||
int CUdpSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
|
||||
{
|
||||
struct sockaddr_in Sin;
|
||||
fd_set FdSet;
|
||||
unsigned int uiFromLen = sizeof(struct sockaddr_in);
|
||||
int iRecvLen = -1;
|
||||
struct timeval tv;
|
||||
struct sockaddr_storage Sin;
|
||||
struct pollfd pfd[UDP_SOCKET_MAX];
|
||||
socklen_t uiFromLen = sizeof(Sin);
|
||||
int i, socks, index, iRecvLen = -1;
|
||||
|
||||
// socket valid ?
|
||||
if ( m_Socket != -1 )
|
||||
for ( i = 0, socks = 0; i < UDP_SOCKET_MAX; i++ )
|
||||
{
|
||||
// control socket
|
||||
FD_ZERO(&FdSet);
|
||||
FD_SET(m_Socket, &FdSet);
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
select(m_Socket + 1, &FdSet, 0, 0, &tv);
|
||||
|
||||
// allocate buffer
|
||||
Buffer->resize(UDP_BUFFER_LENMAX);
|
||||
|
||||
// read
|
||||
iRecvLen = (int)recvfrom(m_Socket,
|
||||
(void *)Buffer->data(), UDP_BUFFER_LENMAX,
|
||||
0, (struct sockaddr *)&Sin, &uiFromLen);
|
||||
|
||||
// handle
|
||||
if ( iRecvLen != -1 )
|
||||
if ( m_Socket[i] != -1 )
|
||||
{
|
||||
// adjust buffer size
|
||||
Buffer->resize(iRecvLen);
|
||||
|
||||
// get IP
|
||||
Ip->SetSockAddr(&Sin);
|
||||
pfd[socks].fd = m_Socket[i];
|
||||
pfd[socks].events = POLLIN;
|
||||
socks++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( socks != 0 )
|
||||
{
|
||||
// control socket
|
||||
poll(pfd, socks, timeout);
|
||||
|
||||
for ( i = 0; i < socks; i++ )
|
||||
{
|
||||
// round robin
|
||||
index = (i + m_Counter) % socks;
|
||||
|
||||
if ( pfd[index].revents & POLLIN )
|
||||
{
|
||||
// allocate buffer
|
||||
Buffer->resize(UDP_BUFFER_LENMAX);
|
||||
|
||||
// read
|
||||
iRecvLen = (int)recvfrom(pfd[index].fd,
|
||||
(void *)Buffer->data(), UDP_BUFFER_LENMAX,
|
||||
0, (struct sockaddr *)&Sin, &uiFromLen);
|
||||
|
||||
// handle
|
||||
if ( iRecvLen != -1 )
|
||||
{
|
||||
// adjust buffer size
|
||||
Buffer->resize(iRecvLen);
|
||||
|
||||
// get IP
|
||||
Ip->SetSockAddr(&Sin, uiFromLen);
|
||||
|
||||
m_Counter++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return iRecvLen;
|
||||
}
|
||||
|
|
@ -139,35 +181,39 @@ int CUdpSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
|
|||
int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip)
|
||||
{
|
||||
CIp temp(Ip);
|
||||
return (int)::sendto(m_Socket,
|
||||
socklen_t ss_len;
|
||||
struct sockaddr_storage *ss = temp.GetSockAddr(ss_len);
|
||||
return (int)::sendto(GetSocket(Ip),
|
||||
(void *)Buffer.data(), Buffer.size(),
|
||||
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
|
||||
0, (struct sockaddr *)ss, ss_len);
|
||||
}
|
||||
|
||||
int CUdpSocket::Send(const char *Buffer, const CIp &Ip)
|
||||
{
|
||||
CIp temp(Ip);
|
||||
return (int)::sendto(m_Socket,
|
||||
socklen_t ss_len;
|
||||
struct sockaddr_storage *ss = temp.GetSockAddr(ss_len);
|
||||
return (int)::sendto(GetSocket(Ip),
|
||||
(void *)Buffer, ::strlen(Buffer),
|
||||
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
|
||||
0, (struct sockaddr *)ss, ss_len);
|
||||
}
|
||||
|
||||
int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip, uint16 destport)
|
||||
{
|
||||
CIp temp(Ip);
|
||||
temp.GetSockAddr()->sin_port = htons(destport);
|
||||
return (int)::sendto(m_Socket,
|
||||
CIp temp(Ip, destport);
|
||||
socklen_t ss_len;
|
||||
struct sockaddr_storage *ss = temp.GetSockAddr(ss_len);
|
||||
return (int)::sendto(GetSocket(Ip),
|
||||
(void *)Buffer.data(), Buffer.size(),
|
||||
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
|
||||
0, (struct sockaddr *)ss, ss_len);
|
||||
}
|
||||
|
||||
int CUdpSocket::Send(const char *Buffer, const CIp &Ip, uint16 destport)
|
||||
{
|
||||
CIp temp(Ip);
|
||||
temp.GetSockAddr()->sin_port = htons(destport);
|
||||
return (int)::sendto(m_Socket,
|
||||
CIp temp(Ip, destport);
|
||||
socklen_t ss_len;
|
||||
struct sockaddr_storage *ss = temp.GetSockAddr(ss_len);
|
||||
return (int)::sendto(GetSocket(Ip),
|
||||
(void *)Buffer, ::strlen(Buffer),
|
||||
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
|
||||
0, (struct sockaddr *)ss, ss_len);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
//#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
|
@ -40,6 +41,7 @@
|
|||
// define
|
||||
|
||||
#define UDP_BUFFER_LENMAX 1024
|
||||
#define UDP_SOCKET_MAX 2
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -57,7 +59,7 @@ public:
|
|||
// open & close
|
||||
bool Open(uint16);
|
||||
void Close(void);
|
||||
int GetSocket(void) { return m_Socket; }
|
||||
int GetSocket(const CIp &);
|
||||
|
||||
// read
|
||||
int Receive(CBuffer *, CIp *, int);
|
||||
|
|
@ -70,8 +72,9 @@ public:
|
|||
|
||||
protected:
|
||||
// data
|
||||
int m_Socket;
|
||||
struct sockaddr_in m_SocketAddr;
|
||||
int m_Socket[UDP_SOCKET_MAX];
|
||||
CIp m_Ip[UDP_SOCKET_MAX];
|
||||
unsigned int m_Counter;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ int main(int argc, const char * argv[])
|
|||
#endif
|
||||
|
||||
// check arguments
|
||||
if ( argc != 4 )
|
||||
if ( argc < 4 )
|
||||
{
|
||||
std::cout << "Usage: xlxd callsign xlxdip ambedip" << std::endl;
|
||||
std::cout << "example: xlxd XLX999 192.168.178.212 127.0.0.1" << std::endl;
|
||||
|
|
@ -99,8 +99,9 @@ int main(int argc, const char * argv[])
|
|||
|
||||
// initialize reflector
|
||||
g_Reflector.SetCallsign(argv[1]);
|
||||
g_Reflector.SetListenIp(CIp(argv[2]));
|
||||
g_Reflector.SetListenIp(0, CIp(argv[2]));
|
||||
g_Reflector.SetTranscoderIp(CIp(CIp(argv[3])));
|
||||
g_Reflector.SetListenIp(1, ( argc >= 5 ) ? CIp(argv[4]) : CIp());
|
||||
|
||||
// and let it run
|
||||
if ( !g_Reflector.Start() )
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
|
|
|||
Loading…
Reference in a new issue