summaryrefslogtreecommitdiffstats
path: root/src/InputTcpReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/InputTcpReader.cpp')
-rw-r--r--src/InputTcpReader.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/InputTcpReader.cpp b/src/InputTcpReader.cpp
new file mode 100644
index 0000000..34ccb2e
--- /dev/null
+++ b/src/InputTcpReader.cpp
@@ -0,0 +1,122 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Copyright (C) 2016
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://www.opendigitalradio.org
+ */
+/*
+ This file is part of ODR-DabMod.
+
+ ODR-DabMod 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-DabMod 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-DabMod. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "InputReader.h"
+#include "PcDebug.h"
+#include "Utils.h"
+
+InputTcpReader::InputTcpReader()
+{
+ if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+ throw std::runtime_error("Can't create TCP socket");
+ }
+}
+
+InputTcpReader::~InputTcpReader()
+{
+ if (m_sock != INVALID_SOCKET) {
+ close(m_sock);
+ }
+}
+
+void InputTcpReader::Open(const std::string& endpoint)
+{
+ std::string hostname;
+ if (endpoint.compare(0, 6, "tcp://") == 0) {
+ hostname = endpoint.substr(6, std::string::npos);
+ }
+ else {
+ hostname = endpoint;
+ }
+
+ size_t colon_pos = hostname.find(":");
+ if (colon_pos == std::string::npos) {
+ std::stringstream ss;
+ ss << "Could not parse TCP endpoint " << endpoint;
+ throw std::runtime_error(ss.str());
+ }
+
+ long port = strtol(hostname.c_str() + colon_pos + 1, NULL, 10);
+ if (errno == ERANGE) {
+ std::stringstream ss;
+ ss << "Could not parse port in TCP endpoint " << endpoint;
+ throw std::runtime_error(ss.str());
+ }
+
+ hostname = hostname.substr(0, colon_pos);
+
+ struct sockaddr_in addr;
+ addr.sin_family = PF_INET;
+ addr.sin_addr.s_addr = htons(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ hostent *host = gethostbyname(hostname.c_str());
+ if (host) {
+ addr.sin_addr = *(in_addr *)(host->h_addr);
+ }
+ else {
+ std::stringstream ss;
+ ss << "Could not resolve hostname " << hostname << ": " << strerror(errno);
+ throw std::runtime_error(ss.str());
+ }
+
+ if (connect(m_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
+ std::stringstream ss;
+ ss << "Could not connect to " << hostname << ":" << port << " :" << strerror(errno);
+ throw std::runtime_error(ss.str());
+ }
+
+ m_uri = endpoint;
+}
+
+int InputTcpReader::GetNextFrame(void* buffer)
+{
+ uint8_t* buf = (uint8_t*)buffer;
+
+ const size_t framesize = 6144;
+
+ ssize_t r = recv(m_sock, buf, framesize, MSG_WAITALL);
+
+ if (r == -1) {
+ std::stringstream ss;
+ ss << "Could not receive from socket :" << strerror(errno);
+ throw std::runtime_error(ss.str());
+ }
+
+ return r;
+}
+
+void InputTcpReader::PrintInfo()
+{
+ fprintf(stderr, "Input TCP:\n");
+ fprintf(stderr, " Receiving from %s\n\n", m_uri.c_str());
+}
+