summaryrefslogtreecommitdiffstats
path: root/src/InputZeroMQReader.cpp
diff options
context:
space:
mode:
authorMatthias P. Braendli (think) <matthias@mpb.li>2013-11-10 21:50:12 +0100
committerMatthias P. Braendli (think) <matthias@mpb.li>2013-11-10 21:50:12 +0100
commit5d965e80be2e6ab62bc82fb2e0d4d472153ad241 (patch)
tree5add36f337b0de524b3d098f0b1fcc8d68aba0d7 /src/InputZeroMQReader.cpp
parent4f9a01a80570437b86e69eb0542b13df9a20743d (diff)
downloaddabmod-5d965e80be2e6ab62bc82fb2e0d4d472153ad241.tar.gz
dabmod-5d965e80be2e6ab62bc82fb2e0d4d472153ad241.tar.bz2
dabmod-5d965e80be2e6ab62bc82fb2e0d4d472153ad241.zip
crc-dabmod: add ZeroMQ input module
Diffstat (limited to 'src/InputZeroMQReader.cpp')
-rw-r--r--src/InputZeroMQReader.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/InputZeroMQReader.cpp b/src/InputZeroMQReader.cpp
new file mode 100644
index 0000000..e689e4c
--- /dev/null
+++ b/src/InputZeroMQReader.cpp
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Copyrigth (C) 2013
+ Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD 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.
+
+ CRC-DADMOD 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 CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if defined(HAVE_INPUT_ZEROMQ)
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <stdint.h>
+#include <zmq.hpp>
+#include <boost/thread/thread.hpp>
+#include "porting.h"
+#include "InputReader.h"
+#include "PcDebug.h"
+
+#define MAX_QUEUE_SIZE 50
+
+int InputZeroMQReader::Open(std::string uri)
+{
+ uri_ = uri;
+ workerdata_.uri = uri;
+ // launch receiver thread
+ worker_.Start(&workerdata_);
+
+ return 0;
+}
+
+int InputZeroMQReader::GetNextFrame(void* buffer)
+{
+ zmq::message_t* incoming;
+ in_messages_.wait_and_pop(incoming);
+
+ size_t framesize = incoming->size();
+
+ // guarantee that we never will write more than 6144 bytes
+ if (framesize > 6144) {
+ fprintf(stderr, "ZeroMQ message too large: %zu!\n", framesize);
+ logger_.level(error) << "ZeroMQ message too large" << framesize;
+ return -1;
+ }
+
+ memcpy(buffer, incoming->data(), framesize);
+
+ delete incoming;
+
+ // pad to 6144 bytes
+ memset(&((uint8_t*)buffer)[framesize], 0x55, 6144 - framesize);
+
+
+ return 6144;
+}
+
+void InputZeroMQReader::PrintInfo()
+{
+ fprintf(stderr, "Input ZeroMQ:\n");
+ fprintf(stderr, " Receiving from %s\n\n", uri_.c_str());
+}
+
+// ------------- Worker functions
+
+void InputZeroMQWorker::RecvProcess(struct InputZeroMQThreadData* workerdata)
+{
+ size_t queue_size = 0;
+
+ try {
+ subscriber.connect(workerdata->uri.c_str());
+
+ subscriber.setsockopt(ZMQ_SUBSCRIBE, NULL, 0); // subscribe to all messages
+
+ while (running)
+ {
+ zmq::message_t incoming;
+ subscriber.recv(&incoming);
+
+ if (queue_size < MAX_QUEUE_SIZE) {
+ zmq::message_t* holder = new zmq::message_t();
+ holder->move(&incoming); // move the message into the holder
+ queue_size = workerdata->in_messages->push(holder);
+ }
+ else
+ {
+ workerdata->in_messages->notify();
+ fprintf(stderr, "ZeroMQ message overfull: %zu elements !\n", queue_size);
+ }
+
+ if (queue_size < 5) {
+ fprintf(stderr, "ZeroMQ message underfull: %zu elements !\n", queue_size);
+ }
+ }
+ }
+ catch ( zmq::error_t err ) {
+ printf("ZeroMQ error in RecvProcess: '%s'\n", err.what());
+ }
+}
+
+void InputZeroMQWorker::Start(struct InputZeroMQThreadData* workerdata)
+{
+ running = true;
+ recv_thread = boost::thread(&InputZeroMQWorker::RecvProcess, this, workerdata);
+}
+
+void InputZeroMQWorker::Stop()
+{
+ subscriber.close();
+ running = false;
+}
+
+#endif
+