0
$\begingroup$

I am currently trying to develop a GNU Radio block which takes a tagged stream as an input. The tags keeps the length of the packets. But the distance between the tags and the packet length are not equal due to the burst type of data transmission. The block is planned to work like this:

1.It looks at the tags on the stream where they are.

2.After, it passes the stream data from the beginning of the tag up to the length of the packet_len (specified in the tag value).

  1. Then the rest is cropped.

The screenshot below gives a better understanding for my problem. I believe that the GNU Radio built-in functions and blocks can handle such an issue. Yet, i havent found it. efafa

My blocks diagram is given below. "My correlator" blocks finds the frame start and tags it with the packet len. I use "Tagged Stream Align" to prevent the stream from starting without a tag. The bypassed block is the block that I am looking for/trying to implement. enter image description here

Any king of help is welcome!

Best regards,

$\endgroup$
1
  • $\begingroup$ Hello, I recently fix my problem. I will post the answer as soon as i finished my scripting. $\endgroup$ Dec 26, 2021 at 11:39

1 Answer 1

1
$\begingroup$

The script below is my solution for my case. I hope that it could be useful for anyone facing the same issue. The code can be directly pasted in a "Embedded Python Block". I wrote some comments to explain the mechanism. I hope you find well. Any kind of improvement is welcome!

import numpy as np
from gnuradio import gr
import pmt

class my_basic_adder_block(gr.basic_block):
    def __init__(self,tag_name = 'packet_len'):
        gr.basic_block.__init__(self,
                                name="Tagged Stream Cropper",
                                in_sig  = [np.complex64],
                                out_sig = [np.complex64])

        self.previous_tag_n_remainder = 0
        self.tag_name                 = tag_name
        self.set_tag_propagation_policy(gr.TPP_DONT)


    def general_work(self, input_items, output_items):
        len_out = len(output_items[0])

        # DO PROCESSING
        out_produced = 0 # output produced 

        #-> Write the remaining data of the previous tag
        if self.previous_tag_n_remainder > 0: 
            if self.previous_tag_n_remainder < len_out: # if the length of the input items is sufficient to write the remainder of the previous tag items 
                output_items[0][:self.previous_tag_n_remainder] = input_items[0][:self.previous_tag_n_remainder] #write to output 
                out_produced                                   += self.previous_tag_n_remainder                  #inccrease the number of item produced
                self.previous_tag_n_remainder = 0                                                                #reset the counter 
                # the RETURN is at the end of the work()

            else: # self.previous_tag_n_remainder >= len_out
                output_items[0][:len_out]      = input_items[0][:len_out]
                self.previous_tag_n_remainder -= len_out
                self.consume(0, len_out)
                return len_out

        # READ TAGS AND PARSE THE RECEIVED STREAM
        tags = self.get_tags_in_window(0, out_produced, len_out)

        #if there exist tag
        if len(tags) > 0:
            #for each tag apply
            for tag in tags:
                tag_name   = pmt.to_python(tag.key)            # packet_tag
                tag_len    = pmt.to_python(tag.value)          # packet_len
                tag_pos    = tag.offset - self.nitems_read(0)  # packet_position_index
                if tag_name == self.tag_name:       #check if the tag name is appropriate
                    if tag_pos + tag_len < len_out: # if all the elements correspding to the "tag" are included in the input_items

                        # write the elements to the output
                        output_items[0][out_produced:(out_produced+tag_len)] = input_items[0][tag_pos:(tag_pos+tag_len)]

                        # add tag to the corresponding start point                     
                        self.add_item_tag(0,                                   # Write to output port 0
                                         self.nitems_written(0)+out_produced,  # Index of the tag in absolute terms
                                         tag.key,                              # Key of the tag
                                         tag.value                             # Value of the tag
                                         )
                        #increase the number of output element produced counter
                        out_produced += tag_len

                    else: #tag_pos+tag_len >= len_out:
                        n_item_to_wrt = len_out - tag_pos
                        output_items[0][out_produced:(out_produced + n_item_to_wrt)] = input_items[0][tag_pos:(tag_pos+n_item_to_wrt)]

                        self.add_item_tag(0,                                     # Write to output port 0
                                          self.nitems_written(0)+out_produced,   # Index of the tag in absolute terms
                                          tag.key,                               # Key of the tag
                                          tag.value                              # Value of the tag
                                          )

                        self.previous_tag_n_remainder = tag_len - n_item_to_wrt
                        out_produced                 += n_item_to_wrt
                        self.consume(0,len_out)
                        return out_produced

        #if there is no tag exits
        self.consume(0,len_out)

        #recall that the first "if" state is producing element!
        return out_produced
```
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.