Hi
I am implementing a complete protocol in a module where most of the MAC
layer will be placed in a tagged stream block. I intend to start out
implementing the transmit chain and then the receive chain.
The problem I have run into is that until I get to the receive chain,
the
MAC layer block will need to function as a source, but is that at all
possible based on a tagged stream block?
At the moment the block crashes (silently) in line 102 of the
gr::tagged_stream_block::general_work.
The line in question contains: if(d_n_input_items_reqd[0] == 0)
I believe the cause of the crash is that d_n_input_items_reqd is not
set
or not set to a valid value by the parse_length_tags method, since it
is
responsible for extracting the length tags on all input ports, but this
block, being configured as a source block, does not have any input
ports.
Would it be possible to overcome this by overriding the
*parse_length_tags *method
and setting d_n_input_items_reqd to something valid?
And if yes, what would be a valid value?
My implementation of calculate_output_stream_length just returns a
constant integer.
Best regards
David Marmoy
For convenience here is the relevant code from gr::tagged_stream_block:
void
tagged_stream_block::parse_length_tags(const
std::vector<std::vector<tag_t> > &tags,
gr_vector_int
&n_input_items_reqd)
{
for(unsigned i = 0; i < tags.size(); i++) {
for(unsigned k = 0; k < tags[i].size(); k++) {
if(tags[i][k].key == d_length_tag_key) {
n_input_items_reqd[i] = pmt::to_long(tags[i][k].value);
remove_item_tag(i, tags[i][k]);
}
}
}
}
int
tagged_stream_block::general_work(int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star
&input_items,
gr_vector_void_star &output_items)
{
if(d_length_tag_key_str.empty()) {
return work(noutput_items, ninput_items, input_items,
output_items);
}
if(d_n_input_items_reqd[0] == 0) { // Otherwise, it's already set
from
a previous call
std::vector<std::vector<tag_t> > tags(input_items.size(),
std::vector<tag_t>());
for(unsigned i = 0; i < input_items.size(); i++) {
get_tags_in_range(tags[i], i, nitems_read(i), nitems_read(i)+1);
}
d_n_input_items_reqd.assign(input_items.size(), -1);
parse_length_tags(tags, d_n_input_items_reqd);
}
for(unsigned i = 0; i < input_items.size(); i++) {
if(d_n_input_items_reqd[i] == -1) {
GR_LOG_FATAL(d_logger, boost::format(“Missing a required length
tag
on port %1% at item #%2%”) % i % nitems_read(i));
throw std::runtime_error(“Missing length tag.”);
}
if(d_n_input_items_reqd[i] > ninput_items[i]) {
return 0;
}
}
int min_output_size =
calculate_output_stream_length(d_n_input_items_reqd);
if(noutput_items < min_output_size) {
set_min_noutput_items(min_output_size);
return 0;
}
set_min_noutput_items(1);
// WORK CALLED HERE //
int n_produced = work(noutput_items, d_n_input_items_reqd,
input_items,
output_items);
//////////////////////
if(n_produced == WORK_DONE) {
return n_produced;
}
for(int i = 0; i < (int) d_n_input_items_reqd.size(); i++) {
consume(i, d_n_input_items_reqd[i]);
}
if (n_produced > 0) {
update_length_tags(n_produced, output_items.size());
}
d_n_input_items_reqd.assign(input_items.size(), 0);
return n_produced;
}