123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #ifndef COVERTPROTOCOLBIDIRECTIONAL_H
- #define COVERTPROTOCOLBIDIRECTIONAL_H
- #include <fstream>
- #include <string>
- #include <type_traits>
- #include "../ChannelControls.h"
- #include "CovertProtocol.hpp"
- template <int N, bool PASSIVE> class CovertProtocolBidirectional : public ChannelControls {
- static_assert(N >= 2);
- public:
-
- CovertProtocolBidirectional() : segment(PASSIVE ? 1 : 0) {
- lastData = new uint8_t[N]();
- protocol.reset();
- }
-
- ~CovertProtocolBidirectional() { delete[](lastData); }
-
- void send(uint8_t *const data) {
- if (sendResetFlag) {
- sendResetFlag = false;
- data[0] = (segment << 6) | 1;
- std::memset(data + 1, 0, N - 1);
- return;
- }
- if (sendSegment()) {
- std::memcpy(data, lastData, N);
- return;
- }
- if constexpr (!PASSIVE) {
- protocol.send(data + 1);
- }
- data[0] = (segment << 6);
-
- std::memcpy(lastData, data, N);
- }
-
- void receive(const uint8_t *const data) {
- uint8_t seg = data[0] >> 6;
- bool reset = data[0] & 1;
- if (reset) {
- resetState();
- return;
- }
- if (receiveSegment(seg)) {
- return;
- }
- if constexpr (PASSIVE) {
- protocol.receive(data + 1);
- }
- }
-
-
- virtual bool sendFile(const std::string &fileName) { return protocol.sendFile(fileName); }
-
- virtual std::pair<uint32_t, uint32_t> getProgress() { return protocol.getProgress(); }
-
- virtual bool isTransferRunning() { return protocol.isTransferRunning(); }
-
- virtual void reset() {
- sendResetFlag = true;
- resetState();
- }
-
- virtual std::time_t getTransferStart() { return protocol.getTransferStart(); }
-
- virtual std::string getFileName() { return protocol.getFileName(); };
-
- private:
-
- uint8_t segment;
-
- uint8_t lastACKedSegment = 0;
-
- uint8_t *lastData;
-
- CovertProtocol<N - 1, PASSIVE> protocol;
-
- bool sendResetFlag = true;
-
- inline bool receiveSegment(uint8_t seg) {
- if constexpr (PASSIVE) {
- if (seg == segment && seg == increaseSegment(lastACKedSegment, 1)) {
- lastACKedSegment = seg;
- return false;
- } else {
- return true;
- }
- } else {
- if (seg == increaseSegment(segment, 1) && seg == increaseSegment(lastACKedSegment, 2)) {
- lastACKedSegment = increaseSegment(lastACKedSegment, 1);
- return false;
- } else {
- return true;
- }
- }
- }
-
- inline bool sendSegment() {
- if (segment == lastACKedSegment) {
- segment = increaseSegment(segment, 1);
- return false;
- } else {
- return true;
- }
- }
-
- inline uint8_t increaseSegment(uint8_t seg, uint8_t inc) { return seg + inc & 0x3; }
-
- void resetState() {
- protocol.reset();
- segment = (PASSIVE ? 1 : 0);
- lastACKedSegment = 0;
- std::memset(lastData, 0, N);
- }
- };
- #endif
|