diff --git a/grc/satnogs_json_converter.xml b/grc/satnogs_json_converter.xml
index cbd03d9..b8a7f70 100644
--- a/grc/satnogs_json_converter.xml
+++ b/grc/satnogs_json_converter.xml
@@ -9,7 +9,7 @@
Extra JSON field
extra
- string
+ raw
diff --git a/include/satnogs/ax25_decoder.h b/include/satnogs/ax25_decoder.h
index 0cb7649..6da42ea 100644
--- a/include/satnogs/ax25_decoder.h
+++ b/include/satnogs/ax25_decoder.h
@@ -136,7 +136,8 @@ private:
uint8_t *d_frame_buffer;
std::deque d_bitstream;
size_t d_start_idx;
- size_t d_frame_start;
+ uint64_t d_frame_start;
+ uint64_t d_sample_cnt;
void
reset_state();
diff --git a/include/satnogs/decoder.h b/include/satnogs/decoder.h
index c0c01d6..0e1ee3d 100644
--- a/include/satnogs/decoder.h
+++ b/include/satnogs/decoder.h
@@ -110,10 +110,18 @@ public:
int
sizeof_input_item() const;
+protected:
+ void
+ incr_nitems_read(size_t nitems);
+
+ uint64_t
+ nitems_read() const;
+
private:
const int d_sizeof_in;
const size_t d_max_frame_len;
int d_id;
+ uint64_t d_nitems_read;
};
} // namespace satnogs
diff --git a/lib/ax25_decoder.cc b/lib/ax25_decoder.cc
index 765ba94..d1a7df1 100644
--- a/lib/ax25_decoder.cc
+++ b/lib/ax25_decoder.cc
@@ -57,7 +57,8 @@ ax25_decoder::ax25_decoder(const std::string &addr, uint8_t ssid, bool promisc,
new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN
+ sizeof(uint16_t)]),
d_start_idx(0),
- d_frame_start(0)
+ d_frame_start(0),
+ d_sample_cnt(0)
{
}
@@ -110,8 +111,11 @@ ax25_decoder::_decode(decoder_status_t &status)
if (d_shift_reg == AX25_SYNC_FLAG) {
d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin() + i + 1);
+ /* Increment the number of items read so far */
+ incr_nitems_read(i);
enter_sync_state();
- d_frame_start = i;
+ /* Mark possible start of the frame */
+ d_frame_start = nitems_read();
d_start_idx = 0;
cont = true;
break;
@@ -120,6 +124,7 @@ ax25_decoder::_decode(decoder_status_t &status)
if (cont) {
continue;
}
+ incr_nitems_read(d_bitstream.size());
d_bitstream.clear();
return false;
case IN_SYNC:
@@ -151,10 +156,13 @@ ax25_decoder::_decode(decoder_status_t &status)
for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
decode_1b(d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) {
+ d_sample_cnt = nitems_read() + i - d_frame_start;
LOG_DEBUG("Found frame end");
if (enter_frame_end(status)) {
d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin() + i + 1);
+ /* Increment the number of items read so far */
+ incr_nitems_read(i);
d_start_idx = d_bitstream.size();
return true;
}
@@ -271,6 +279,7 @@ ax25_decoder::enter_frame_end(decoder_status_t &status)
metadata::add_time_iso8601(status.data);
metadata::add_crc_valid(status.data, true);
metadata::add_sample_start(status.data, d_frame_start);
+ metadata::add_sample_cnt(status.data, d_sample_cnt);
status.decode_success = true;
reset_state();
return true;
diff --git a/lib/decoder.cc b/lib/decoder.cc
index fa690af..575710c 100644
--- a/lib/decoder.cc
+++ b/lib/decoder.cc
@@ -41,13 +41,16 @@ decoder::unique_id()
}
/**
- * Creates a generic decoder object
+ * @brief Construct a new decoder::decoder object
+ *
+ * @param input_item_size the sizeof() the input stream item
* @param max_frame_len the maximum allowed frame size in bytes
*/
decoder::decoder(int input_item_size, size_t max_frame_len)
: d_sizeof_in(input_item_size),
d_max_frame_len(max_frame_len),
- d_id(base_unique_id++)
+ d_id(base_unique_id++),
+ d_nitems_read(0)
{
}
@@ -81,12 +84,41 @@ decoder::max_frame_len() const
return d_max_frame_len;
}
+/**
+ * @brief Return the size of the input stream
+ *
+ * @return int the sizeof() the input stream item
+*/
int
decoder::sizeof_input_item() const
{
return d_sizeof_in;
}
+
+/**
+ * @brief Increaments the number of items read so far
+ *
+ * @param nitems the number of items read
+ */
+void
+decoder::incr_nitems_read(size_t nitems)
+{
+ d_nitems_read += nitems;
+}
+
+/**
+ * @brief Return the number of items read so far
+ *
+ * @return uint64_t number of items read so far
+ */
+uint64_t
+decoder::nitems_read() const
+{
+ return d_nitems_read;
+}
+
+
} /* namespace satnogs */
} /* namespace gr */
diff --git a/lib/json_converter_impl.cc b/lib/json_converter_impl.cc
index c77b299..5a01553 100644
--- a/lib/json_converter_impl.cc
+++ b/lib/json_converter_impl.cc
@@ -62,8 +62,16 @@ json_converter_impl::~json_converter_impl()
void
json_converter_impl::convert(pmt::pmt_t m)
{
+ Json::CharReaderBuilder crb;
+ Json::CharReader *cr = crb.newCharReader();
+ Json::Value extra;
+ std::string err;
+
+
Json::Value root = metadata::to_json(m);
- root["extra"] = d_extra;
+ if (cr->parse(d_extra.c_str(), d_extra.c_str() + d_extra.size(), &extra, &err)) {
+ root["extra"] = extra;
+ }
const std::string &s = root.toStyledString();
const char *c = s.c_str();
message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length()));
diff --git a/lib/metadata.cc b/lib/metadata.cc
index da8931c..5c435a9 100644
--- a/lib/metadata.cc
+++ b/lib/metadata.cc
@@ -162,6 +162,11 @@ metadata::to_json(const pmt::pmt_t &m)
root[value(SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64(v));
}
+ v = pmt::dict_ref(m, pmt::mp(value(SAMPLE_CNT)), pmt::PMT_NIL);
+ if (!pmt::equal(v, pmt::PMT_NIL)) {
+ root[value(SAMPLE_CNT)] = Json::Value::UInt64(pmt::to_uint64(v));
+ }
+
v = pmt::dict_ref(m, pmt::mp(value(SYMBOL_ERASURES)), pmt::PMT_NIL);
if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value(SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64(v));