Add support for AX.25 frame tagging on the IQ stream

This commit is contained in:
Manolis Surligas 2019-09-19 15:24:23 +03:00
parent ab45da4ad3
commit 729d97c73c
7 changed files with 70 additions and 7 deletions

View File

@ -9,7 +9,7 @@
<name>Extra JSON field</name> <name>Extra JSON field</name>
<key>extra</key> <key>extra</key>
<value></value> <value></value>
<type>string</type> <type>raw</type>
</param> </param>
<sink> <sink>

View File

@ -136,7 +136,8 @@ private:
uint8_t *d_frame_buffer; uint8_t *d_frame_buffer;
std::deque<uint8_t> d_bitstream; std::deque<uint8_t> d_bitstream;
size_t d_start_idx; size_t d_start_idx;
size_t d_frame_start; uint64_t d_frame_start;
uint64_t d_sample_cnt;
void void
reset_state(); reset_state();

View File

@ -110,10 +110,18 @@ public:
int int
sizeof_input_item() const; sizeof_input_item() const;
protected:
void
incr_nitems_read(size_t nitems);
uint64_t
nitems_read() const;
private: private:
const int d_sizeof_in; const int d_sizeof_in;
const size_t d_max_frame_len; const size_t d_max_frame_len;
int d_id; int d_id;
uint64_t d_nitems_read;
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -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 new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN
+ sizeof(uint16_t)]), + sizeof(uint16_t)]),
d_start_idx(0), 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) { if (d_shift_reg == AX25_SYNC_FLAG) {
d_bitstream.erase(d_bitstream.begin(), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin() + i + 1); d_bitstream.begin() + i + 1);
/* Increment the number of items read so far */
incr_nitems_read(i);
enter_sync_state(); enter_sync_state();
d_frame_start = i; /* Mark possible start of the frame */
d_frame_start = nitems_read();
d_start_idx = 0; d_start_idx = 0;
cont = true; cont = true;
break; break;
@ -120,6 +124,7 @@ ax25_decoder::_decode(decoder_status_t &status)
if (cont) { if (cont) {
continue; continue;
} }
incr_nitems_read(d_bitstream.size());
d_bitstream.clear(); d_bitstream.clear();
return false; return false;
case IN_SYNC: 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++) { for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
decode_1b(d_bitstream[i]); decode_1b(d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) { if (d_shift_reg == AX25_SYNC_FLAG) {
d_sample_cnt = nitems_read() + i - d_frame_start;
LOG_DEBUG("Found frame end"); LOG_DEBUG("Found frame end");
if (enter_frame_end(status)) { if (enter_frame_end(status)) {
d_bitstream.erase(d_bitstream.begin(), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin() + i + 1); d_bitstream.begin() + i + 1);
/* Increment the number of items read so far */
incr_nitems_read(i);
d_start_idx = d_bitstream.size(); d_start_idx = d_bitstream.size();
return true; return true;
} }
@ -271,6 +279,7 @@ ax25_decoder::enter_frame_end(decoder_status_t &status)
metadata::add_time_iso8601(status.data); metadata::add_time_iso8601(status.data);
metadata::add_crc_valid(status.data, true); metadata::add_crc_valid(status.data, true);
metadata::add_sample_start(status.data, d_frame_start); metadata::add_sample_start(status.data, d_frame_start);
metadata::add_sample_cnt(status.data, d_sample_cnt);
status.decode_success = true; status.decode_success = true;
reset_state(); reset_state();
return true; return true;

View File

@ -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 * @param max_frame_len the maximum allowed frame size in bytes
*/ */
decoder::decoder(int input_item_size, size_t max_frame_len) decoder::decoder(int input_item_size, size_t max_frame_len)
: d_sizeof_in(input_item_size), : d_sizeof_in(input_item_size),
d_max_frame_len(max_frame_len), 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; return d_max_frame_len;
} }
/**
* @brief Return the size of the input stream
*
* @return int the sizeof() the input stream item
*/
int int
decoder::sizeof_input_item() const decoder::sizeof_input_item() const
{ {
return d_sizeof_in; 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 satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -62,8 +62,16 @@ json_converter_impl::~json_converter_impl()
void void
json_converter_impl::convert(pmt::pmt_t m) 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); 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 std::string &s = root.toStyledString();
const char *c = s.c_str(); const char *c = s.c_str();
message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length())); message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length()));

View File

@ -162,6 +162,11 @@ metadata::to_json(const pmt::pmt_t &m)
root[value(SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64(v)); 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); v = pmt::dict_ref(m, pmt::mp(value(SYMBOL_ERASURES)), pmt::PMT_NIL);
if (!pmt::equal(v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value(SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64(v)); root[value(SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64(v));