2014-02-04 16:57:25 +00:00
/* -*- c++ -*- */
2014-12-02 17:07:38 +00:00
/*
* @ file
2017-08-23 14:02:19 +00:00
* @ author ( C ) 2009 - 2017 by Piotr Krysik < ptrkrysik @ gmail . com >
2014-12-02 17:07:38 +00:00
* @ section LICENSE
*
* Gr - gsm is free software ; you can redistribute it and / or modify
2014-02-04 16:57:25 +00:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 , or ( at your option )
* any later version .
2014-12-02 17:07:38 +00:00
*
* Gr - gsm is distributed in the hope that it will be useful ,
2014-02-04 16:57:25 +00:00
* 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 .
2014-12-02 17:07:38 +00:00
*
2014-02-04 16:57:25 +00:00
* You should have received a copy of the GNU General Public License
2014-12-02 17:07:38 +00:00
* along with gr - gsm ; see the file COPYING . If not , write to
2014-02-04 16:57:25 +00:00
* the Free Software Foundation , Inc . , 51 Franklin Street ,
* Boston , MA 02110 - 1301 , USA .
*/
# ifndef INCLUDED_GSM_RECEIVER_IMPL_H
# define INCLUDED_GSM_RECEIVER_IMPL_H
2014-12-13 09:11:00 +00:00
# include <grgsm/receiver/receiver.h>
# include <grgsm/gsmtap.h>
2017-11-07 18:33:22 +00:00
# include <grgsm/gsm_constants.h>
2014-02-04 16:57:25 +00:00
# include <receiver_config.h>
2015-07-08 08:50:41 +00:00
# include <vector>
2017-09-27 19:58:24 +00:00
# include "time_sample_ref.h"
2014-02-04 16:57:25 +00:00
namespace gr {
namespace gsm {
class receiver_impl : public receiver
{
private :
2017-10-16 13:47:08 +00:00
unsigned int d_samples_consumed ;
2017-09-27 19:58:24 +00:00
bool d_rx_time_received ;
time_sample_ref d_time_samp_ref ;
2017-11-11 10:12:02 +00:00
int d_c0_burst_start ;
2014-10-30 08:05:15 +00:00
float d_c0_signal_dbm ;
2016-08-29 05:38:25 +00:00
2014-02-04 16:57:25 +00:00
/**@name Configuration of the receiver */
//@{
const int d_OSR ; ///< oversampling ratio
2015-08-06 08:11:58 +00:00
bool d_process_uplink ;
2014-02-04 16:57:25 +00:00
const int d_chan_imp_length ; ///< channel impulse length
2014-10-30 08:05:15 +00:00
float d_signal_dbm ;
2014-11-06 13:50:59 +00:00
std : : vector < int > d_tseq_nums ; ///< stores training sequence numbers for channels different than C0
2014-11-19 10:27:34 +00:00
std : : vector < int > d_cell_allocation ; ///< stores cell allocation - absolute rf channel numbers (ARFCNs) assigned to the given cell. The variable should at least contain C0 channel number.
2014-02-04 16:57:25 +00:00
//@}
gr_complex d_sch_training_seq [ N_SYNC_BITS ] ; ///<encoded training sequence of a SCH burst
2014-10-30 08:05:15 +00:00
gr_complex d_norm_training_seq [ TRAIN_SEQ_NUM ] [ N_TRAIN_BITS ] ; ///<encoded training sequences of a normal and dummy burst
2014-02-04 16:57:25 +00:00
2015-04-04 12:01:52 +00:00
float d_last_time ;
2014-02-04 16:57:25 +00:00
/** Counts samples consumed by the receiver
*
* It is used in beetween find_fcch_burst and reach_sch_burst calls .
* My intention was to synchronize this counter with some internal sample
* counter of the USRP . Simple access to such USRP ' s counter isn ' t possible
* so this variable isn ' t used in the " synchronized " state of the receiver yet .
*/
unsigned d_counter ;
/**@name Variables used to store result of the find_fcch_burst fuction */
//@{
2017-07-24 12:21:02 +00:00
bool d_freq_offset_tag_in_fcch ; ///< frequency offset tag presence
2014-02-04 16:57:25 +00:00
unsigned d_fcch_start_pos ; ///< position of the first sample of the fcch burst
2014-08-06 12:10:56 +00:00
float d_freq_offset_setting ; ///< frequency offset set in frequency shifter located upstream
2014-02-04 16:57:25 +00:00
//@}
std : : list < double > d_freq_offset_vals ;
/**@name Identifiers of the BTS extracted from the SCH burst */
//@{
int d_ncc ; ///< network color code
int d_bcc ; ///< base station color code
//@}
/**@name Internal state of the gsm receiver */
//@{
enum states {
2014-08-06 13:20:33 +00:00
fcch_search , sch_search , // synchronization search part
2014-02-04 16:57:25 +00:00
synchronized // receiver is synchronized in this state
} d_state ;
//@}
/**@name Variables which make internal state in the "synchronized" state */
//@{
burst_counter d_burst_nr ; ///< frame number and timeslot number
channel_configuration d_channel_conf ; ///< mapping of burst_counter to burst_type
//@}
2014-11-06 13:50:59 +00:00
2014-02-04 16:57:25 +00:00
unsigned d_failed_sch ; ///< number of subsequent erroneous SCH bursts
/** Function whis is used to search a FCCH burst and to compute frequency offset before
* " synchronized " state of the receiver
*
* @ param input vector with input signal
* @ param nitems number of samples in the input vector
* @ return
*/
2014-08-06 12:10:56 +00:00
bool find_fcch_burst ( const gr_complex * input , const int nitems , double & computed_freq_offset ) ;
2014-02-04 16:57:25 +00:00
/** Computes frequency offset from FCCH burst samples
*
2014-08-06 12:10:56 +00:00
* @ param [ in ] input vector with input samples
* @ param [ in ] first_sample number of the first sample of the FCCH busrt
* @ param [ in ] last_sample number of the last sample of the FCCH busrt
* @ param [ out ] computed_freq_offset contains frequency offset estimate if FCCH burst was located
* @ return true if frequency offset was faound
2014-02-04 16:57:25 +00:00
*/
double compute_freq_offset ( const gr_complex * input , unsigned first_sample , unsigned last_sample ) ;
/** Computes angle between two complex numbers
*
* @ param val1 first complex number
* @ param val2 second complex number
* @ return
*/
inline float compute_phase_diff ( gr_complex val1 , gr_complex val2 ) ;
/** Function whis is used to get near to SCH burst
*
* @ param nitems number of samples in the gsm_receiver ' s buffer
* @ return true if SCH burst is near , false otherwise
*/
bool reach_sch_burst ( const int nitems ) ;
/** Extracts channel impulse response from a SCH burst and computes first sample number of this burst
*
* @ param input vector with input samples
* @ param chan_imp_resp complex vector where channel impulse response will be stored
* @ return number of first sample of the burst
*/
int get_sch_chan_imp_resp ( const gr_complex * input , gr_complex * chan_imp_resp ) ;
/** MLSE detection of a burst bits
*
* Detects bits of burst using viterbi algorithm .
* @ param input vector with input samples
* @ param chan_imp_resp vector with the channel impulse response
* @ param burst_start number of the first sample of the burst
* @ param output_binary vector with output bits
*/
void detect_burst ( const gr_complex * input , gr_complex * chan_imp_resp , int burst_start , unsigned char * output_binary ) ;
/** Encodes differentially input bits and maps them into MSK states
*
* @ param input vector with input bits
* @ param nitems number of samples in the " input " vector
* @ param gmsk_output bits mapped into MSK states
* @ param start_point first state
*/
void gmsk_mapper ( const unsigned char * input , int nitems , gr_complex * gmsk_output , gr_complex start_point ) ;
/** Correlates MSK mapped sequence with input signal
*
* @ param sequence MKS mapped sequence
* @ param length length of the sequence
* @ param input_signal vector with input samples
* @ return correlation value
*/
gr_complex correlate_sequence ( const gr_complex * sequence , int length , const gr_complex * input ) ;
/** Computes autocorrelation of input vector for positive arguments
*
* @ param input vector with input samples
* @ param out output vector
* @ param nitems length of the input vector
*/
inline void autocorrelation ( const gr_complex * input , gr_complex * out , int nitems ) ;
/** Filters input signal through channel impulse response
*
* @ param input vector with input samples
* @ param nitems number of samples to pass through filter
* @ param filter filter taps - channel impulse response
* @ param filter_length nember of filter taps
* @ param output vector with filtered samples
*/
inline void mafi ( const gr_complex * input , int nitems , gr_complex * filter , int filter_length , gr_complex * output ) ;
/** Extracts channel impulse response from a normal burst and computes first sample number of this burst
*
* @ param input vector with input samples
* @ param chan_imp_resp complex vector where channel impulse response will be stored
* @ param search_range possible absolute offset of a channel impulse response start
* @ param bcc base station color code - number of a training sequence
* @ return first sample number of normal burst
*/
2014-02-05 21:44:30 +00:00
int get_norm_chan_imp_resp ( const gr_complex * input , gr_complex * chan_imp_resp , float * corr_max , int bcc ) ;
2014-02-04 16:57:25 +00:00
/**
2014-11-06 13:50:59 +00:00
* Sends burst through a C0 ( for burst from C0 channel ) or Cx ( for other bursts ) message port
2014-02-04 16:57:25 +00:00
*
2014-11-06 13:50:59 +00:00
* @ param burst_nr - frame number of the burst
* @ param burst_binary - content of the burst
* @ b_type - type of the burst
2014-02-04 16:57:25 +00:00
*/
2018-04-16 20:21:29 +00:00
void send_burst ( burst_counter burst_nr , const unsigned char * burst_binary , uint8_t burst_type , size_t input_nr , unsigned int burst_start = - 1 ) ;
2014-02-04 16:57:25 +00:00
/**
2014-11-06 13:50:59 +00:00
* Configures burst types in different channels
2014-02-04 16:57:25 +00:00
*/
void configure_receiver ( ) ;
2014-08-04 09:28:59 +00:00
2017-07-24 12:21:02 +00:00
/* State machine handlers */
void fcch_search_handler ( gr_complex * input , int noutput_items ) ;
void sch_search_handler ( gr_complex * input , int noutput_items ) ;
void synchronized_handler ( gr_complex * input ,
gr_vector_const_void_star & input_items , int noutput_items ) ;
2014-02-04 16:57:25 +00:00
public :
2018-04-16 20:21:29 +00:00
receiver_impl ( int osr , const std : : vector < int > & cell_allocation , const std : : vector < int > & tseq_nums , bool process_uplink ) ;
2017-09-27 19:58:24 +00:00
~ receiver_impl ( ) ;
2014-02-04 16:57:25 +00:00
2017-09-27 19:58:24 +00:00
int work ( int noutput_items , gr_vector_const_void_star & input_items , gr_vector_void_star & output_items ) ;
virtual void set_cell_allocation ( const std : : vector < int > & cell_allocation ) ;
virtual void set_tseq_nums ( const std : : vector < int > & tseq_nums ) ;
virtual void reset ( ) ;
2014-02-04 16:57:25 +00:00
} ;
} // namespace gsm
} // namespace gr
# endif /* INCLUDED_GSM_RECEIVER_IMPL_H */