mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Optimizing custom UDP packet source and applying code style
This commit is contained in:
		| @@ -6,23 +6,25 @@ | |||||||
|  |  | ||||||
| ;######### GLOBAL OPTIONS ################## | ;######### GLOBAL OPTIONS ################## | ||||||
| ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. | ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. | ||||||
| ;GNSS-SDR.internal_fs_sps=3312500 | GNSS-SDR.internal_fs_sps=13250000 ;//66.25/5 | ||||||
| GNSS-SDR.internal_fs_sps=2650000 | ;GNSS-SDR.internal_fs_sps=6625000  ;//66.25/10 | ||||||
|  | ;GNSS-SDR.internal_fs_sps=3312500 ;//66.25/20 | ||||||
|  | ;GNSS-SDR.internal_fs_sps=2650000  ;//66.25/25 | ||||||
|  |  | ||||||
| ;######### SIGNAL_SOURCE CONFIG ############ | ;######### SIGNAL_SOURCE CONFIG ############ | ||||||
| SignalSource.implementation=UDP_Signal_Source | SignalSource.implementation=UDP_Signal_Source | ||||||
| ;SignalSource.implementation=File_Signal_Source | ;SignalSource.implementation=File_Signal_Source | ||||||
| SignalSource.filename=/home/javier/gnss/gnss-simulator/build/signal_out.bin ; <- PUT YOUR FILE HERE | ;SignalSource.filename=/home/javier/gnss/gnss-simulator/build/signal_out.bin ; <- PUT YOUR FILE HERE | ||||||
| SignalSource.item_type=gr_complex | SignalSource.item_type=gr_complex | ||||||
| SignalSource.origin_address=0.0.0.0 | SignalSource.origin_address=0.0.0.0 | ||||||
| SignalSource.capture_device=eth0 | SignalSource.capture_device=eth0 | ||||||
| SignalSource.port=1234 | SignalSource.port=1234 | ||||||
| SignalSource.payload_bytes=1472 | SignalSource.payload_bytes=1472 | ||||||
| SignalSource.sample_type=cbyte | ;SignalSource.sample_type=cbyte | ||||||
|  | SignalSource.sample_type=c4bits | ||||||
|  | SignalSource.IQ_swap=false | ||||||
| SignalSource.RF_channels=1 | SignalSource.RF_channels=1 | ||||||
| SignalSource.select_single_channel=0 |  | ||||||
| SignalSource.channels_in_udp=2 | SignalSource.channels_in_udp=2 | ||||||
| SignalSource.IQ_swap=true |  | ||||||
| SignalSource.dump=false | SignalSource.dump=false | ||||||
| SignalSource.dump_filename=./signal_source.dat | SignalSource.dump_filename=./signal_source.dat | ||||||
|  |  | ||||||
| @@ -33,12 +35,22 @@ SignalConditioner.implementation=Pass_Through | |||||||
| ;SignalConditioner1.implementation=Pass_Through | ;SignalConditioner1.implementation=Pass_Through | ||||||
|  |  | ||||||
| ;######### CHANNELS GLOBAL CONFIG ############ | ;######### CHANNELS GLOBAL CONFIG ############ | ||||||
| Channels_1C.count=1 | Channels_1C.count=8 | ||||||
| Channels.in_acquisition=1 | Channels.in_acquisition=1 | ||||||
|  |  | ||||||
| ;# CHANNEL CONNECTION | ;# CHANNEL CONNECTION | ||||||
| Channel.signal=1C | Channel.signal=1C | ||||||
| ;Channel0.RF_channel_ID=0 | Channel0.RF_channel_ID=0 | ||||||
|  | Channel1.RF_channel_ID=0 | ||||||
|  | Channel2.RF_channel_ID=0 | ||||||
|  | Channel3.RF_channel_ID=0 | ||||||
|  | Channel4.RF_channel_ID=0 | ||||||
|  | Channel5.RF_channel_ID=0 | ||||||
|  | Channel6.RF_channel_ID=0 | ||||||
|  | Channel7.RF_channel_ID=0 | ||||||
|  | Channel8.RF_channel_ID=1 | ||||||
|  | Channel9.RF_channel_ID=1 | ||||||
|  |  | ||||||
| ;Channel0.signal=1C | ;Channel0.signal=1C | ||||||
| ;Channel1.RF_channel_ID=1 | ;Channel1.RF_channel_ID=1 | ||||||
| ;Channel1.signal=1C | ;Channel1.signal=1C | ||||||
| @@ -46,11 +58,11 @@ Channel.signal=1C | |||||||
| ;######### ACQUISITION GLOBAL CONFIG ############ | ;######### ACQUISITION GLOBAL CONFIG ############ | ||||||
| Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition | Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition | ||||||
| Acquisition_1C.item_type=gr_complex | Acquisition_1C.item_type=gr_complex | ||||||
| Acquisition_1C.threshold=60 | Acquisition_1C.threshold=17 | ||||||
| Acquisition_1C.use_CFAR_algorithm=false | Acquisition_1C.use_CFAR_algorithm=false | ||||||
| Acquisition_1C.blocking=false | Acquisition_1C.blocking=false | ||||||
| Acquisition_1C.doppler_max=5000 | Acquisition_1C.doppler_max=5000 | ||||||
| Acquisition_1C.doppler_step=500 | Acquisition_1C.doppler_step=250 | ||||||
| Acquisition_1C.dump=false | Acquisition_1C.dump=false | ||||||
| Acquisition_1C.dump_filename=./acq_dump.dat | Acquisition_1C.dump_filename=./acq_dump.dat | ||||||
|  |  | ||||||
| @@ -78,7 +90,7 @@ Observables.dump_filename=./observables.dat | |||||||
|  |  | ||||||
| ;######### PVT CONFIG ############ | ;######### PVT CONFIG ############ | ||||||
| PVT.implementation=RTKLIB_PVT | PVT.implementation=RTKLIB_PVT | ||||||
| PVT.positioning_mode=Single  ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic | PVT.positioning_mode=PPP_Static  ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic | ||||||
| PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX | PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX | ||||||
| PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad | PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad | ||||||
| PVT.output_rate_ms=100 | PVT.output_rate_ms=100 | ||||||
|   | |||||||
| @@ -1,13 +1,12 @@ | |||||||
| /*! | /*! | ||||||
|  * \file rtl_tcp_signal_source.cc |  * \file udp_signal_source.cc | ||||||
|  * \brief Signal source for the Realtek RTL2832U USB dongle DVB-T receiver |  | ||||||
|  *        over TCP. |  | ||||||
|  * (see http://sdr.osmocom.org/trac/wiki/rtl-sdr for more information) |  | ||||||
|  * \author Anthony Arnold, 2015. anthony.arnold(at)uqconnect.edu.au |  | ||||||
|  * |  * | ||||||
|  |  * \brief Receives ip frames containing samples in UDP frame encapsulation | ||||||
|  |  * using a high performance packet capture library (libpcap) | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) |  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||||
|  * |  * | ||||||
|  * GNSS-SDR is a software defined Global Navigation |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  *          Satellite Systems receiver |  *          Satellite Systems receiver | ||||||
| @@ -30,6 +29,7 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "udp_signal_source.h" | #include "udp_signal_source.h" | ||||||
| #include "configuration_interface.h" | #include "configuration_interface.h" | ||||||
| #include "GPS_L1_CA.h" | #include "GPS_L1_CA.h" | ||||||
| @@ -64,58 +64,46 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, | |||||||
|  |  | ||||||
|  |  | ||||||
|     RF_channels_ = configuration->property(role + ".RF_channels", 1); |     RF_channels_ = configuration->property(role + ".RF_channels", 1); | ||||||
|     select_single_channel_ = configuration->property(role + ".select_single_channel", 0); |     channels_in_udp_ = configuration->property(role + ".channels_in_udp", 1); | ||||||
|     channels_in_udp_= configuration->property(role + ".channels_in_udp", 1); |     IQ_swap_ = configuration->property(role + ".IQ_swap", false); | ||||||
|     IQ_swap_= configuration->property(role + ".IQ_swap", false); |  | ||||||
|  |  | ||||||
|     std::string default_sample_type = "cbyte"; |     std::string default_sample_type = "cbyte"; | ||||||
|     std::string sample_type = configuration->property(role + ".sample_type", default_sample_type); |     std::string sample_type = configuration->property(role + ".sample_type", default_sample_type); | ||||||
|     item_type_ = configuration->property(role + ".item_type", default_item_type); |     item_type_ = configuration->property(role + ".item_type", default_item_type); | ||||||
|  |     //output item size is always gr_complex | ||||||
|  |     item_size_ = sizeof(gr_complex); | ||||||
|  |  | ||||||
|     if (sample_type.compare("cbyte")==0) |     udp_gnss_rx_source_ = gr_complex_ip_packet_source::make(capture_device, | ||||||
|     { |         address, | ||||||
|         udp_gnss_rx_source_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); |         port, | ||||||
|         demux_=gr::blocks::deinterleave::make(sizeof(char),1); |         payload_bytes, | ||||||
|     }else{ |         channels_in_udp_, | ||||||
|         std::cout<<"WARNING: Requested UDP sample type unsuported, setting sample type to cbyte\n"; |         sample_type, | ||||||
|         udp_gnss_rx_source_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); |         item_size_, | ||||||
|         demux_=gr::blocks::deinterleave::make(sizeof(char),1); |         IQ_swap_); | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //create I, Q -> gr_complex type conversion blocks |     if (channels_in_udp_ >= RF_channels_) | ||||||
|     for (int n = 0; n < (channels_in_udp_ * 2); n++) |  | ||||||
|         { |  | ||||||
|             char_to_float_.push_back(gr::blocks::char_to_float::make()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     for (int n = 0; n < channels_in_udp_; n++) |  | ||||||
|         { |  | ||||||
|             float_to_complex_.push_back(gr::blocks::float_to_complex::make()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     if (channels_in_udp_>RF_channels_) |  | ||||||
|         { |         { | ||||||
|             for (int n = 0; n < channels_in_udp_; n++) |             for (int n = 0; n < channels_in_udp_; n++) | ||||||
|                 { |                 { | ||||||
|                     null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); |                     null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); | ||||||
|                 } |                 } | ||||||
|     }else |         } | ||||||
|  |     else | ||||||
|         { |         { | ||||||
|         std::cout<<"Configuration error: RF_channels<channels_in_use"<<std::endl; |             std::cout << "Configuration error: RF_channels<channels_in_use" << std::endl; | ||||||
|             exit(0); |             exit(0); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     //output item size is always gr_complex |  | ||||||
|     item_size_ = sizeof(gr_complex); |  | ||||||
|     if (dump_) |     if (dump_) | ||||||
|         { |         { | ||||||
|             for (int n = 0; n < channels_in_udp_; n++) |             for (int n = 0; n < channels_in_udp_; n++) | ||||||
|                 { |                 { | ||||||
|                 DLOG(INFO) << "Dumping output into file " << (dump_filename_+"c_h"+std::to_string(n)+".bin"); |                     DLOG(INFO) << "Dumping output into file " << (dump_filename_ + "c_h" + std::to_string(n) + ".bin"); | ||||||
|                 file_sink_.push_back(gr::blocks::file_sink::make(item_size_, (dump_filename_+"_ch"+std::to_string(n)+".bin").c_str())); |                     file_sink_.push_back(gr::blocks::file_sink::make(item_size_, (dump_filename_ + "_ch" + std::to_string(n) + ".bin").c_str())); | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -126,43 +114,18 @@ UDPSignalSource::~UDPSignalSource() | |||||||
|  |  | ||||||
| void UDPSignalSource::connect(gr::top_block_sptr top_block) | void UDPSignalSource::connect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|     top_block->connect(udp_gnss_rx_source_,0, demux_,0); |  | ||||||
|     DLOG(INFO)<<"connected udp_source to demux"<<std::endl; |  | ||||||
|     for (int n = 0; n < (channels_in_udp_ * 2); n++) |  | ||||||
|         { |  | ||||||
|  |  | ||||||
|             top_block->connect(demux_, n, char_to_float_.at(n), 0); |  | ||||||
|             DLOG(INFO) << "connected demux to char_to_float CH" << n; |  | ||||||
|         } |  | ||||||
|     for (int n = 0; n < channels_in_udp_; n++) |  | ||||||
|         { |  | ||||||
|             if (!IQ_swap_) |  | ||||||
|             { |  | ||||||
|                 top_block->connect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 0); |  | ||||||
|                 top_block->connect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 1); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 top_block->connect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); |  | ||||||
|                 top_block->connect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); |  | ||||||
|             } |  | ||||||
|             DLOG(INFO) << "connected char_to_float to float_to_complex_ CH" << n; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     //connect null sinks to unused streams |     //connect null sinks to unused streams | ||||||
|     if (channels_in_udp_>RF_channels_) |  | ||||||
|     { |  | ||||||
|     for (int n = 0; n < channels_in_udp_; n++) |     for (int n = 0; n < channels_in_udp_; n++) | ||||||
|         { |         { | ||||||
|             top_block->connect(float_to_complex_.at(n),0,null_sinks_.at(n),0); |             top_block->connect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); | ||||||
|         } |  | ||||||
|         } |         } | ||||||
|  |     DLOG(INFO) << "connected udp_source to null_sinks to enable the use of spare channels" << std::endl; | ||||||
|  |  | ||||||
|     if (dump_) |     if (dump_) | ||||||
|         { |         { | ||||||
|             for (int n = 0; n < channels_in_udp_; n++) |             for (int n = 0; n < channels_in_udp_; n++) | ||||||
|                 { |                 { | ||||||
|                 top_block->connect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); |                     top_block->connect(udp_gnss_rx_source_, n, file_sink_.at(n), 0); | ||||||
|                     DLOG(INFO) << "connected source to file sink"; |                     DLOG(INFO) << "connected source to file sink"; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| @@ -171,47 +134,20 @@ void UDPSignalSource::connect(gr::top_block_sptr top_block) | |||||||
|  |  | ||||||
| void UDPSignalSource::disconnect(gr::top_block_sptr top_block) | void UDPSignalSource::disconnect(gr::top_block_sptr top_block) | ||||||
| { | { | ||||||
|  |  | ||||||
|     for (int n = 0; n < (channels_in_udp_ * 2); n++) |  | ||||||
|         { |  | ||||||
|             top_block->disconnect(demux_, n, char_to_float_.at(n), 0); |  | ||||||
|             DLOG(INFO) << "disconnect demux to char_to_float CH" << n; |  | ||||||
|         } |  | ||||||
|     for (int n = 0; n < channels_in_udp_; n++) |  | ||||||
|         { |  | ||||||
|             if (!IQ_swap_) |  | ||||||
|             { |  | ||||||
|                 top_block->disconnect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 0); |  | ||||||
|                 top_block->disconnect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 1); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 top_block->disconnect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); |  | ||||||
|                 top_block->disconnect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); |  | ||||||
|             } |  | ||||||
|             DLOG(INFO) << "disconnect char_to_float to float_to_complex_ CH" << n; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     //disconnect null sinks to unused streams |     //disconnect null sinks to unused streams | ||||||
|     if (channels_in_udp_>RF_channels_) |  | ||||||
|     { |  | ||||||
|     for (int n = 0; n < channels_in_udp_; n++) |     for (int n = 0; n < channels_in_udp_; n++) | ||||||
|         { |         { | ||||||
|             top_block->disconnect(float_to_complex_.at(n),0,null_sinks_.at(n),0); |             top_block->disconnect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); | ||||||
|         } |         } | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     if (dump_) |     if (dump_) | ||||||
|         { |         { | ||||||
|             for (int n = 0; n < channels_in_udp_; n++) |             for (int n = 0; n < channels_in_udp_; n++) | ||||||
|                 { |                 { | ||||||
|             top_block->disconnect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); |                     top_block->disconnect(udp_gnss_rx_source_, n, file_sink_.at(n), 0); | ||||||
|                     DLOG(INFO) << "disconnected source to file sink"; |                     DLOG(INFO) << "disconnected source to file sink"; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|     top_block->disconnect(udp_gnss_rx_source_,0, demux_,0); |     DLOG(INFO) << "disconnected udp_source" << std::endl; | ||||||
|     DLOG(INFO)<<"disconnected udp_source to demux"<<std::endl; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -224,11 +160,10 @@ gr::basic_block_sptr UDPSignalSource::get_left_block() | |||||||
|  |  | ||||||
| gr::basic_block_sptr UDPSignalSource::get_right_block() | gr::basic_block_sptr UDPSignalSource::get_right_block() | ||||||
| { | { | ||||||
|     return get_right_block(select_single_channel_); |     return udp_gnss_rx_source_; | ||||||
| } | } | ||||||
|  |  | ||||||
| gr::basic_block_sptr UDPSignalSource::get_right_block(int RF_channel) | gr::basic_block_sptr UDPSignalSource::get_right_block(int RF_channel) | ||||||
| { | { | ||||||
|     return float_to_complex_.at(RF_channel); |     return udp_gnss_rx_source_; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| /*! | /*! | ||||||
|  * \file rtl_tcp_signal_source.h |  * \file udp_signal_source.h | ||||||
|  * \brief Signal source which reads from rtl_tcp. |  | ||||||
|  * (see http://sdr.osmocom.org/trac/wiki/rtl-sdr for more information) |  | ||||||
|  * \author Anthony Arnold, 2015. anthony.arnold(at)uqconnect.edu.au |  | ||||||
|  * |  * | ||||||
|  |  * \brief Receives ip frames containing samples in UDP frame encapsulation | ||||||
|  |  * using a high performance packet capture library (libpcap) | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) |  * Copyright (C) 2010-2018  (see AUTHORS file for a list of contributors) | ||||||
|  * |  * | ||||||
|  * GNSS-SDR is a software defined Global Navigation |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  *          Satellite Systems receiver |  *          Satellite Systems receiver | ||||||
| @@ -29,18 +29,16 @@ | |||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifndef GNSS_SDR_UDP_SIGNAL_SOURCE_H | #ifndef GNSS_SDR_UDP_SIGNAL_SOURCE_H | ||||||
| #define GNSS_SDR_UDP_SIGNAL_SOURCE_H | #define GNSS_SDR_UDP_SIGNAL_SOURCE_H | ||||||
|  |  | ||||||
| #include "gnss_block_interface.h" | #include "gnss_block_interface.h" | ||||||
| #include "raw_ip_packet_source.h" | #include "gr_complex_ip_packet_source.h" | ||||||
| #include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | ||||||
| #include <gnuradio/msg_queue.h> | #include <gnuradio/msg_queue.h> | ||||||
| #include <gnuradio/blocks/char_to_float.h> |  | ||||||
| #include <gnuradio/blocks/file_sink.h> | #include <gnuradio/blocks/file_sink.h> | ||||||
| #include <gnuradio/blocks/null_sink.h> | #include <gnuradio/blocks/null_sink.h> | ||||||
| #include <gnuradio/blocks/deinterleave.h> |  | ||||||
| #include <gnuradio/blocks/float_to_complex.h> |  | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
| @@ -90,7 +88,6 @@ private: | |||||||
|  |  | ||||||
|     bool IQ_swap_; |     bool IQ_swap_; | ||||||
|     int RF_channels_; |     int RF_channels_; | ||||||
|     int select_single_channel_; |  | ||||||
|     int channels_in_udp_; |     int channels_in_udp_; | ||||||
|     unsigned int in_stream_; |     unsigned int in_stream_; | ||||||
|     unsigned int out_stream_; |     unsigned int out_stream_; | ||||||
| @@ -99,12 +96,8 @@ private: | |||||||
|     size_t item_size_; |     size_t item_size_; | ||||||
|     bool dump_; |     bool dump_; | ||||||
|     std::string dump_filename_; |     std::string dump_filename_; | ||||||
|     std::vector<boost::shared_ptr<gr::block>> char_to_float_; |  | ||||||
|     std::vector<boost::shared_ptr<gr::block>> float_to_complex_; |  | ||||||
|     std::vector<boost::shared_ptr<gr::block>> null_sinks_; |     std::vector<boost::shared_ptr<gr::block>> null_sinks_; | ||||||
|  |     gr_complex_ip_packet_source::sptr udp_gnss_rx_source_; | ||||||
|     raw_ip_packet_source::sptr udp_gnss_rx_source_; |  | ||||||
|     gr::blocks::deinterleave::sptr demux_; |  | ||||||
|     std::vector<boost::shared_ptr<gr::block>> file_sink_; |     std::vector<boost::shared_ptr<gr::block>> file_sink_; | ||||||
|     boost::shared_ptr<gr::msg_queue> queue_; |     boost::shared_ptr<gr::msg_queue> queue_; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -20,12 +20,14 @@ | |||||||
| set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES | set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES | ||||||
|      unpack_byte_2bit_samples.cc |      unpack_byte_2bit_samples.cc | ||||||
|      unpack_byte_2bit_cpx_samples.cc |      unpack_byte_2bit_cpx_samples.cc | ||||||
|  |      unpack_byte_4bit_samples.cc | ||||||
|      unpack_intspir_1bit_samples.cc |      unpack_intspir_1bit_samples.cc | ||||||
|      rtl_tcp_signal_source_c.cc |      rtl_tcp_signal_source_c.cc | ||||||
|      unpack_2bit_samples.cc |      unpack_2bit_samples.cc | ||||||
|      unpack_spir_gss6450_samples.cc |      unpack_spir_gss6450_samples.cc | ||||||
|      labsat23_source.cc |      labsat23_source.cc | ||||||
|      raw_ip_packet_source.cc |      raw_ip_packet_source.cc | ||||||
|  |      gr_complex_ip_packet_source.cc | ||||||
| ) | ) | ||||||
|  |  | ||||||
| include_directories( | include_directories( | ||||||
|   | |||||||
| @@ -0,0 +1,439 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gr_complex_ip_packet_source.cc | ||||||
|  |  * | ||||||
|  |  * \brief Receives ip frames containing samples in UDP frame encapsulation | ||||||
|  |  * using a high performance packet capture library (libpcap) | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2018  (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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include <gnuradio/io_signature.h> | ||||||
|  | #include "gr_complex_ip_packet_source.h" | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define FIFO_SIZE 1472000 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* 4 bytes IP address */ | ||||||
|  | typedef struct gr_ip_address | ||||||
|  | { | ||||||
|  |     u_char byte1; | ||||||
|  |     u_char byte2; | ||||||
|  |     u_char byte3; | ||||||
|  |     u_char byte4; | ||||||
|  | } gr_ip_address; | ||||||
|  |  | ||||||
|  | /* IPv4 header */ | ||||||
|  | typedef struct gr_ip_header | ||||||
|  | { | ||||||
|  |     u_char ver_ihl;          // Version (4 bits) + Internet header length (4 bits) | ||||||
|  |     u_char tos;              // Type of service | ||||||
|  |     u_short tlen;            // Total length | ||||||
|  |     u_short identification;  // Identification | ||||||
|  |     u_short flags_fo;        // Flags (3 bits) + Fragment offset (13 bits) | ||||||
|  |     u_char ttl;              // Time to live | ||||||
|  |     u_char proto;            // Protocol | ||||||
|  |     u_short crc;             // Header checksum | ||||||
|  |     gr_ip_address saddr;     // Source address | ||||||
|  |     gr_ip_address daddr;     // Destination address | ||||||
|  |     u_int op_pad;            // Option + Padding | ||||||
|  | } gr_ip_header; | ||||||
|  |  | ||||||
|  | /* UDP header*/ | ||||||
|  | typedef struct gr_udp_header | ||||||
|  | { | ||||||
|  |     u_short sport;  // Source port | ||||||
|  |     u_short dport;  // Destination port | ||||||
|  |     u_short len;    // Datagram length | ||||||
|  |     u_short crc;    // Checksum | ||||||
|  | } gr_udp_header; | ||||||
|  |  | ||||||
|  | gr_complex_ip_packet_source::sptr | ||||||
|  | gr_complex_ip_packet_source::make(std::string src_device, | ||||||
|  |     std::string origin_address, | ||||||
|  |     int udp_port, | ||||||
|  |     int udp_packet_size, | ||||||
|  |     int n_baseband_channels, | ||||||
|  |     std::string wire_sample_type, | ||||||
|  |     size_t item_size, | ||||||
|  |     bool IQ_swap_) | ||||||
|  | { | ||||||
|  |     return gnuradio::get_initial_sptr(new gr_complex_ip_packet_source(src_device, | ||||||
|  |         origin_address, | ||||||
|  |         udp_port, | ||||||
|  |         udp_packet_size, | ||||||
|  |         n_baseband_channels, | ||||||
|  |         wire_sample_type, | ||||||
|  |         item_size, | ||||||
|  |         IQ_swap_)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * The private constructor | ||||||
|  |  */ | ||||||
|  | gr_complex_ip_packet_source::gr_complex_ip_packet_source(std::string src_device, | ||||||
|  |     __attribute__((unused)) std::string origin_address, | ||||||
|  |     int udp_port, | ||||||
|  |     int udp_packet_size, | ||||||
|  |     int n_baseband_channels, | ||||||
|  |     std::string wire_sample_type, | ||||||
|  |     size_t item_size, | ||||||
|  |     bool IQ_swap_) | ||||||
|  |     : gr::sync_block("gr_complex_ip_packet_source", | ||||||
|  |           gr::io_signature::make(0, 0, 0), | ||||||
|  |           gr::io_signature::make(1, 4, item_size))  //1 to 4 baseband complex channels | ||||||
|  | { | ||||||
|  |     // constructor code here | ||||||
|  |     std::cout << "Start Ethernet packet capture\n"; | ||||||
|  |  | ||||||
|  |     d_n_baseband_channels = n_baseband_channels; | ||||||
|  |     if (wire_sample_type.compare("cbyte") == 0) | ||||||
|  |         { | ||||||
|  |             d_wire_sample_type = 1; | ||||||
|  |             d_bytes_per_sample = d_n_baseband_channels * 2; | ||||||
|  |         } | ||||||
|  |     else if (wire_sample_type.compare("c4bits") == 0) | ||||||
|  |         { | ||||||
|  |             d_wire_sample_type = 2; | ||||||
|  |             d_bytes_per_sample = d_n_baseband_channels; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             std::cout << "Unknown wire sample type\n"; | ||||||
|  |             exit(0); | ||||||
|  |         } | ||||||
|  |     std::cout << "d_wire_sample_type:" << d_wire_sample_type << std::endl; | ||||||
|  |     d_src_device = src_device; | ||||||
|  |     d_udp_port = udp_port; | ||||||
|  |     d_udp_payload_size = udp_packet_size; | ||||||
|  |     d_fifo_full = false; | ||||||
|  |  | ||||||
|  |     //allocate signal samples buffer | ||||||
|  |     fifo_buff = new char[FIFO_SIZE]; | ||||||
|  |     fifo_read_ptr = 0; | ||||||
|  |     fifo_write_ptr = 0; | ||||||
|  |     fifo_items = 0; | ||||||
|  |     d_item_size = item_size; | ||||||
|  |     d_IQ_swap = IQ_swap_; | ||||||
|  |     d_sock_raw = 0; | ||||||
|  |     d_pcap_thread = NULL; | ||||||
|  |     descr = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //Called by gnuradio to enable drivers, etc for i/o devices. | ||||||
|  | bool gr_complex_ip_packet_source::start() | ||||||
|  | { | ||||||
|  |     std::cout << "gr_complex_ip_packet_source START\n"; | ||||||
|  |     //open the ethernet device | ||||||
|  |     if (open() == true) | ||||||
|  |         { | ||||||
|  |             // start pcap capture thread | ||||||
|  |             d_pcap_thread = new boost::thread(boost::bind(&gr_complex_ip_packet_source::my_pcap_loop_thread, this, descr)); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //Called by gnuradio to disable drivers, etc for i/o devices. | ||||||
|  | bool gr_complex_ip_packet_source::stop() | ||||||
|  | { | ||||||
|  |     std::cout << "gr_complex_ip_packet_source STOP\n"; | ||||||
|  |     if (descr != NULL) | ||||||
|  |         { | ||||||
|  |             pcap_breakloop(descr); | ||||||
|  |             d_pcap_thread->join(); | ||||||
|  |             pcap_close(descr); | ||||||
|  |         } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool gr_complex_ip_packet_source::open() | ||||||
|  | { | ||||||
|  |     char errbuf[PCAP_ERRBUF_SIZE]; | ||||||
|  |     boost::mutex::scoped_lock lock(d_mutex);  // hold mutex for duration of this function | ||||||
|  |     /* open device for reading */ | ||||||
|  |     descr = pcap_open_live(d_src_device.c_str(), 1500, 1, 1000, errbuf); | ||||||
|  |     if (descr == NULL) | ||||||
|  |         { | ||||||
|  |             std::cout << "Error openning Ethernet device " << d_src_device << std::endl; | ||||||
|  |             printf("Fatal Error in pcap_open_live(): %s\n", errbuf); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     //bind UDP port to avoid automatic reply with ICMP port ureacheable packets from kernel | ||||||
|  |     d_sock_raw = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||||||
|  |     if (d_sock_raw == -1) | ||||||
|  |         { | ||||||
|  |             std::cout << "Error openning UDP socket" << std::endl; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // zero out the structure | ||||||
|  |     memset((char *)&si_me, 0, sizeof(si_me)); | ||||||
|  |  | ||||||
|  |     si_me.sin_family = AF_INET; | ||||||
|  |     si_me.sin_port = htons(d_udp_port); | ||||||
|  |     si_me.sin_addr.s_addr = htonl(INADDR_ANY); | ||||||
|  |  | ||||||
|  |     //bind socket to port | ||||||
|  |     if (bind(d_sock_raw, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) | ||||||
|  |         { | ||||||
|  |             std::cout << "Error openning UDP socket" << std::endl; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | gr_complex_ip_packet_source::~gr_complex_ip_packet_source() | ||||||
|  | { | ||||||
|  |     if (d_pcap_thread != NULL) | ||||||
|  |         { | ||||||
|  |             delete d_pcap_thread; | ||||||
|  |         } | ||||||
|  |     delete fifo_buff; | ||||||
|  |     std::cout << "Stop Ethernet packet capture\n"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gr_complex_ip_packet_source::static_pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, | ||||||
|  |     const u_char *packet) | ||||||
|  | { | ||||||
|  |     gr_complex_ip_packet_source *bridge = (gr_complex_ip_packet_source *)args; | ||||||
|  |     bridge->pcap_callback(args, pkthdr, packet); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gr_complex_ip_packet_source::pcap_callback(__attribute__((unused)) u_char *args, __attribute__((unused)) const struct pcap_pkthdr *pkthdr, | ||||||
|  |     const u_char *packet) | ||||||
|  | { | ||||||
|  |     boost::mutex::scoped_lock lock(d_mutex);  // hold mutex for duration of this function | ||||||
|  |  | ||||||
|  |     gr_ip_header *ih; | ||||||
|  |     gr_udp_header *uh; | ||||||
|  |  | ||||||
|  |     // eth frame parameters | ||||||
|  |     // **** UDP RAW PACKET DECODER **** | ||||||
|  |     if ((packet[12] == 0x08) & (packet[13] == 0x00))  //IP FRAME | ||||||
|  |         { | ||||||
|  |             /* retireve the position of the ip header */ | ||||||
|  |             ih = (gr_ip_header *)(packet + | ||||||
|  |                                   14);  //length of ethernet header | ||||||
|  |  | ||||||
|  |             /* retireve the position of the udp header */ | ||||||
|  |             u_int ip_len; | ||||||
|  |             ip_len = (ih->ver_ihl & 0xf) * 4; | ||||||
|  |             uh = (gr_udp_header *)((u_char *)ih + ip_len); | ||||||
|  |  | ||||||
|  |             /* convert from network byte order to host byte order */ | ||||||
|  |             //u_short sport; | ||||||
|  |             u_short dport; | ||||||
|  |             dport = ntohs(uh->dport); | ||||||
|  |             //sport = ntohs(uh->sport); | ||||||
|  |             if (dport == d_udp_port) | ||||||
|  |                 { | ||||||
|  |                     // print ip addresses and udp ports | ||||||
|  |                     //            printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", | ||||||
|  |                     //                   ih->saddr.byte1, | ||||||
|  |                     //                   ih->saddr.byte2, | ||||||
|  |                     //                   ih->saddr.byte3, | ||||||
|  |                     //                   ih->saddr.byte4, | ||||||
|  |                     //                   sport, | ||||||
|  |                     //                   ih->daddr.byte1, | ||||||
|  |                     //                   ih->daddr.byte2, | ||||||
|  |                     //                   ih->daddr.byte3, | ||||||
|  |                     //                   ih->daddr.byte4, | ||||||
|  |                     //                   dport); | ||||||
|  |                     //            std::cout<<"uh->len:"<<ntohs(uh->len)<<std::endl; | ||||||
|  |  | ||||||
|  |                     int payload_lenght_bytes = ntohs(uh->len) - 8;  //total udp packet lenght minus the header lenght | ||||||
|  |                     //read the payload bytes and insert them into the shared circular buffer | ||||||
|  |                     u_char *udp_payload = ((u_char *)uh + sizeof(gr_udp_header)); | ||||||
|  |                     if (fifo_items <= (FIFO_SIZE - payload_lenght_bytes)) | ||||||
|  |                         { | ||||||
|  |                             int aligned_write_items = FIFO_SIZE - fifo_write_ptr; | ||||||
|  |                             if (aligned_write_items >= payload_lenght_bytes) | ||||||
|  |                                 { | ||||||
|  |                                     //write all in a single memcpy | ||||||
|  |                                     memcpy(&fifo_buff[fifo_write_ptr], &udp_payload[0], payload_lenght_bytes);  //size in bytes | ||||||
|  |                                     fifo_write_ptr += payload_lenght_bytes; | ||||||
|  |                                     if (fifo_write_ptr == FIFO_SIZE) fifo_write_ptr = 0; | ||||||
|  |                                     fifo_items += payload_lenght_bytes; | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     //two step wrap write | ||||||
|  |                                     memcpy(&fifo_buff[fifo_write_ptr], &udp_payload[0], aligned_write_items);  //size in bytes | ||||||
|  |                                     fifo_write_ptr = payload_lenght_bytes - aligned_write_items; | ||||||
|  |                                     memcpy(&fifo_buff[0], &udp_payload[aligned_write_items], fifo_write_ptr);  //size in bytes | ||||||
|  |                                     fifo_items += payload_lenght_bytes; | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                     else | ||||||
|  |                         { | ||||||
|  |                             //notify overflow | ||||||
|  |                             std::cout << "O" << std::flush; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gr_complex_ip_packet_source::my_pcap_loop_thread(pcap_t *pcap_handle) | ||||||
|  |  | ||||||
|  | { | ||||||
|  |     pcap_loop(pcap_handle, -1, gr_complex_ip_packet_source::static_pcap_callback, (u_char *)this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gr_complex_ip_packet_source::demux_samples(gr_vector_void_star output_items, int num_samples_readed) | ||||||
|  | { | ||||||
|  |     int8_t real; | ||||||
|  |     int8_t imag; | ||||||
|  |     uint8_t tmp_char2; | ||||||
|  |     for (int n = 0; n < num_samples_readed; n++) | ||||||
|  |         { | ||||||
|  |             switch (d_wire_sample_type) | ||||||
|  |                 { | ||||||
|  |                 case 1:  //interleaved byte samples | ||||||
|  |                     for (int i = 0; i < output_items.size(); i++) | ||||||
|  |                         { | ||||||
|  |                             real = fifo_buff[fifo_read_ptr++]; | ||||||
|  |                             imag = fifo_buff[fifo_read_ptr++]; | ||||||
|  |                             if (d_IQ_swap) | ||||||
|  |                                 { | ||||||
|  |                                     ((gr_complex *)output_items[i])[n] = gr_complex(real, imag); | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     ((gr_complex *)output_items[i])[n] = gr_complex(imag, real); | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                     break; | ||||||
|  |                 case 2:  // 4bits samples | ||||||
|  |                     for (int i = 0; i < output_items.size(); i++) | ||||||
|  |                         { | ||||||
|  |                             tmp_char2 = fifo_buff[fifo_read_ptr] & 0x0F; | ||||||
|  |                             if (tmp_char2 >= 8) | ||||||
|  |                                 { | ||||||
|  |                                     real = 2 * (tmp_char2 - 16) + 1; | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     real = 2 * tmp_char2 + 1; | ||||||
|  |                                 } | ||||||
|  |                             tmp_char2 = fifo_buff[fifo_read_ptr++] >> 4; | ||||||
|  |                             tmp_char2 = tmp_char2 & 0x0F; | ||||||
|  |                             if (tmp_char2 >= 8) | ||||||
|  |                                 { | ||||||
|  |                                     imag = 2 * (tmp_char2 - 16) + 1; | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     imag = 2 * tmp_char2 + 1; | ||||||
|  |                                 } | ||||||
|  |                             if (d_IQ_swap) | ||||||
|  |                                 { | ||||||
|  |                                     ((gr_complex *)output_items[i])[n] = gr_complex(imag, real); | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     ((gr_complex *)output_items[i])[n] = gr_complex(real, imag); | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     std::cout << "Unknown wire sample type\n"; | ||||||
|  |                     exit(0); | ||||||
|  |                 } | ||||||
|  |             if (fifo_read_ptr == FIFO_SIZE) fifo_read_ptr = 0; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int gr_complex_ip_packet_source::work(int noutput_items, | ||||||
|  |     __attribute__((unused)) gr_vector_const_void_star &input_items, | ||||||
|  |     gr_vector_void_star &output_items) | ||||||
|  | { | ||||||
|  |     // send samples to next GNU Radio block | ||||||
|  |     boost::mutex::scoped_lock lock(d_mutex);  // hold mutex for duration of this function | ||||||
|  |     if (fifo_items == 0) return 0; | ||||||
|  |  | ||||||
|  |     if (output_items.size() > d_n_baseband_channels) | ||||||
|  |         { | ||||||
|  |             std::cout << "Configuration error: more baseband channels connected than the available in the UDP source\n"; | ||||||
|  |             exit(0); | ||||||
|  |         } | ||||||
|  |     int num_samples_readed; | ||||||
|  |     int bytes_requested; | ||||||
|  |     switch (d_wire_sample_type) | ||||||
|  |         { | ||||||
|  |         case 1:  //complex byte samples | ||||||
|  |             bytes_requested = noutput_items * d_bytes_per_sample; | ||||||
|  |             if (bytes_requested < fifo_items) | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = noutput_items;  //read all | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = fifo_items / d_bytes_per_sample;  //read what we have | ||||||
|  |                 } | ||||||
|  |             break; | ||||||
|  |         case 2:  //complex 4 bits samples | ||||||
|  |             bytes_requested = noutput_items * d_bytes_per_sample; | ||||||
|  |             if (bytes_requested < fifo_items) | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = noutput_items;  //read all | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = fifo_items / d_bytes_per_sample;  //read what we have | ||||||
|  |                 } | ||||||
|  |             break; | ||||||
|  |         default:  //complex byte samples | ||||||
|  |             bytes_requested = noutput_items * d_bytes_per_sample; | ||||||
|  |             if (bytes_requested < fifo_items) | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = noutput_items;  //read all | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     num_samples_readed = fifo_items / d_bytes_per_sample;  //read what we have | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     bytes_requested = num_samples_readed * d_bytes_per_sample; | ||||||
|  |     //read all in a single loop | ||||||
|  |     demux_samples(output_items, num_samples_readed);  // it also increases the fifo read pointer | ||||||
|  |     //update fifo items | ||||||
|  |     fifo_items = fifo_items - bytes_requested; | ||||||
|  |  | ||||||
|  |     for (int n = 0; n < output_items.size(); n++) | ||||||
|  |         { | ||||||
|  |             produce(n, num_samples_readed); | ||||||
|  |         } | ||||||
|  |     return this->WORK_CALLED_PRODUCE; | ||||||
|  | } | ||||||
| @@ -0,0 +1,117 @@ | |||||||
|  | /*! | ||||||
|  |  * \file gr_complex_ip_packet_source.h | ||||||
|  |  * | ||||||
|  |  * \brief Receives ip frames containing samples in UDP frame encapsulation | ||||||
|  |  * using a high performance packet capture library (libpcap) | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2018  (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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H | ||||||
|  | #define INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H | ||||||
|  |  | ||||||
|  | #include <gnuradio/sync_block.h> | ||||||
|  | #include <boost/thread.hpp> | ||||||
|  | #include <pcap.h> | ||||||
|  | #include <arpa/inet.h> | ||||||
|  | #include <net/if.h> | ||||||
|  | #include <net/ethernet.h> | ||||||
|  | #include <netinet/if_ether.h> | ||||||
|  | #include <sys/ioctl.h> | ||||||
|  |  | ||||||
|  | class gr_complex_ip_packet_source : virtual public gr::sync_block | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     boost::mutex d_mutex; | ||||||
|  |     pcap_t *descr;  //ethernet pcap device descriptor | ||||||
|  |  | ||||||
|  |     char *fifo_buff; | ||||||
|  |  | ||||||
|  |     int fifo_read_ptr; | ||||||
|  |     int fifo_write_ptr; | ||||||
|  |     int fifo_items; | ||||||
|  |     int d_sock_raw; | ||||||
|  |     int d_udp_port; | ||||||
|  |     struct sockaddr_in si_me; | ||||||
|  |     std::string d_src_device; | ||||||
|  |     std::string d_origin_address; | ||||||
|  |     int d_udp_payload_size; | ||||||
|  |     bool d_fifo_full; | ||||||
|  |  | ||||||
|  |     int d_n_baseband_channels; | ||||||
|  |     int d_wire_sample_type; | ||||||
|  |     int d_bytes_per_sample; | ||||||
|  |     size_t d_item_size; | ||||||
|  |     bool d_IQ_swap; | ||||||
|  |  | ||||||
|  |     boost::thread *d_pcap_thread; | ||||||
|  |     /*! | ||||||
|  | 	 * \brief | ||||||
|  | 	 * Opens the ethernet device using libpcap raw capture mode | ||||||
|  | 	 * If any of these fail, the fuction retuns the error and exits. | ||||||
|  | 	 */ | ||||||
|  |     bool open(); | ||||||
|  |  | ||||||
|  |     void demux_samples(gr_vector_void_star output_items, int num_samples_readed); | ||||||
|  |     void my_pcap_loop_thread(pcap_t *pcap_handle); | ||||||
|  |  | ||||||
|  |     void pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); | ||||||
|  |  | ||||||
|  |     static void static_pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     typedef boost::shared_ptr<gr_complex_ip_packet_source> sptr; | ||||||
|  |     static sptr make(std::string src_device, | ||||||
|  |         std::string origin_address, | ||||||
|  |         int udp_port, | ||||||
|  |         int udp_packet_size, | ||||||
|  |         int n_baseband_channels, | ||||||
|  |         std::string wire_sample_type, | ||||||
|  |         size_t item_size, | ||||||
|  |         bool IQ_swap_); | ||||||
|  |     gr_complex_ip_packet_source(std::string src_device, | ||||||
|  |         std::string origin_address, | ||||||
|  |         int udp_port, | ||||||
|  |         int udp_packet_size, | ||||||
|  |         int n_baseband_channels, | ||||||
|  |         std::string wire_sample_type, | ||||||
|  |         size_t item_size, | ||||||
|  |         bool IQ_swap_); | ||||||
|  |     ~gr_complex_ip_packet_source(); | ||||||
|  |  | ||||||
|  |     // Where all the action really happens | ||||||
|  |     int work(int noutput_items, | ||||||
|  |         gr_vector_const_void_star &input_items, | ||||||
|  |         gr_vector_void_star &output_items); | ||||||
|  |  | ||||||
|  |     //Called by gnuradio to enable drivers, etc for i/o devices. | ||||||
|  |     bool start(); | ||||||
|  |     //Called by gnuradio to disable drivers, etc for i/o devices. | ||||||
|  |     bool stop(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif /* INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H */ | ||||||
| @@ -0,0 +1,86 @@ | |||||||
|  | /*! | ||||||
|  |  * \file unpack_byte_4bit_samples.cc | ||||||
|  |  * | ||||||
|  |  * \brief Unpacks byte samples to 4 bits samples. | ||||||
|  |  *     Packing Order | ||||||
|  |  *     Packing order in Nibble I0 I1 I2 I3 I0 I1 I2 I3 | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "unpack_byte_4bit_samples.h" | ||||||
|  | #include <gnuradio/io_signature.h> | ||||||
|  |  | ||||||
|  | unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples() | ||||||
|  | { | ||||||
|  |     return unpack_byte_4bit_samples_sptr(new unpack_byte_4bit_samples()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | unpack_byte_4bit_samples::unpack_byte_4bit_samples() : sync_interpolator("unpack_byte_4bit_samples", | ||||||
|  |                                                            gr::io_signature::make(1, 1, sizeof(signed char)), | ||||||
|  |                                                            gr::io_signature::make(1, 1, sizeof(signed char)), | ||||||
|  |                                                            2) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | unpack_byte_4bit_samples::~unpack_byte_4bit_samples() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int unpack_byte_4bit_samples::work(int noutput_items, | ||||||
|  |     gr_vector_const_void_star &input_items, | ||||||
|  |     gr_vector_void_star &output_items) | ||||||
|  | { | ||||||
|  |     const signed char *in = reinterpret_cast<const signed char *>(input_items[0]); | ||||||
|  |     signed char *out = reinterpret_cast<signed char *>(output_items[0]); | ||||||
|  |     int n = 0; | ||||||
|  |     unsigned char tmp_char2; | ||||||
|  |     for (int i = 0; i < noutput_items / 2; i++) | ||||||
|  |         { | ||||||
|  |             tmp_char2 = in[i] & 0x0F; | ||||||
|  |             if (tmp_char2 >= 8) | ||||||
|  |                 { | ||||||
|  |                     out[n++] = 2 * (tmp_char2 - 16) + 1; | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     out[n++] = 2 * tmp_char2 + 1; | ||||||
|  |                 } | ||||||
|  |             tmp_char2 = in[i] >> 4; | ||||||
|  |             tmp_char2 = tmp_char2 & 0x0F; | ||||||
|  |             if (tmp_char2 >= 8) | ||||||
|  |                 { | ||||||
|  |                     out[n++] = 2 * (tmp_char2 - 16) + 1; | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     out[n++] = 2 * tmp_char2 + 1; | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     return noutput_items; | ||||||
|  | } | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | /*! | ||||||
|  |  * \file unpack_byte_4bit_samples.h | ||||||
|  |  * | ||||||
|  |  * \brief Unpacks byte samples to 4 bits samples. | ||||||
|  |  *     Packing Order | ||||||
|  |  *     Packing order in Nibble I0 I1 I2 I3 I0 I1 I2 I3 | ||||||
|  |  * \author Javier Arribas jarribas (at) cttc.es | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_unpack_byte_4bit_samples_H | ||||||
|  | #define GNSS_SDR_unpack_byte_4bit_samples_H | ||||||
|  |  | ||||||
|  | #include <gnuradio/sync_interpolator.h> | ||||||
|  |  | ||||||
|  | class unpack_byte_4bit_samples; | ||||||
|  |  | ||||||
|  | typedef boost::shared_ptr<unpack_byte_4bit_samples> unpack_byte_4bit_samples_sptr; | ||||||
|  |  | ||||||
|  | unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples(); | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief This class implements conversion between byte packet samples to 4bit_cpx samples | ||||||
|  |  *  1 byte = 1 x complex 4bit I, + 4bit Q samples | ||||||
|  |  */ | ||||||
|  | class unpack_byte_4bit_samples : public gr::sync_interpolator | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     friend unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples_sptr(); | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     unpack_byte_4bit_samples(); | ||||||
|  |     ~unpack_byte_4bit_samples(); | ||||||
|  |     int work(int noutput_items, | ||||||
|  |         gr_vector_const_void_star &input_items, | ||||||
|  |         gr_vector_void_star &output_items); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user
	 Javier Arribas
					Javier Arribas