2

I'm begining with gnuradio,

I'm trying to create a custom block. My goal is to read hex data from a txt file and send them in binary with a preamble.

I tried with the following code, but the work is sometimes exiting before the end, sometimes looping... It never reaches the conversion part. I suspect there is something wrong with my noutput somewhere.

Thanks in advance for all your help ! :)

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "acars_gen_impl.h"

namespace gr {
  namespace Acars_send {

    acars_gen::sptr
    acars_gen::make(char* file)
    {
      return gnuradio::get_initial_sptr
        (new acars_gen_impl(file));
    }

    /*
     * The private constructor
     */
    acars_gen_impl::acars_gen_impl(char* file)
      : gr::sync_block("acars_gen",
      gr::io_signature::make(0, 0, 0),
        gr::io_signature::make(1, 1, sizeof(char))),
        preamble_sync{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2B,0x2A,0x16,0x16}
        /*preamble_sync_bit{11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111,
      11111111,11111111,11111111,11111111,11111111,00101011,00101010,00010110,00010110}*/
{


  myfile.open(file);
  int ret = myfile.is_open();
  printf("Fichier ouvert %d\n",ret);
}
    /*
     * Our virtual destructor.
     */
    acars_gen_impl::~acars_gen_impl()
    {
      myfile.close();
      printf("Fichier fermé\n");
    }


    /* -------------
     *  W O R K
     -------------*/

    int
    acars_gen_impl::work (int noutput_items,
        gr_vector_const_void_star &input_items,
        gr_vector_void_star &output_items)
    {
      printf("Debut WORK\n");

      char *out = (char *) output_items[0];

      for(int i =0; i < noutput_items; i++){
      out[i] = 0;
      consume_each (noutput_items);
      }

    /*if (noutput_items<(162))
        return 0;*/
 //Compte du nombre de charactères du fichier

    char current_char;
    int c = 0;
    if (myfile.is_open()){

      printf("Fichier BIEN ouvert\n");
      while(myfile.get(current_char)){
        printf("%c\n",current_char);
        if(current_char == EOF)
          {
            break;
          }
          c++;
          printf("Taille : %d\n",c);

          }
        }

    myfile.clear();
    myfile.seekg(0, std::ios::beg);

    unsigned char message[c]={0};

    std::string line;
    getline (myfile,line);
    std::cout<<line;
    if (line.find("0x")==0) {
      printf("Trouvé!\n");

    int i = 0;

    for ( std::string::iterator it=(line.begin()+2); it!=line.end(); ++it){
        unsigned char hex = *it;
        unsigned char conv;
  printf("Conversion en cours %c\n",c);
        switch(toupper(c))
    {

        case '0': conv = 0;
        case '1': conv = 1;
        case '2': conv = 2;
        case '3': conv = 3;
        case '4': conv = 4;
        case '5': conv = 5;
        case '6': conv = 6;
        case '7': conv = 7;
        case '8': conv = 8;
        case '9': conv = 9;
        case 'A': conv = 10;
        case 'B': conv = 11;
        case 'C': conv = 12;
        case 'D': conv = 13;
        case 'E': conv = 14;
        case 'F': conv = 15;
    }


    message[i/2]= message[i/2] | (conv<< (4*(1-i%2)));
    ++i;

    }
  }

  for(int i=0 ; i < c ; i ++ ){
        std::cout << message[i];
  }

  memcpy(out,preamble_sync,20*sizeof(char));
  memcpy(out+20,message,c*sizeof(char));
  return noutput_items;
  return -1;

    }

  } /* namespace Acars_send */
} /* namespace gr */

1 Answers1

2

There are many things wrong with your code. It is very confused.

  • You use c as a count of characters in the file. Then you interpret it as a character with toupper[c] and ignore the hex character you just read.
  • Your hex conversion switch statement has no breaks and will therefore always result in conv = 15.
  • Your work function must write no more than noutput_items, and save the rest for later. Instead it is writing as many as it wants, possibly overflowing the provided buffer.

Given the mess here, I strongly recommend that you work on smaller problems first and get a stronger grasp of the language. Get your converter from hex working with just printing the results. Make a source block that doesn't read a file.

Also, turn on your C++ compiler's warnings and listen to them. It would likely have told you that your switch statement is broken.

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
  • Thanks for your answer ! These warnings were not displayed in my compiler.. I just fixed the two first errors. However, how can i control the noutput_items? If i add somethng like if (noutput_items<(162)) return 0; (162 is the length of the message i wish to write) at the begining of the code, will it allow the work function to process entirely? Thx in advance – Corentin Bresteau Jun 15 '17 at 13:59
  • @CorentinBresteau It _might_ work by accident, but as I already said, your work function must be able to produce some items and save the rest for later. You would usually do this by not reading the entire file at once. – Kevin Reid Jun 15 '17 at 14:08
  • The file i am trying to read will always be very small. I could read the length of the 'noutput', then read the same number of characters in the file and finally send the result after conversion? – Corentin Bresteau Jun 15 '17 at 14:16
  • @CorentinBresteau If you are only sending a short message, you don't need to make a custom block. Just read the file, convert it, and put the data into a `gr::blocks::vector_source_b`. – Kevin Reid Jun 15 '17 at 14:50