From b396a7eff34173fd4a9e48d8e4cfa5bab7fa603f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 12 Feb 2017 19:02:45 +0100 Subject: Add initial copy-pasted code --- src/UdpSocket.cpp | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 src/UdpSocket.cpp (limited to 'src/UdpSocket.cpp') diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp new file mode 100644 index 0000000..8ac3706 --- /dev/null +++ b/src/UdpSocket.cpp @@ -0,0 +1,510 @@ +/* + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the + Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2015 Matthias P. Braendli + http://www.opendigitalradio.org + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . + */ + +#include "UdpSocket.h" + +#include +#include +#include +#include +#include + +#ifdef TRACE_ON +# ifndef TRACE_CLASS +# define TRACE_CLASS(class, func) cout <<"-" <<(class) <<"\t(" < data, InetAddress destination) +{ +#ifdef DUMP + TRACE_CLASS("UdpSocket", "send(vector)"); +#endif + int ret = sendto(listenSocket, &data[0], data.size(), 0, + destination.getAddress(), sizeof(*destination.getAddress())); + if (ret == SOCKET_ERROR +#ifndef _WIN32 + && errno != ECONNREFUSED +#endif + ) { + setInetError("Can't send UDP packet"); + return -1; + } + return 0; +} + + +/** + * Must be called to receive data on a multicast address. + * @param groupname The multica +st address to join. + * @return 0 if ok, -1 if error + */ +int UdpSocket::joinGroup(char* groupname) +{ + TRACE_CLASS("UdpSocket", "joinGroup(char*)"); +#ifdef _WIN32 + ip_mreq group; +#else + ip_mreqn group; +#endif + if ((group.imr_multiaddr.s_addr = inet_addr(groupname)) == INADDR_NONE) { + setInetError(groupname); + return -1; + } + if (!IN_MULTICAST(ntohl(group.imr_multiaddr.s_addr))) { + setInetError("Not a multicast address"); + return -1; + } +#ifdef _WIN32 + group.imr_interface.s_addr = 0; + if (setsockopt(listenSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&group, sizeof(group)) + == SOCKET_ERROR) { + setInetError("Can't join multicast group"); + return -1; + } +#else + group.imr_address.s_addr = htons(INADDR_ANY);; + group.imr_ifindex = 0; + if (setsockopt(listenSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)) + == SOCKET_ERROR) { + setInetError("Can't join multicast group"); + } +#endif + return 0; +} + +int UdpSocket::setMulticastTTL(int ttl) +{ + if (setsockopt(listenSocket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) + == SOCKET_ERROR) { + setInetError("Can't set ttl"); + return -1; + } + + return 0; +} + +int UdpSocket::setMulticastSource(const char* source_addr) +{ + struct in_addr addr; + if (inet_aton(source_addr, &addr) == 0) { + setInetError("Can't parse source address"); + return -1; + } + + if (setsockopt(listenSocket, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) + == SOCKET_ERROR) { + setInetError("Can't set source address"); + return -1; + } + + return 0; +} + + +/** + * Constructs an UDP packet. + * @param initSize The initial size of the data buffer + */ +UdpPacket::UdpPacket(unsigned int initSize) : + dataBuf(new char[initSize]), + length(0), + size(initSize), + offset(0) +{ + TRACE_CLASS("UdpPacket", "UdpPacket(unsigned int)"); + if (dataBuf == NULL) + size = 0; +} + + +/// Destructor +UdpPacket::~UdpPacket() +{ + TRACE_CLASS("UdpPacket", "~UdpPacket()"); + if (dataBuf != NULL) { + delete []dataBuf; + dataBuf = NULL; + } +} + + +/** + * Changes size of the data buffer size. \a Length + \a offset data will be copied + * in the new buffer. + * @warning The pointer to data will be changed + * @param newSize The new data buffer size + */ +void UdpPacket::setSize(unsigned newSize) +{ + TRACE_CLASS("UdpPacket", "setSize(unsigned)"); + char *tmp = new char[newSize]; + if (length > newSize) + length = newSize; + if (tmp) { + memcpy(tmp, dataBuf, length); + delete []dataBuf; + dataBuf = tmp; + size = newSize; + } +} + + +/** + * Give the pointer to data. It is ajusted with the \a offset. + * @warning This pointer change. when the \a size of the buffer and the \a offset change. + * @return The pointer + */ +char *UdpPacket::getData() +{ + return dataBuf + offset; +} + + +/** + * Add some data at the end of data buffer and adjust size. + * @param data Pointer to the data to add + * @param size Size in bytes of new data + */ +void UdpPacket::addData(const void *data, unsigned size) +{ + if (length + size > this->size) { + setSize(this->size << 1); + } + memcpy(dataBuf + length, data, size); + length += size; +} + + +/** + * Returns the length of useful data. Data before the \a offset are ignored. + * @return The data length + */ +unsigned long UdpPacket::getLength() +{ + return length - offset; +} + + +/** + * Returns the size of the data buffer. + * @return The data buffer size + */ +unsigned long UdpPacket::getSize() +{ + return size; +} + + +/** + * Returns the offset value. + * @return The offset value + */ +unsigned long UdpPacket::getOffset() +{ + return offset; +} + + +/** + * Sets the data length value. Data before the \a offset are ignored. + * @param len The new length of data + */ +void UdpPacket::setLength(unsigned long len) +{ + length = len + offset; +} + + +/** + * Sets the data offset. Data length is ajusted to ignore data before the \a offset. + * @param val The new data offset. + */ +void UdpPacket::setOffset(unsigned long val) +{ + offset = val; + if (offset > length) + length = offset; +} + + +/** + * Returns the UDP address of the data. + * @return The UDP address + */ +InetAddress &UdpPacket::getAddress() +{ + return address; +} + +/* +WSAEINTR +WSAEBADF +WSAEACCES +WSAEFAULT +WSAEINVAL +WSAEMFILE +WSAEWOULDBLOCK +WSAEINPROGRESS +WSAEALREADY +WSAENOTSOCK +WSAEDESTADDRREQ +WSAEMSGSIZE +WSAEPROTOTYPE +WSAENOPROTOOPT +WSAEPROTONOSUPPORT +WSAESOCKTNOSUPPORT +WSAEOPNOTSUPP +WSAEPFNOSUPPORT +WSAEAFNOSUPPORT +WSAEADDRINUSE +WSAEADDRNOTAVAIL +WSAENETDOWN +WSAENETUNREACH +WSAENETRESET +WSAECONNABORTED +WSAECONNRESET +WSAENOBUFS +WSAEISCONN +WSAENOTCONN +WSAESHUTDOWN +WSAETOOMANYREFS +WSAETIMEDOUT +WSAECONNREFUSED +WSAELOOP +WSAENAMETOOLONG +WSAEHOSTDOWN +WSAEHOSTUNREACH +WSAENOTEMPTY +WSAEPROCLIM +WSAEUSERS +WSAEDQUOT +WSAESTALE +WSAEREMOTE +WSAEDISCON +WSASYSNOTREADY +WSAVERNOTSUPPORTED +WSANOTINITIALISED +*/ -- cgit v1.2.3