mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
				synced 2025-11-04 06:03:17 +00:00 
			
		
		
		
	wip
Change-Id: Ie8fdf358df07f3944cb223584581514d6c229de7
This commit is contained in:
		@@ -871,7 +871,7 @@ int Transceiver::ctrl_sock_handle_rx(int chan)
 | 
			
		||||
  LOGCHAN(chan, DTRXCTRL, INFO) << "command is '" << command << "'";
 | 
			
		||||
 | 
			
		||||
  if (match_cmd(command, "POWEROFF", NULL)) {
 | 
			
		||||
    stop();
 | 
			
		||||
    // stop();
 | 
			
		||||
    sprintf(response,"RSP POWEROFF 0");
 | 
			
		||||
  } else if (match_cmd(command, "POWERON", NULL)) {
 | 
			
		||||
    if (!start()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,9 @@ class trxmsif {
 | 
			
		||||
			dl.ts.store(write_ts);
 | 
			
		||||
			dl.len_written.store(howmany);
 | 
			
		||||
		}
 | 
			
		||||
		shm::mtx_log::print_guard() << std::endl << "####w+ " << write_ts << " " << howmany << std::endl << std::endl;
 | 
			
		||||
		shm::mtx_log::print_guard() << std::endl
 | 
			
		||||
					    << "####w+ " << write_ts << " " << howmany << std::endl
 | 
			
		||||
					    << std::endl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void signal_read_start()
 | 
			
		||||
@@ -155,13 +157,13 @@ class trxmsif {
 | 
			
		||||
 | 
			
		||||
		// data left from prev read
 | 
			
		||||
		if (left_to_read >= howmany) {
 | 
			
		||||
			memcpy(outbuf, buf, samp2byte(howmany));
 | 
			
		||||
			memcpy(outbuf, &buf[dl_readoffset], samp2byte(howmany));
 | 
			
		||||
			dl_readoffset += howmany;
 | 
			
		||||
 | 
			
		||||
			shm::mtx_log::print_guard() << "\tr++ " << *read_ts << " " << howmany << std::endl;
 | 
			
		||||
			return;
 | 
			
		||||
		} else {
 | 
			
		||||
			memcpy(outbuf, buf, samp2byte(left_to_read));
 | 
			
		||||
			memcpy(outbuf, &buf[dl_readoffset], samp2byte(left_to_read));
 | 
			
		||||
			dl_readoffset = 0;
 | 
			
		||||
			auto still_left_to_read = howmany - left_to_read;
 | 
			
		||||
			{
 | 
			
		||||
@@ -170,11 +172,12 @@ class trxmsif {
 | 
			
		||||
				dl.r.wait_and_reset(1);
 | 
			
		||||
				assert(*read_ts != dl.ts.load());
 | 
			
		||||
				len_avail = dl.len_written.load();
 | 
			
		||||
				dl_readoffset += still_left_to_read;
 | 
			
		||||
				assert(len_avail >= still_left_to_read);
 | 
			
		||||
				memcpy(outbuf + left_to_read, buf, samp2byte(still_left_to_read));
 | 
			
		||||
				shm::mtx_log::print_guard() << "\tr+++2 " << *read_ts << " " << howmany << " "
 | 
			
		||||
						   << still_left_to_read << " new @" << dl.ts.load() << std::endl;
 | 
			
		||||
				memcpy(&outbuf[left_to_read], buf, samp2byte(still_left_to_read));
 | 
			
		||||
				dl_readoffset += still_left_to_read;
 | 
			
		||||
				shm::mtx_log::print_guard()
 | 
			
		||||
					<< "\tr+++2 " << *read_ts << " " << howmany << " " << still_left_to_read
 | 
			
		||||
					<< " new @" << dl.ts.load() << std::endl;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@
 | 
			
		||||
#endif
 | 
			
		||||
#include <complex>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
@@ -43,8 +42,8 @@ gr_complex d_sch_training_seq[N_SYNC_BITS]; ///<encoded training sequence of a S
 | 
			
		||||
gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; ///<encoded training sequences of a normal and dummy burst
 | 
			
		||||
const int d_chan_imp_length = CHAN_IMP_RESP_LENGTH;
 | 
			
		||||
 | 
			
		||||
void initvita() {
 | 
			
		||||
 | 
			
		||||
void initvita()
 | 
			
		||||
{
 | 
			
		||||
	/**
 | 
			
		||||
	 * Prepare SCH sequence bits
 | 
			
		||||
	 *
 | 
			
		||||
@@ -52,8 +51,7 @@ void initvita() {
 | 
			
		||||
	 * Burst and two guard periods
 | 
			
		||||
	 * (one guard period is an arbitrary overlap)
 | 
			
		||||
	 */
 | 
			
		||||
	gmsk_mapper(SYNC_BITS, N_SYNC_BITS,
 | 
			
		||||
		d_sch_training_seq, gr_complex(0.0, -1.0));
 | 
			
		||||
	gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0));
 | 
			
		||||
	for (auto &i : d_sch_training_seq)
 | 
			
		||||
		i = conj(i);
 | 
			
		||||
 | 
			
		||||
@@ -63,21 +61,15 @@ void initvita() {
 | 
			
		||||
		 * If first bit of the sequence is 0
 | 
			
		||||
		 * => first symbol is 1, else -1
 | 
			
		||||
		 */
 | 
			
		||||
		gr_complex startpoint = train_seq[i][0] == 0 ?
 | 
			
		||||
			gr_complex(1.0, 0.0) : gr_complex(-1.0, 0.0);
 | 
			
		||||
		gmsk_mapper(train_seq[i], N_TRAIN_BITS,
 | 
			
		||||
			d_norm_training_seq[i], startpoint);
 | 
			
		||||
		gr_complex startpoint = train_seq[i][0] == 0 ? gr_complex(1.0, 0.0) : gr_complex(-1.0, 0.0);
 | 
			
		||||
		gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
 | 
			
		||||
		for (auto &i : d_norm_training_seq[i])
 | 
			
		||||
			i = conj(i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MULTI_VER_TARGET_ATTR
 | 
			
		||||
void
 | 
			
		||||
detect_burst(const gr_complex* input,
 | 
			
		||||
	gr_complex* chan_imp_resp, int burst_start,
 | 
			
		||||
	unsigned char* output_binary)
 | 
			
		||||
void detect_burst(const gr_complex *input, gr_complex *chan_imp_resp, int burst_start, unsigned char *output_binary)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<gr_complex> rhh_temp(CHAN_IMP_RESP_LENGTH * d_OSR);
 | 
			
		||||
	unsigned int stop_states[2] = { 4, 12 };
 | 
			
		||||
@@ -90,31 +82,27 @@ detect_burst(const gr_complex* input,
 | 
			
		||||
	for (int ii = 0; ii < d_chan_imp_length; ii++)
 | 
			
		||||
		rhh[ii] = conj(rhh_temp[ii * d_OSR]);
 | 
			
		||||
 | 
			
		||||
	mafi(&input[burst_start], BURST_SIZE, chan_imp_resp,
 | 
			
		||||
		d_chan_imp_length * d_OSR, filtered_burst);
 | 
			
		||||
	mafi(&input[burst_start], BURST_SIZE, chan_imp_resp, d_chan_imp_length * d_OSR, filtered_burst);
 | 
			
		||||
 | 
			
		||||
	viterbi_detector(filtered_burst, BURST_SIZE, rhh,
 | 
			
		||||
		start_state, stop_states, 2, output);
 | 
			
		||||
	viterbi_detector(filtered_burst, BURST_SIZE, rhh, start_state, stop_states, 2, output);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < BURST_SIZE; i++)
 | 
			
		||||
		output_binary[i] = output[i] > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int process_vita_burst(gr_complex* input, int tsc, unsigned char* output_binary) {
 | 
			
		||||
int process_vita_burst(gr_complex *input, int tsc, unsigned char *output_binary)
 | 
			
		||||
{
 | 
			
		||||
	gr_complex channel_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR];
 | 
			
		||||
	int normal_burst_start, dummy_burst_start;
 | 
			
		||||
	float dummy_corr_max, normal_corr_max;
 | 
			
		||||
 | 
			
		||||
	dummy_burst_start = get_norm_chan_imp_resp(input,
 | 
			
		||||
		&channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
 | 
			
		||||
	normal_burst_start = get_norm_chan_imp_resp(input,
 | 
			
		||||
		&channel_imp_resp[0], &normal_corr_max, tsc);
 | 
			
		||||
	dummy_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
 | 
			
		||||
	normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, tsc);
 | 
			
		||||
 | 
			
		||||
	if (normal_corr_max > dummy_corr_max) {
 | 
			
		||||
		/* Perform MLSE detection */
 | 
			
		||||
		detect_burst(input, &channel_imp_resp[0],
 | 
			
		||||
			normal_burst_start, output_binary);
 | 
			
		||||
		
 | 
			
		||||
		detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -124,22 +112,20 @@ int process_vita_burst(gr_complex* input, int tsc, unsigned char* output_binary)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int process_vita_sc_burst(gr_complex* input, int tsc, unsigned char* output_binary, int* offset) {
 | 
			
		||||
int process_vita_sc_burst(gr_complex *input, int tsc, unsigned char *output_binary, int *offset)
 | 
			
		||||
{
 | 
			
		||||
	gr_complex channel_imp_resp[CHAN_IMP_RESP_LENGTH * d_OSR];
 | 
			
		||||
 | 
			
		||||
	/* Get channel impulse response */
 | 
			
		||||
	int d_c0_burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]);
 | 
			
		||||
	//	*offset = d_c0_burst_start;
 | 
			
		||||
	/* Perform MLSE detection */
 | 
			
		||||
	detect_burst(input, &channel_imp_resp[0],
 | 
			
		||||
	d_c0_burst_start, output_binary);
 | 
			
		||||
	detect_burst(input, &channel_imp_resp[0], d_c0_burst_start, output_binary);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gmsk_mapper(const unsigned char* input,
 | 
			
		||||
	int nitems, gr_complex* gmsk_output, gr_complex start_point)
 | 
			
		||||
void gmsk_mapper(const unsigned char *input, int nitems, gr_complex *gmsk_output, gr_complex start_point)
 | 
			
		||||
{
 | 
			
		||||
	gr_complex j = gr_complex(0.0, 1.0);
 | 
			
		||||
	gmsk_output[0] = start_point;
 | 
			
		||||
@@ -156,16 +142,13 @@ gmsk_mapper(const unsigned char* input,
 | 
			
		||||
		encoded_symbol = current_symbol * previous_symbol;
 | 
			
		||||
 | 
			
		||||
		/* And do GMSK mapping */
 | 
			
		||||
		gmsk_output[i] = j * gr_complex(encoded_symbol, 0.0)
 | 
			
		||||
			* gmsk_output[i - 1];
 | 
			
		||||
		gmsk_output[i] = j * gr_complex(encoded_symbol, 0.0) * gmsk_output[i - 1];
 | 
			
		||||
 | 
			
		||||
		previous_symbol = current_symbol;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gr_complex
 | 
			
		||||
correlate_sequence(const gr_complex* sequence,
 | 
			
		||||
	int length, const gr_complex* input)
 | 
			
		||||
gr_complex correlate_sequence(const gr_complex *sequence, int length, const gr_complex *input)
 | 
			
		||||
{
 | 
			
		||||
	gr_complex result(0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
@@ -176,9 +159,7 @@ correlate_sequence(const gr_complex* sequence,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Computes autocorrelation for positive arguments */
 | 
			
		||||
inline void
 | 
			
		||||
autocorrelation(const gr_complex* input,
 | 
			
		||||
	gr_complex* out, int nitems)
 | 
			
		||||
inline void autocorrelation(const gr_complex *input, gr_complex *out, int nitems)
 | 
			
		||||
{
 | 
			
		||||
	for (int k = nitems - 1; k >= 0; k--) {
 | 
			
		||||
		out[k] = gr_complex(0, 0);
 | 
			
		||||
@@ -187,9 +168,7 @@ autocorrelation(const gr_complex* input,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void
 | 
			
		||||
mafi(const gr_complex* input, int nitems,
 | 
			
		||||
	gr_complex* filter, int filter_length, gr_complex* output)
 | 
			
		||||
inline void mafi(const gr_complex *input, int nitems, gr_complex *filter, int filter_length, gr_complex *output)
 | 
			
		||||
{
 | 
			
		||||
	for (int n = 0; n < nitems; n++) {
 | 
			
		||||
		int a = n * d_OSR;
 | 
			
		||||
@@ -221,10 +200,12 @@ int get_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, int se
 | 
			
		||||
 | 
			
		||||
	/* Compute window energies */
 | 
			
		||||
	auto window_energy_start_offset = strongest_corr_nr - 6 * d_OSR;
 | 
			
		||||
	window_energy_start_offset = window_energy_start_offset < 0 ? 0 : window_energy_start_offset; //can end up out of range..
 | 
			
		||||
	window_energy_start_offset =
 | 
			
		||||
		window_energy_start_offset < 0 ? 0 : window_energy_start_offset; //can end up out of range..
 | 
			
		||||
	auto window_energy_end_offset = strongest_corr_nr + 6 * d_OSR + d_chan_imp_length * d_OSR;
 | 
			
		||||
	auto iter = power_buffer.begin() + window_energy_start_offset;
 | 
			
		||||
	auto iter_end = power_buffer.begin() + window_energy_end_offset;
 | 
			
		||||
	iter_end = iter_end < power_buffer.end() ? iter_end : power_buffer.end(); //can end up out of range..
 | 
			
		||||
	while (iter != iter_end) {
 | 
			
		||||
		std::vector<float>::iterator iter_ii = iter;
 | 
			
		||||
		bool loop_end = false;
 | 
			
		||||
@@ -321,12 +302,12 @@ int get_sch_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp)
 | 
			
		||||
 | 
			
		||||
int get_sch_buffer_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, unsigned int len, float *corr_max)
 | 
			
		||||
{
 | 
			
		||||
	const auto tseqlen = N_SYNC_BITS - (2 * TRAIN_BEGINNING);
 | 
			
		||||
	const int search_center = SYNC_POS + TRAIN_BEGINNING;
 | 
			
		||||
	const int search_start_pos = 0;
 | 
			
		||||
	// FIXME: proper end offset
 | 
			
		||||
	const int search_stop_pos = len - (N_SYNC_BITS*8);
 | 
			
		||||
	auto tseq = &d_sch_training_seq[TRAIN_BEGINNING];
 | 
			
		||||
	const int search_stop_pos = len - (N_SYNC_BITS * 8);
 | 
			
		||||
	const auto tseq = &d_sch_training_seq[TRAIN_BEGINNING];
 | 
			
		||||
	const auto tseqlen = N_SYNC_BITS - (2 * TRAIN_BEGINNING);
 | 
			
		||||
 | 
			
		||||
	return get_chan_imp_resp(input, chan_imp_resp, search_center, search_start_pos, search_stop_pos, tseq, tseqlen,
 | 
			
		||||
				 corr_max);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <complex>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <functional>
 | 
			
		||||
@@ -145,6 +146,7 @@ template <typename T> struct ipc_hw {
 | 
			
		||||
	{
 | 
			
		||||
		void *ret;
 | 
			
		||||
		static int to_skip = 0;
 | 
			
		||||
		static uint64_t last_ts;
 | 
			
		||||
 | 
			
		||||
		blade_sample_type pbuf[508 * 2];
 | 
			
		||||
 | 
			
		||||
@@ -185,7 +187,9 @@ template <typename T> struct ipc_hw {
 | 
			
		||||
		if (to_skip < 120) // prevents weird overflows on startup
 | 
			
		||||
			to_skip++;
 | 
			
		||||
		else {
 | 
			
		||||
			assert(last_ts != rcd.get_first_ts());
 | 
			
		||||
			burst_handler(&rcd);
 | 
			
		||||
			last_ts = rcd.get_first_ts();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -173,6 +173,7 @@ __attribute__((xray_always_instrument)) __attribute__((noinline)) void rcv_burst
 | 
			
		||||
	unsigned int fnbm = 0;
 | 
			
		||||
	signalVector burst(ONE_TS_BURST_LEN, 100, 100);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	cpu_set_t cpuset;
 | 
			
		||||
 | 
			
		||||
	CPU_ZERO(&cpuset);
 | 
			
		||||
@@ -192,7 +193,7 @@ __attribute__((xray_always_instrument)) __attribute__((noinline)) void rcv_burst
 | 
			
		||||
		std::cerr << "scheduler: errreur! " << std::strerror(errno);
 | 
			
		||||
		exit(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
	while (1) {
 | 
			
		||||
		one_burst e;
 | 
			
		||||
		while (!q->spsc_pop(&e)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -44,13 +44,13 @@ extern "C" {
 | 
			
		||||
#define DBGLG(...) std::cerr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(SYNCTHINGONLY) || !defined(NODAMNLOG)
 | 
			
		||||
#if !defined(SYNCTHINGONLY) //|| !defined(NODAMNLOG)
 | 
			
		||||
#define DBGLG2(...) ms_trx::dummy_log()
 | 
			
		||||
#else
 | 
			
		||||
#define DBGLG2(...) std::cerr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PRINT_Q_OVERFLOW
 | 
			
		||||
// #define PRINT_Q_OVERFLOW
 | 
			
		||||
__attribute__((xray_always_instrument)) __attribute__((noinline)) bool ms_trx::decode_sch(float *bits,
 | 
			
		||||
											  bool update_global_clock)
 | 
			
		||||
{
 | 
			
		||||
@@ -145,6 +145,8 @@ bool ms_trx::handle_sch_or_nb(bool get_first_sch)
 | 
			
		||||
#ifdef PRINT_Q_OVERFLOW
 | 
			
		||||
	if (!pushok)
 | 
			
		||||
		std::cout << "F" << std::endl;
 | 
			
		||||
	else
 | 
			
		||||
	 std::cout << "+" << std::endl;;
 | 
			
		||||
#endif
 | 
			
		||||
	if (do_auto_gain)
 | 
			
		||||
		maybe_update_gain(brst);
 | 
			
		||||
@@ -180,7 +182,10 @@ bool ms_trx::handle_sch(bool is_first_sch_acq)
 | 
			
		||||
 | 
			
		||||
	auto start = is_first_sch_acq ? get_sch_buffer_chan_imp_resp(ss, &channel_imp_resp[0], buf_len, &max_corr) :
 | 
			
		||||
					get_sch_chan_imp_resp(ss, channel_imp_resp);
 | 
			
		||||
	detect_burst(&ss[start], &channel_imp_resp[0], 0, outbin);
 | 
			
		||||
	if(start <0)
 | 
			
		||||
		std::cerr << "wtf start" << start << (is_first_sch_acq ? "FIRST" : "") << std::endl;
 | 
			
		||||
	auto clamped_start = start < 0 ? 0 : start;
 | 
			
		||||
	detect_burst(&ss[0], &channel_imp_resp[0], clamped_start, outbin);
 | 
			
		||||
 | 
			
		||||
	SoftVector bitss(148);
 | 
			
		||||
	for (int i = 0; i < 148; i++) {
 | 
			
		||||
 
 | 
			
		||||
@@ -220,6 +220,9 @@ int main(int argc, char *argv[])
 | 
			
		||||
		if (tx_flag)
 | 
			
		||||
			std::thread(tx_test, trx, &trx->ts_hitter_q, &trx->mTSC).detach();
 | 
			
		||||
		trx->start();
 | 
			
		||||
 | 
			
		||||
		usleep(1000*100);
 | 
			
		||||
		trx->signal_start();
 | 
			
		||||
		do {
 | 
			
		||||
			sleep(1);
 | 
			
		||||
		} while (1);
 | 
			
		||||
@@ -253,6 +256,7 @@ bh_fn_t ms_trx::rx_bh()
 | 
			
		||||
	return [this](dev_buf_t *rcd) -> int {
 | 
			
		||||
		if (this->search_for_sch(rcd) == SCH_STATE::FOUND)
 | 
			
		||||
			this->grab_bursts(rcd);
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user