/*! * \file raw_array_impl.cc * \brief GNU Radio source block to acces to experimental GNSS Array platform. * \author Javier Arribas, 2014. jarribas(at)cttc.es * * ------------------------------------------------------------------------- * * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver * * This file is part of GNSS-SDR. * * GNSS-SDR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * at your option) any later version. * * GNSS-SDR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "raw_array_impl.h" #include #include #include #include #include #include #include #define FIFO_SIZE 1000000 #define DBFCTTC_NUM_CHANNELS 8 namespace gr { namespace dbfcttc { raw_array::sptr raw_array::make(const char *src_device,short number_of_channels, int snapshots_per_frame, int inter_frame_delay, int sampling_freq) { return gnuradio::get_initial_sptr (new raw_array_impl(src_device, number_of_channels, snapshots_per_frame, inter_frame_delay, sampling_freq)); } /* * The private constructor */ raw_array_impl::raw_array_impl(const char *src_device,short number_of_channels, int snapshots_per_frame, int inter_frame_delay, int sampling_freq) : gr::sync_block("raw_array", gr::io_signature::make(0, 0, 0), gr::io_signature::make(8, 8, sizeof(gr_complex))) { // constructor code here fprintf(stdout,"DBFCTTC Start\n"); d_src_device=src_device; d_number_of_channels=number_of_channels; d_snapshots_per_frame=snapshots_per_frame; d_inter_frame_delay=inter_frame_delay; d_sampling_freq=sampling_freq; d_flag_start_frame=true; d_fifo_full=false; d_last_frame_counter=0; d_num_rx_errors=0; flag_16_bits_sample=true; //allocate signal samples buffer //TODO: Check memory pointers fifo_buff_ch=new gr_complex*[DBFCTTC_NUM_CHANNELS]; for (int i=0;i beamforming config // command=2 -> start // command=3 -> stop // command=4 -> raw array config char data[20]; for(int i=0;i<20;i++) { data[i]=0x00; } data[0]=4; //command to activate RAW array data[1]=d_number_of_channels; data[2]=d_snapshots_per_frame>>8; data[3]=d_snapshots_per_frame & 255; printf("\n Total bytes in snapshots payload = %i\n",d_snapshots_per_frame*d_number_of_channels*2); printf("\n Estimated eth RAW frame size [bytes] %i\n",12+2+3+d_snapshots_per_frame*d_number_of_channels*2+1); data[4]=d_inter_frame_delay>>8; data[5]=d_inter_frame_delay & 255; data[6]=0xB; data[7]=0xF; //send the frame struct ether_header myheader; myheader.ether_type=0xbfcd; //this is the ethenet layer II protocol ID for the CTTC array hardware memset(myheader.ether_dhost,0xff,sizeof(myheader.ether_dhost)); memset(myheader.ether_shost,0x11,sizeof(myheader.ether_shost)); unsigned char frame[sizeof(struct ether_header)+sizeof(data)]; memcpy(frame,&myheader,sizeof(struct ether_header)); memcpy(frame+sizeof(struct ether_header),&data,sizeof(data)); if (pcap_inject(descr,frame,sizeof(frame))==-1) { printf("Error sending configuration packet\n"); pcap_perror(descr,0); return false; }else{ printf("Sent configuration packet OK\n"); return true; } } bool raw_array_impl::start_array() { char data[20]; for(int i=0;i<20;i++) { data[i]=0x00; } data[0]=2; //command to start the array operation (configured previously) //send the frame struct ether_header myheader; myheader.ether_type=0xbfcd; //this is the ethenet layer II protocol ID for the CTTC array hardware memset(myheader.ether_dhost,0xff,sizeof(myheader.ether_dhost)); memset(myheader.ether_shost,0x11,sizeof(myheader.ether_shost)); unsigned char frame[sizeof(struct ether_header)+sizeof(data)]; memcpy(frame,&myheader,sizeof(struct ether_header)); memcpy(frame+sizeof(struct ether_header),&data,sizeof(data)); if (pcap_inject(descr,frame,sizeof(frame))==-1) { printf("Error sending start packet\n"); pcap_perror(descr,0); return false; }else{ printf("Sent start packet OK\n"); return true; } } bool raw_array_impl::stop_array() { char data[20]; for(int i=0;i<20;i++) { data[i]=0x00; } data[0]=3; //command to stop the array operation (configured previously) //send the frame struct ether_header myheader; myheader.ether_type=0xbfcd; //this is the ethenet layer II protocol ID for the CTTC array hardware memset(myheader.ether_dhost,0xff,sizeof(myheader.ether_dhost)); memset(myheader.ether_shost,0x11,sizeof(myheader.ether_shost)); unsigned char frame[sizeof(struct ether_header)+sizeof(data)]; memcpy(frame,&myheader,sizeof(struct ether_header)); memcpy(frame+sizeof(struct ether_header),&data,sizeof(data)); if (pcap_inject(descr,frame,sizeof(frame))==-1) { printf("Error sending stop packet\n"); pcap_perror(descr,0); return false; }else{ printf("Sent stop packet OK\n"); return true; } } /* * Our virtual destructor. */ raw_array_impl::~raw_array_impl() { // destructor code here if (stop_array()==true) { printf("Array stopped!\n"); }else{ exit(1); //ethernet error! } if(descr != NULL) { pcap_breakloop(descr); d_pcap_thread->join(); pcap_close(descr); } for (int i=0;ipcap_callback(args, pkthdr, packet); } void raw_array_impl::pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet) { boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function int numframebyte; short int real,imag; // eth frame parameters int number_of_channels; unsigned short int snapshots_per_frame; // **** CTTC DBF PACKET DECODER **** if ((packet[12]==0xCD) & (packet[13]==0xBF)) { //printf("."); // control parameters number_of_channels=(int)packet[14]; //std::cout<<"number_of_channels="<(real, imag); fifo_buff_ch[ch][fifo_write_ptr] = std::complex(imag, real); //inverted due to inversion in front-end //std::cout<<"["<=num_samples_readed) { //read all in a single memcpy for (int ch=0;ch )*num_samples_readed); } fifo_read_ptr=fifo_read_ptr+num_samples_readed; //increase the fifo pointer if (fifo_read_ptr==FIFO_SIZE) fifo_read_ptr=0; }else{ //two step wrap read for (int ch=0;ch )*aligned_read_items); } fifo_read_ptr=fifo_read_ptr+aligned_read_items; //increase the fifo pointer if (fifo_read_ptr==FIFO_SIZE) fifo_read_ptr=0; for (int ch=0;ch)*(num_samples_readed-aligned_read_items)); } fifo_read_ptr=fifo_read_ptr+(num_samples_readed-aligned_read_items); //increase the fifo pointer } fifo_items=fifo_items-num_samples_readed; // int num_samples_readed=0; // for(int i=0;i 0) { // //TODO: optimize-me with memcpy!! // for (int ch=0;ch