From c66bf4c088638169e74e6911f6c6601614bce353 Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sun, 22 Apr 2018 14:07:52 +0200 Subject: [PATCH] LaunchAPPL/Serial: UnreliableStram to simulate bit errors --- LaunchAPPL/Common/CMakeLists.txt | 1 + LaunchAPPL/Common/ReliableStream.cc | 5 ++- LaunchAPPL/Common/UnreliableStream.h | 56 ++++++++++++++++++++++++++++ LaunchAPPL/Server/main.cc | 11 +++++- 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 LaunchAPPL/Common/UnreliableStream.h diff --git a/LaunchAPPL/Common/CMakeLists.txt b/LaunchAPPL/Common/CMakeLists.txt index 95f2a5a7d5..f55ea48076 100644 --- a/LaunchAPPL/Common/CMakeLists.txt +++ b/LaunchAPPL/Common/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(LaunchAPPLCommon ReliableStream.h ReliableStream.cc CRC32.h + UnreliableStream.h ) target_include_directories(LaunchAPPLCommon PUBLIC .) diff --git a/LaunchAPPL/Common/ReliableStream.cc b/LaunchAPPL/Common/ReliableStream.cc index 49be3b29af..05ab9ca294 100644 --- a/LaunchAPPL/Common/ReliableStream.cc +++ b/LaunchAPPL/Common/ReliableStream.cc @@ -35,6 +35,7 @@ ReliableStream::ReliableStream(Stream& stream) : stream(stream) { incomingPacket.reserve(packetSize + 4); + stream.setListener(this); } ReliableStream::~ReliableStream() { @@ -65,12 +66,12 @@ void ReliableStream::nack() printf("nack sent\n"); } -void ReliableStream::gotNack(uint8_t id) +void ReliableStream::gotAck(uint8_t id) { printf("got ack\n"); } -void ReliableStream::gotAck(uint8_t id) +void ReliableStream::gotNack(uint8_t id) { printf("got nack\n"); } diff --git a/LaunchAPPL/Common/UnreliableStream.h b/LaunchAPPL/Common/UnreliableStream.h new file mode 100644 index 0000000000..cbe4fbc7f8 --- /dev/null +++ b/LaunchAPPL/Common/UnreliableStream.h @@ -0,0 +1,56 @@ +#ifndef UNRELIABLESTREAM_H_ +#define UNRELIABLESTREAM_H_ + +#include "Stream.h" + + // A stream filter to simulate bit errors +class UnreliableStream : public Stream, private StreamListener +{ + Stream& stream_; + int nextError = 0; +public: + UnreliableStream(Stream& stream) + : stream_(stream) + { + stream_.setListener(this); + setupNextError(); + } + virtual void write(const void* p, size_t n) override + { + std::vector tmp(n); + memcpy(tmp.data(), p, n); + maybeFlipBit(tmp.data(), n); + stream_.write(tmp.data(),n); + } + virtual void flushWrite() override + { + stream_.flushWrite(); + } + +private: + virtual size_t onReceive(const uint8_t* p, size_t n) override + { + std::vector tmp(n); + memcpy(tmp.data(), p, n); + maybeFlipBit(tmp.data(), n); + notifyReceive(tmp.data(), n); + return n; + } + + void setupNextError() + { + nextError += 8 * 1000 + 3; + } + + void maybeFlipBit(uint8_t* p, size_t n) + { + while(nextError < n * 8) + { + p[n / 8] ^= 0x80 >> (n%8); + setupNextError(); + } + nextError -= n * 8; + } +}; + +#endif diff --git a/LaunchAPPL/Server/main.cc b/LaunchAPPL/Server/main.cc index 33d46a59af..d6ee50d79b 100644 --- a/LaunchAPPL/Server/main.cc +++ b/LaunchAPPL/Server/main.cc @@ -9,6 +9,8 @@ #include #include +#include + class MacSerialStream : public Stream { static const long kInputBufferSize = 4096; @@ -195,8 +197,15 @@ int main() { MacSerialStream stream; + +//#define SIMULATE_ERRORS +#ifdef SIMULATE_ERRORS + UnreliableStream uStream(stream); + ReliableStream rStream(uStream); +#else ReliableStream rStream(stream); - stream.setListener(&rStream); +#endif + Listener listener; rStream.setListener(&listener);