aboutsummaryrefslogtreecommitdiffstats
path: root/lib/edi
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2016-12-26 22:20:35 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2016-12-26 22:20:35 +0100
commit37f5c2d4654580aa9d1195490d4a911b9b079acb (patch)
tree8cd76a87fe430eb0959f759ff7894c6667aa4016 /lib/edi
parentfd6d695275f88e83ebba6fa39afc044e329a690f (diff)
downloaddabmod-37f5c2d4654580aa9d1195490d4a911b9b079acb.tar.gz
dabmod-37f5c2d4654580aa9d1195490d4a911b9b079acb.tar.bz2
dabmod-37f5c2d4654580aa9d1195490d4a911b9b079acb.zip
EDI: Handle RFU bits and add some sanity checks
Diffstat (limited to 'lib/edi')
-rw-r--r--lib/edi/ETIDecoder.cpp36
-rw-r--r--lib/edi/ETIDecoder.hpp2
-rw-r--r--lib/edi/ETIWriter.cpp13
-rw-r--r--lib/edi/ETIWriter.hpp5
4 files changed, 48 insertions, 8 deletions
diff --git a/lib/edi/ETIDecoder.cpp b/lib/edi/ETIDecoder.cpp
index 36e49fa..c79054b 100644
--- a/lib/edi/ETIDecoder.cpp
+++ b/lib/edi/ETIDecoder.cpp
@@ -154,9 +154,18 @@ decode_state_t ETIDecoder::decode_afpacket(
// read length from packet
uint32_t taglength = read_32b(input_data.begin() + 2);
uint16_t seq = read_16b(input_data.begin() + 6);
+ if (m_last_seq + 1 != seq) {
+ etiLog.level(warn) << "EDI AF Packet sequence error";
+ }
+ m_last_seq = seq;
bool has_crc = (input_data[8] & 0x80) ? true : false;
- uint8_t revision = input_data[8] & 0x7F;
+ uint8_t major_revision = (input_data[8] & 0x70) >> 4;
+ uint8_t minor_revision = input_data[8] & 0x0F;
+ if (major_revision != 1 or minor_revision != 0) {
+ throw invalid_argument("EDI AF Packet has wrong revision " +
+ to_string(major_revision) + "." + to_string(minor_revision));
+ }
uint8_t pt = input_data[9];
if (pt != 'T') {
// only support Tag
@@ -298,9 +307,13 @@ bool ETIDecoder::decode_deti(const vector<uint8_t> &value)
fc.mid = (etiHeader >> 22) & 0x03;
fc.fp = (etiHeader >> 19) & 0x07;
- bool rfa = (etiHeader >> 17) & 0x1;
+ uint8_t rfa = (etiHeader >> 17) & 0x3;
+ if (rfa != 0) {
+ etiLog.log(warn, "EDI deti TAG: rfa non-zero");
+ }
+
bool rfu = (etiHeader >> 16) & 0x1;
- uint16_t mnsc = etiHeader & 0xFFFF;
+ uint16_t mnsc = rfu ? 0xFFFF : etiHeader & 0xFFFF;
const size_t fic_length_words = (fc.ficf ? (fc.mid == 3 ? 32 : 24) : 0);
const size_t fic_length = 4 * fic_length_words;
@@ -311,9 +324,10 @@ bool ETIDecoder::decode_deti(const vector<uint8_t> &value)
(rfudf ? 3 : 0);
if (value.size() != expected_length) {
- etiLog.log(warn, " Assertion error: value.size() != expected_length: %zu %zu\n",
- value.size(), expected_length);
- assert(false);
+ throw std::logic_error("EDI deti: Assertion error:"
+ "value.size() != expected_length: " +
+ to_string(value.size()) + " " +
+ to_string(expected_length));
}
m_eti_writer.update_err(stat);
@@ -352,6 +366,13 @@ bool ETIDecoder::decode_deti(const vector<uint8_t> &value)
if (rfudf) {
uint32_t rfud = read_24b(value.begin() + i);
+ // high 16 bits: RFU in LIDATA EOH
+ // low 8 bits: RFU in TIST (not supported)
+ m_eti_writer.update_rfu(rfud >> 8);
+ if ((rfud & 0xFF) != 0xFF) {
+ etiLog.level(warn) << "EDI: RFU in TIST not supported";
+ }
+
i += 3;
}
@@ -370,6 +391,9 @@ bool ETIDecoder::decode_estn(const vector<uint8_t> &value, uint8_t n)
stc.sad = (sstc >> 8) & 0x3FF;
stc.tpl = (sstc >> 2) & 0x3F;
uint8_t rfa = sstc & 0x3;
+ if (rfa != 0) {
+ etiLog.level(warn) << "EDI: rfa field in ESTn tag non-null";
+ }
copy( value.begin() + 3,
value.end(),
diff --git a/lib/edi/ETIDecoder.hpp b/lib/edi/ETIDecoder.hpp
index e0c7218..cec284f 100644
--- a/lib/edi/ETIDecoder.hpp
+++ b/lib/edi/ETIDecoder.hpp
@@ -68,6 +68,8 @@ class ETIDecoder {
PFT::PFT m_pft;
+ uint16_t m_last_seq;
+
std::vector<uint8_t> m_input_data;
};
diff --git a/lib/edi/ETIWriter.cpp b/lib/edi/ETIWriter.cpp
index 0eb3feb..bd051dd 100644
--- a/lib/edi/ETIWriter.cpp
+++ b/lib/edi/ETIWriter.cpp
@@ -117,6 +117,15 @@ void ETIWriter::update_mnsc(uint16_t mnsc)
m_mnsc = mnsc;
}
+void ETIWriter::update_rfu(uint16_t rfu)
+{
+ if (not m_proto_valid) {
+ throw std::logic_error("Cannot update RFU before protocol");
+ }
+
+ m_rfu = rfu;
+}
+
void ETIWriter::add_subchannel(const eti_stc_data& stc)
{
if (not m_proto_valid) {
@@ -242,8 +251,8 @@ void ETIWriter::assemble()
eti.push_back(mst_crc & 0xFF);
// RFU
- eti.push_back(0xff);
- eti.push_back(0xff);
+ eti.push_back(m_rfu >> 8);
+ eti.push_back(m_rfu);
// TIST
eti.push_back(m_fc.tsta >> 24);
diff --git a/lib/edi/ETIWriter.hpp b/lib/edi/ETIWriter.hpp
index 001f537..aa907fc 100644
--- a/lib/edi/ETIWriter.hpp
+++ b/lib/edi/ETIWriter.hpp
@@ -79,6 +79,8 @@ class ETIWriter {
void update_mnsc(uint16_t mnsc);
+ void update_rfu(uint16_t rfu);
+
void add_subchannel(const eti_stc_data& stc);
// Tell the ETIWriter that the AFPacket is complete
@@ -109,6 +111,9 @@ class ETIWriter {
uint32_t m_seconds;
uint16_t m_mnsc = 0xffff;
+
+ // 16 bits: RFU field in EOH
+ uint16_t m_rfu = 0xffff;
};
}