From 68d193a725241df755370308faa9c8315346a6c3 Mon Sep 17 00:00:00 2001 From: ismagom Date: Wed, 13 May 2015 11:44:01 +0200 Subject: [PATCH] Working on mac_test --- matlab/sync/cfo_estimate_cp.m | 26 +- matlab/sync/cfo_test.m | 28 +- matlab/sync/compute_m0.m | 55 -- matlab/sync/compute_m1.m | 49 -- matlab/sync/convfft.m | 57 -- .../sync/find_coarse_time_and_freq_offset.m | 82 --- matlab/sync/find_pss.m | 31 +- matlab/tests/prach_test.m | 16 +- .../common/include/srsapps/common/tti_sync.h | 1 + .../include/srsapps/common/tti_sync_cv.h | 1 + srsapps/common/src/tti_sync_cv.cc | 5 + srsapps/ue/mac/include/srsapps/ue/mac/demux.h | 10 +- .../ue/mac/include/srsapps/ue/mac/dl_harq.h | 2 +- .../ue/mac/include/srsapps/ue/mac/mac_pdu.h | 165 ----- srsapps/ue/mac/include/srsapps/ue/mac/mux.h | 10 +- srsapps/ue/mac/include/srsapps/ue/mac/pdu.h | 285 ++++++++ .../ue/mac/include/srsapps/ue/mac/proc_ra.h | 15 +- .../ue/mac/include/srsapps/ue/mac/ul_harq.h | 12 +- srsapps/ue/mac/src/demux.cc | 37 +- srsapps/ue/mac/src/dl_harq.cc | 9 +- srsapps/ue/mac/src/mac.cc | 49 +- srsapps/ue/mac/src/mac_pdu.cc | 214 ------ srsapps/ue/mac/src/mux.cc | 31 +- srsapps/ue/mac/src/pdu.cc | 497 ++++++++++++++ srsapps/ue/mac/src/proc_ra.cc | 96 ++- srsapps/ue/mac/src/ul_harq.cc | 48 +- srsapps/ue/mac/test/CMakeLists.txt | 2 +- srsapps/ue/mac/test/mac_test.cc | 14 +- .../ue/phy/include/srsapps/ue/phy/dl_buffer.h | 4 +- srsapps/ue/phy/src/dl_buffer.cc | 37 +- srsapps/ue/phy/src/phy.cc | 14 +- srsapps/ue/phy/src/prach.cc | 25 +- srsapps/ue/phy/src/ul_buffer.cc | 45 +- srsapps/ue/phy/test/CMakeLists.txt | 4 +- srsapps/ue/phy/test/ue_itf_test_prach.cc | 26 +- srslte/examples/CMakeLists.txt | 15 +- srslte/examples/prach_ue.c | 9 +- .../examples/tutorial_examples/CMakeLists.txt | 7 +- srslte/examples/tutorial_examples/ue_rx.c | 629 ------------------ srslte/include/srslte/phch/dci.h | 3 + srslte/lib/CMakeLists.txt | 16 +- srslte/lib/phch/src/dci.c | 15 +- srslte/lib/phch/src/pdcch.c | 14 +- srslte/lib/phch/src/prach.c | 9 +- srslte/lib/phch/src/pusch.c | 1 - srslte/lib/phch/src/regs.c | 4 +- srslte/lib/phch/src/sch.c | 5 +- srslte/lib/phch/test/prach_test_mex.c | 3 +- srslte/lib/sync/src/sync.c | 10 +- srslte/lib/sync/test/CMakeLists.txt | 2 +- srslte/lib/ue/src/ue_cell_search.c | 2 +- srslte/lib/ue/src/ue_dl.c | 4 +- srslte/lib/ue/src/ue_mib.c | 4 +- srslte/lib/ue/src/ue_sync.c | 18 +- srslte/lib/ue/src/ue_ul.c | 2 - 55 files changed, 1224 insertions(+), 1550 deletions(-) delete mode 100644 matlab/sync/compute_m0.m delete mode 100644 matlab/sync/compute_m1.m delete mode 100644 matlab/sync/convfft.m delete mode 100644 matlab/sync/find_coarse_time_and_freq_offset.m delete mode 100644 srsapps/ue/mac/include/srsapps/ue/mac/mac_pdu.h create mode 100644 srsapps/ue/mac/include/srsapps/ue/mac/pdu.h delete mode 100644 srsapps/ue/mac/src/mac_pdu.cc create mode 100644 srsapps/ue/mac/src/pdu.cc delete mode 100644 srslte/examples/tutorial_examples/ue_rx.c diff --git a/matlab/sync/cfo_estimate_cp.m b/matlab/sync/cfo_estimate_cp.m index e04960dad..0d3a4d723 100644 --- a/matlab/sync/cfo_estimate_cp.m +++ b/matlab/sync/cfo_estimate_cp.m @@ -1,12 +1,18 @@ -function cfo = cfo_estimate_cp(input, Nsyms, sym_len, cp0_len, cp_len) +function cfo = cfo_estimate_cp(input_slot, Nsyms, sym_len, cp0_len, cp_len) -r=zeros(Nsyms, 1); -r(1)=sum(input(1:cp0_len).*conj(input(1+sym_len:cp0_len+sym_len))); -s=cp0_len+sym_len+1; -e=cp0_len+sym_len+cp_len; -for i=2:Nsyms - r(i)=sum(input(s:e).*conj(input(s+sym_len:e+sym_len))); - s=s+sym_len+cp_len; - e=e+sym_len+cp_len; +% Start correlating from the end. Nsyms is the number of symbols to +% correlate starting from the end. + +s=length(input_slot)-sym_len-cp_len; +e=length(input_slot)-sym_len; +for i=1:Nsyms + r(i)=sum(input_slot(s:e).*conj(input_slot(s+sym_len:e+sym_len))); + if (i < 7) + s=s-sym_len-cp_len; + e=e-sym_len-cp_len; + else + s=s-sym_len-cp0_len; + e=e-sym_len-cp0_len; + end end -cfo=-angle(mean(r))/2/pi; \ No newline at end of file +cfo=-angle(mean(r))/pi; \ No newline at end of file diff --git a/matlab/sync/cfo_test.m b/matlab/sync/cfo_test.m index e3bf39c51..128964f13 100644 --- a/matlab/sync/cfo_test.m +++ b/matlab/sync/cfo_test.m @@ -1,27 +1,21 @@ -%clear; -M=1000; +clear; sym_len=128; -x=lte(1:M*15360*sym_len/2048*2000/1536); -%x=read_complex('../../../eclipse_osldlib/test.dat'); -%y=resample(x,99839996,100000000); - -input=resample(x,1536,2000); -%input=x; -%input=y(1:M*15360*sym_len/2048); -%input=resample(x,3840000,1920000); +hflen = (sym_len/128)*1920*10; +N_id_2=1; +input=read_complex('../../build/lte_signal.dat', hflen*500); cp0_len=160*sym_len/2048; cp1_len=144*sym_len/2048; -slots=reshape(input,15360*sym_len/2048,[]); -[n m]=size(slots); +subframes=reshape(input,hflen,[]); +[n m]=size(subframes); -cfo=zeros(m,1); -output=zeros(size(input)); +cfo=zeros(m,2); for i=1:m - cfo(i)=cfo_estimate(slots(:,i),7,sym_len,cp1_len,cp1_len); - t=(i-1)*n+1:i*n; - %output(t)=input(t).*exp(-1i*2*pi*cfo(i)*t/sym_len); + cfo(i,1) = cfo_estimate_cp(subframes(1:960,i),1,sym_len,cp0_len,cp1_len); + [~, cfo(i,2)] = find_pss(subframes(:,i),N_id_2); + end plot(cfo) +legend('CP-based','PSS-based') \ No newline at end of file diff --git a/matlab/sync/compute_m0.m b/matlab/sync/compute_m0.m deleted file mode 100644 index f109bd1de..000000000 --- a/matlab/sync/compute_m0.m +++ /dev/null @@ -1,55 +0,0 @@ -function [ s0_m0 z1_m0 ] = compute_m0( m0) -%COMPUTE_S Summary of this function goes here -% Detailed explanation goes here - - % Generate s_tilda - x_s_tilda(0+1) = 0; - x_s_tilda(1+1) = 0; - x_s_tilda(2+1) = 0; - x_s_tilda(3+1) = 0; - x_s_tilda(4+1) = 1; - for(i_hat=0:25) - x_s_tilda(i_hat+5+1) = mod((x_s_tilda(i_hat+2+1) + x_s_tilda(i_hat+1)), 2); - end - for(idx=0:30) - s_tilda(idx+1) = 1 - 2*x_s_tilda(idx+1); - end - - % Generate c_tilda - x_c_tilda(0+1) = 0; - x_c_tilda(1+1) = 0; - x_c_tilda(2+1) = 0; - x_c_tilda(3+1) = 0; - x_c_tilda(4+1) = 1; - for(i_hat=0:25) - x_c_tilda(i_hat+5+1) = mod((x_c_tilda(i_hat+3+1) + x_c_tilda(i_hat+1)), 2); - end - for(idx=0:30) - c_tilda(idx+1) = 1 - 2*x_c_tilda(idx+1); - end - - % Generate z_tilda - x_z_tilda(0+1) = 0; - x_z_tilda(1+1) = 0; - x_z_tilda(2+1) = 0; - x_z_tilda(3+1) = 0; - x_z_tilda(4+1) = 1; - for(i_hat=0:25) - x_z_tilda(i_hat+5+1) = mod((x_z_tilda(i_hat+4+1) + x_z_tilda(i_hat+2+1) + x_z_tilda(i_hat+1+1) + x_z_tilda(i_hat+1)), 2); - end - for(idx=0:30) - z_tilda(idx+1) = 1 - 2*x_z_tilda(idx+1); - end - - % Generate s0_m0 and s1_m1 - for(n=0:30) - s0_m0(n+1) = s_tilda(mod(n + m0, 31)+1); - end - - % Generate z1_m0 and z1_m1 - for(n=0:30) - z1_m0(n+1) = z_tilda(mod(n + mod(m0, 8), 31)+1); - end - -end - diff --git a/matlab/sync/compute_m1.m b/matlab/sync/compute_m1.m deleted file mode 100644 index 8fdb4c0e7..000000000 --- a/matlab/sync/compute_m1.m +++ /dev/null @@ -1,49 +0,0 @@ -function [ s1_m1 ] = compute_m1( m1, N_id_2) -%COMPUTE_S Summary of this function goes here -% Detailed explanation goes here - - % Generate s_tilda - x_s_tilda(0+1) = 0; - x_s_tilda(1+1) = 0; - x_s_tilda(2+1) = 0; - x_s_tilda(3+1) = 0; - x_s_tilda(4+1) = 1; - for(i_hat=0:25) - x_s_tilda(i_hat+5+1) = mod((x_s_tilda(i_hat+2+1) + x_s_tilda(i_hat+1)), 2); - end - for(idx=0:30) - s_tilda(idx+1) = 1 - 2*x_s_tilda(idx+1); - end - - % Generate c_tilda - x_c_tilda(0+1) = 0; - x_c_tilda(1+1) = 0; - x_c_tilda(2+1) = 0; - x_c_tilda(3+1) = 0; - x_c_tilda(4+1) = 1; - for(i_hat=0:25) - x_c_tilda(i_hat+5+1) = mod((x_c_tilda(i_hat+3+1) + x_c_tilda(i_hat+1)), 2); - end - for(idx=0:30) - c_tilda(idx+1) = 1 - 2*x_c_tilda(idx+1); - end - - % Generate z_tilda - x_z_tilda(0+1) = 0; - x_z_tilda(1+1) = 0; - x_z_tilda(2+1) = 0; - x_z_tilda(3+1) = 0; - x_z_tilda(4+1) = 1; - for(i_hat=0:25) - x_z_tilda(i_hat+5+1) = mod((x_z_tilda(i_hat+4+1) + x_z_tilda(i_hat+2+1) + x_z_tilda(i_hat+1+1) + x_z_tilda(i_hat+1)), 2); - end - for(idx=0:30) - z_tilda(idx+1) = 1 - 2*x_z_tilda(idx+1); - end - - % Generate s0_m0 and s1_m1 - for(n=0:30) - s1_m1(n+1) = s_tilda(mod(n + m1, 31)+1); - end -end - diff --git a/matlab/sync/convfft.m b/matlab/sync/convfft.m deleted file mode 100644 index 5ccf9a886..000000000 --- a/matlab/sync/convfft.m +++ /dev/null @@ -1,57 +0,0 @@ -function [out] = convfft(z1,z2) -%CONVFFT FFT-based convolution and polynomial multiplication. -% C = CONVFFT(A, B) convolves vectors A and B. The resulting -% vector is length LENGTH(A)+LENGTH(B)-1. -% If A and B are vectors of polynomial coefficients, convolving -% them is equivalent to multiplying the two polynomials. -% -% Please contribute if you find this software useful. -% Report bugs to luigi.rosa@tiscali.it -% -%***************************************************************** -% Luigi Rosa -% Via Centrale 27 -% 67042 Civita di Bagno -% L'Aquila --- ITALY -% email luigi.rosa@tiscali.it -% mobile +39 340 3463208 -% http://utenti.lycos.it/matlab -%***************************************************************** -% - - -z1x=size(z1,1); -z1y=size(z1,2); -z2x=size(z2,1); -z2y=size(z2,2); -if (~isa(z1,'double'))||(~isa(z2,'double'))||(ndims(z1)>2)||(ndims(z2)>2) - disp('Error: input vector must be unidimensional double array'); - out=[]; - return; -else - if ((z1x>1)&&(z1y>1)) || ((z2x>1)&&(z2y>1)) - out=[]; - disp('Error: input vectors are double matrices'); - return; - - else - - if (z1x==1)&&(z1y>1) - z1=z1'; - z1x=z1y; - end - - - if (z2x==1)&&(z2y>1) - z2=z2'; - z2x=z2y; - end - - - if (any(any(imag(z1))))||(any(any(imag(z2)))) - out=(ifft(fft(z1,z1x+z2x-1).*fft(z2,z1x+z2x-1))); - else - out=real(ifft(fft(z1,z1x+z2x-1).*fft(z2,z1x+z2x-1))); - end - end -end \ No newline at end of file diff --git a/matlab/sync/find_coarse_time_and_freq_offset.m b/matlab/sync/find_coarse_time_and_freq_offset.m deleted file mode 100644 index 7293c17a9..000000000 --- a/matlab/sync/find_coarse_time_and_freq_offset.m +++ /dev/null @@ -1,82 +0,0 @@ -function [coarse_start freq_offset] = find_coarse_time_and_freq_offset(in, N_cp_l_else) - - % Decompose input - in_re = real(in); - in_im = imag(in); - - abs_corr = zeros(1,960); - for(slot=0:10) - for(n=1:40:960) - corr_re = 0; - corr_im = 0; - for(z=1:N_cp_l_else) - index = (slot*960) + n-1 + z; - corr_re = corr_re + in_re(index)*in_re(index+128) + in_im(index)*in_im(index+128); - corr_im = corr_im + in_re(index)*in_im(index+128) - in_im(index)*in_re(index+128); - end - abs_corr(n) = abs_corr(n) + corr_re*corr_re + corr_im*corr_im; - end - end - - % Find first and second max - abs_corr_idx = zeros(1,2); - for(m=0:1) - abs_corr_max = 0; - for(n=1:480) - if(abs_corr((m*480)+n) > abs_corr_max) - abs_corr_max = abs_corr((m*480)+n); - abs_corr_idx(m+1) = (m*480)+n; - end - end - end - - % Fine correlation and fraction frequency offset - abs_corr = zeros(1,960); - corr_freq_err = zeros(1,960); - for(slot=1:10) - for(idx=1:2) - if((abs_corr_idx(idx) - 40) < 1) - abs_corr_idx(idx) = 41; - end - if((abs_corr_idx(idx) + 40) > 960) - abs_corr_idx(idx) = 960 - 40; - end - for(n=abs_corr_idx(idx)-40:abs_corr_idx(idx)+40) - corr_re = 0; - corr_im = 0; - for(z=1:N_cp_l_else) - index = (slot*960) + n-1 + z; - corr_re = corr_re + in_re(index)*in_re(index+128) + in_im(index)*in_im(index+128); - corr_im = corr_im + in_re(index)*in_im(index+128) - in_im(index)*in_re(index+128); - end - abs_corr(n) = abs_corr(n) + corr_re*corr_re + corr_im*corr_im; - corr_freq_err(n) = corr_freq_err(n) + atan2(corr_im, corr_re)/(128*2*pi*(0.0005/960)); - end - end - end - - % Find first and second max - abs_corr_idx = zeros(1,2); - for(m=0:1) - abs_corr_max = 0; - for(n=1:480) - if(abs_corr((m*480)+n) > abs_corr_max) - abs_corr_max = abs_corr((m*480)+n); - abs_corr_idx(m+1) = (m*480)+n; - end - end - end - - % Determine frequency offset FIXME No integer offset is calculated here - freq_offset = (corr_freq_err(abs_corr_idx(1))/10 + corr_freq_err(abs_corr_idx(2))/10)/2;23 - - % Determine the symbol start locations from the correlation peaks - % FIXME Needs some work - tmp = abs_corr_idx(1); - while(tmp > 0) - tmp = tmp - 2192; - end - for(n=1:7) - coarse_start(n) = tmp + (n*2192); - end -end \ No newline at end of file diff --git a/matlab/sync/find_pss.m b/matlab/sync/find_pss.m index 94486553f..c4b460173 100644 --- a/matlab/sync/find_pss.m +++ b/matlab/sync/find_pss.m @@ -1,31 +1,18 @@ -function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot, threshold) - if nargin == 2 - doplot = false; - threshold = 0; - end - if nargin == 3 - threshold = 0; - end +function [ fs, cfo, p_m, w2] = find_pss( x, N_id_2) c=lte_pss_zc(N_id_2); cc=[zeros(33,1); c; zeros(33,1)]; ccf=[0; cc(65:128); cc(2:64)]; ccf=conj(ifft(ccf)); - w2=conv(x,ccf); - if (doplot) - %plot(10*log10(abs(w2)));%./mean(abs(w2)))); - plot(abs(w2)) - %axis([0 length(w2) 0 20]) - end - [m i]=max(abs(w2)); - fs=i-960; - p_m = m/mean(abs(w2)); - - if doplot - fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',fs, ... - mean(abs(w2)), m, 10*log10(m/mean(abs(w2)))); - end + [m, fs]=max(abs(w2)); + + y=ccf.*x(fs-128:fs-1); + y0=y(1:64); + y1=y(65:length(y)); + cfo=angle(conj(sum(y0))*sum(y1))/pi; + p_m = m/mean(abs(w2)); + end diff --git a/matlab/tests/prach_test.m b/matlab/tests/prach_test.m index 5fbee677e..1263860a2 100644 --- a/matlab/tests/prach_test.m +++ b/matlab/tests/prach_test.m @@ -2,18 +2,18 @@ clear ueConfig=struct('NULRB',6,'DuplexMode','FDD','CyclicPrefix','Normal'); prachConfig=struct('Format',0,'SeqIdx',0,'PreambleIdx',0,'CyclicShiftIdx',0,'HighSpeed',0,'TimingOffset',0,'FreqIdx',0,'FreqOffset',0); -addpath('../../debug/lte/phy/lib/phch/test') +addpath('../../debug/srslte/lib/phch/test') -NULRB=[15 25 50 100]; +NULRB=[6 15 25 50 100]; % FreqIdx, FreqOffset and TimeOffset need to be tested -for n_rb=1:length(NULRB) - for format=1:3; - for seqIdx=0:17:837 +for n_rb=3:length(NULRB) + for format=0; + for seqIdx=0:17:237 fprintf('RB: %d, format %d, seqIdx: %d\n',NULRB(n_rb),format,seqIdx); for preambleIdx=0:23:63 - for CyclicShift=0:6:15 + for CyclicShift=1:3:15 %for hs=0:1 hs=0; ueConfig.NULRB=NULRB(n_rb); @@ -22,8 +22,8 @@ for n_rb=1:length(NULRB) prachConfig.PreambleIdx=preambleIdx; prachConfig.CyclicShiftIdx=CyclicShift; prachConfig.HighSpeed=hs; - prachConfig.FreqIdx=5; - prachConfig.FreqOffest=5; + prachConfig.FreqIdx=0; + prachConfig.FreqOffset=0; lib=srslte_prach(ueConfig,prachConfig); [mat, info]=ltePRACH(ueConfig,prachConfig); diff --git a/srsapps/common/include/srsapps/common/tti_sync.h b/srsapps/common/include/srsapps/common/tti_sync.h index 52cc8501f..6779e76c8 100644 --- a/srsapps/common/include/srsapps/common/tti_sync.h +++ b/srsapps/common/include/srsapps/common/tti_sync.h @@ -51,6 +51,7 @@ class tti_sync init_counters(0); } virtual void increase() = 0; + virtual void resync() = 0; virtual uint32_t wait() = 0; virtual void set_producer_cntr(uint32_t) = 0; uint32_t get_producer_cntr() { return producer_cntr; } diff --git a/srsapps/common/include/srsapps/common/tti_sync_cv.h b/srsapps/common/include/srsapps/common/tti_sync_cv.h index 35b020974..fea9a6db7 100644 --- a/srsapps/common/include/srsapps/common/tti_sync_cv.h +++ b/srsapps/common/include/srsapps/common/tti_sync_cv.h @@ -48,6 +48,7 @@ class tti_sync_cv : public tti_sync ~tti_sync_cv(); void increase(); uint32_t wait(); + void resync(); void set_producer_cntr(uint32_t producer_cntr); private: diff --git a/srsapps/common/src/tti_sync_cv.cc b/srsapps/common/src/tti_sync_cv.cc index 8e5e16a6f..da5b5096a 100644 --- a/srsapps/common/src/tti_sync_cv.cc +++ b/srsapps/common/src/tti_sync_cv.cc @@ -56,6 +56,11 @@ namespace srslte { return x; } + void tti_sync_cv::resync() + { + consumer_cntr = producer_cntr; + } + void tti_sync_cv::set_producer_cntr(uint32_t producer_cntr) { pthread_mutex_lock(&mutex); diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/demux.h b/srsapps/ue/mac/include/srsapps/ue/mac/demux.h index 824803b67..f4182b50e 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/demux.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/demux.h @@ -32,7 +32,7 @@ #include "srsapps/ue/mac/mac_io.h" #include "srsapps/common/timers.h" #include "srsapps/ue/mac/mac_params.h" -#include "srsapps/ue/mac/mac_pdu.h" +#include "srsapps/ue/mac/pdu.h" #ifndef DEMUX_H #define DEMUX_H @@ -57,11 +57,11 @@ public: uint64_t get_contention_resolution_id(); private: - mac_pdu mac_msg; - mac_pdu pending_mac_msg; + sch_pdu mac_msg; + sch_pdu pending_mac_msg; - void process_pdu(mac_pdu *pdu); - bool process_ce(mac_pdu::mac_subh *subheader); + void process_pdu(sch_pdu *pdu); + bool process_ce(sch_subh *subheader); uint64_t contention_resolution_id; bool pending_temp_rnti; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h b/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h index befa2c1ff..dbddbc9f6 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/dl_harq.h @@ -75,6 +75,7 @@ private: uint32_t pid; private: + bool is_initiated; dl_harq_entity *harq_entity; uint8_t *payload; uint32_t max_payload_len; @@ -89,7 +90,6 @@ private: srslte_softbuffer_rx_t softbuffer; }; - dl_harq_process *proc; timers *timers_db; demux *demux_unit; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac_pdu.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac_pdu.h deleted file mode 100644 index 58bfb65e6..000000000 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac_pdu.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include -#include "srsapps/common/log.h" - -#ifndef MACPDU_H -#define MACPDU_H - -/* MAC PDU Packing/Unpacking functions */ - -namespace srslte { -namespace ue { - -class mac_pdu -{ -public: - - class mac_subh - { - public: - - typedef enum { - C_RNTI = 0, - CON_RES_ID, - TA_CMD, - PHD, - SDU - } cetype; - - // Reading functions - bool is_sdu(); - cetype ce_type(); - - uint32_t get_sdu_lcid(); - uint32_t get_sdu_nbytes(); - uint8_t* get_sdu_ptr(); - - uint16_t get_c_rnti(); - uint64_t get_con_res_id(); - uint8_t get_ta_cmd(); - uint8_t get_phd(); - - // Writing functions - bool set_sdu(uint8_t *ptr, uint32_t nof_bytes); - bool set_c_rnti(uint16_t crnti); - bool set_con_res_id(uint64_t con_res_id); - bool set_ta_cmd(uint8_t ta_cmd); - bool set_phd(uint8_t phd); - - private: - static const int MAX_CE_PAYLOAD_LEN = 8; - uint32_t lcid; - uint32_t nof_bytes; - uint8_t* sdu_payload_ptr; - uint8_t ce_payload[MAX_CE_PAYLOAD_LEN]; - }; - - mac_pdu(uint32_t max_subheaders); - - void reset(); - void init(uint32_t pdu_len); - - bool read_next(); - bool write_next(); - mac_subh* get(); - - bool write_packet(uint8_t *ptr); - void parse_packet(uint8_t *ptr); - - - -protected: - mac_subh *subheaders; - uint32_t pdu_len; - uint32_t rem_len; - uint32_t rp, wp; - uint32_t nof_subheaders; - uint32_t max_subheaders; -}; - -class mac_rar_pdu -{ -public: - class mac_rar - { - - public: - - static const uint32_t RAR_GRANT_LEN = 20; - - // Reading functions - uint32_t get_rapid(); - uint32_t get_ta_cmd(); - uint16_t get_temp_crnti(); - void get_sched_grant(uint8_t grant[RAR_GRANT_LEN]); - - // Writing functoins - void set_rapid(uint32_t rapid); - void set_ta_cmd(uint32_t ta); - void set_temp_crnti(uint16_t temp_rnti); - void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]); - private: - uint8_t grant[RAR_GRANT_LEN]; - uint32_t ta; - uint16_t temp_rnti; - }; - - mac_rar_pdu(uint32_t max_rars); - - void reset(); - void init(uint32_t pdu_len); - - bool read_next(); - bool write_next(); - mac_rar* get(); - - void set_backoff(uint8_t bi); - bool is_backoff(); - uint8_t get_backoff(); - - bool write_packet(uint8_t *ptr); - void parse_packet(uint8_t *ptr); - - -private: - mac_rar *rars; - uint32_t pdu_len; - uint32_t rem_len; - uint32_t rp, wp; - uint32_t nof_rars; - uint32_t max_rars; - -}; - -} -} - -#endif - diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mux.h b/srsapps/ue/mac/include/srsapps/ue/mac/mux.h index d35748749..9972e8f68 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mux.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mux.h @@ -31,7 +31,7 @@ #include "srsapps/common/log.h" #include "srsapps/ue/mac/mac_io.h" #include "srsapps/ue/mac/mac_params.h" -#include "srsapps/ue/mac/mac_pdu.h" +#include "srsapps/ue/mac/pdu.h" #ifndef MUX_H #define MUX_H @@ -48,6 +48,8 @@ public: void reset(); void init(log *log_h, mac_io *mac_io_h); + bool is_pending_sdu(); + uint8_t* pdu_pop(uint32_t tti_, uint32_t pdu_sz); bool pdu_move_to_msg3(uint32_t tti, uint32_t pdu_sz); void pdu_release(); @@ -63,8 +65,8 @@ public: private: bool assemble_pdu(uint32_t pdu_sz); - bool allocate_sdu(uint32_t lcid, mac_pdu *pdu, uint32_t *sdu_sz); - bool allocate_sdu(uint32_t lcid, mac_pdu *pdu); + bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, uint32_t *sdu_sz); + bool allocate_sdu(uint32_t lcid, sch_pdu *pdu); int64_t Bj[mac_io::NOF_UL_LCH]; int PBR[mac_io::NOF_UL_LCH]; // -1 sets to infinity @@ -89,7 +91,7 @@ private: /* PDU Buffer */ static const uint32_t PDU_BUFF_SZ = 16*1024; qbuff pdu_buff; - mac_pdu pdu_msg; + sch_pdu pdu_msg; }; } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h new file mode 100644 index 000000000..15ad95329 --- /dev/null +++ b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h @@ -0,0 +1,285 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 The srsLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE 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 Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + + +#include +#include "srsapps/common/log.h" +#include +#include + + +#ifndef MACPDU_H +#define MACPDU_H + +/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */ + +namespace srslte { +namespace ue { + + +template +class pdu +{ +public: + + pdu(uint32_t max_subheaders_) : subheaders(max_subheaders_) { + max_subheaders = max_subheaders_; + nof_subheaders = 0; + cur_idx = -1; + pdu_len = 0; + rem_len = 0; + for (int i=0;i= 0) { + return &subheaders[cur_idx]; + } + } + + // Section 6.1.2 + void parse_packet(uint8_t *ptr) { + nof_subheaders = 0; + while(subheaders[nof_subheaders].read_subheader(&ptr)) { + nof_subheaders++; + } + nof_subheaders++; + for (int i=0;i subheaders; + uint32_t pdu_len; + uint32_t rem_len; + int cur_idx; + int nof_subheaders; + uint32_t max_subheaders; + bool pdu_is_ul; +}; + +template +class subh +{ +public: + + virtual bool read_subheader(uint8_t** ptr) = 0; + virtual void read_payload(uint8_t **ptr) = 0; + virtual void write_subheader(uint8_t** ptr, bool is_last) = 0; + virtual void write_payload(uint8_t **ptr) = 0; + virtual void fprint(FILE *stream) = 0; + + pdu* parent; + +private: + virtual void init() = 0; +}; + + + +class sch_subh : public subh +{ + +public: + + typedef enum { + PHD_REPORT = 26, + C_RNTI = 27, + CON_RES_ID = 28, + TRUNC_BSR = 28, + TA_CMD = 29, + SHORT_BSR = 29, + DRX_CMD = 30, + LONG_BSR = 30, + PADDING = 31, + SDU = 0 + } cetype; + + // Reading functions + bool is_sdu(); + cetype ce_type(); + + bool read_subheader(uint8_t** ptr); + void read_payload(uint8_t **ptr); + uint32_t get_sdu_lcid(); + uint32_t get_sdu_nbytes(); + uint8_t* get_sdu_ptr(); + + uint16_t get_c_rnti(); + uint64_t get_con_res_id(); + uint8_t get_ta_cmd(); + uint8_t get_phd(); + + // Writing functions + void write_subheader(uint8_t** ptr, bool is_last); + void write_payload(uint8_t **ptr); + bool set_sdu(uint32_t lcid, uint8_t *ptr, uint32_t nof_bytes); + bool set_c_rnti(uint16_t crnti); + bool set_con_res_id(uint64_t con_res_id); + bool set_ta_cmd(uint8_t ta_cmd); + bool set_phd(uint8_t phd); + void set_padding(); + + void init(); + void fprint(FILE *stream); + +private: + static const int MAX_CE_PAYLOAD_LEN = 8; + uint32_t lcid; + uint32_t nof_bytes; + uint8_t* sdu_payload_ptr; + bool F_bit; + uint8_t ce_payload[MAX_CE_PAYLOAD_LEN]; + uint32_t sizeof_ce(uint32_t lcid, bool is_ul); +}; + +class sch_pdu : public pdu +{ +public: + + sch_pdu(uint32_t max_rars) : pdu(max_rars) {} + + bool write_packet(uint8_t *ptr); + bool has_space_ce(uint32_t nbytes); + bool has_space_sdu(uint32_t nbytes); + static uint32_t size_plus_header_pdu(uint32_t nbytes); + bool update_space_ce(uint32_t nbytes); + bool update_space_sdu(uint32_t nbytes); + void fprint(FILE *stream); + +}; + +class rar_subh : public subh +{ +public: + + static const uint32_t RAR_GRANT_LEN = 20; + + // Reading functions + bool read_subheader(uint8_t** ptr); + void read_payload(uint8_t** ptr); + uint32_t get_rapid(); + uint32_t get_ta_cmd(); + uint16_t get_temp_crnti(); + void get_sched_grant(uint8_t grant[RAR_GRANT_LEN]); + + // Writing functoins + void write_subheader(uint8_t** ptr, bool is_last); + void write_payload(uint8_t** ptr); + void set_rapid(uint32_t rapid); + void set_ta_cmd(uint32_t ta); + void set_temp_crnti(uint16_t temp_rnti); + void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]); + + void init(); + void fprint(FILE *stream); + +private: + uint8_t grant[RAR_GRANT_LEN]; + uint32_t ta; + uint16_t temp_rnti; + uint32_t preamble; +}; + +class rar_pdu : public pdu +{ +public: + + rar_pdu(uint32_t max_rars); + + void set_backoff(uint8_t bi); + bool has_backoff(); + uint8_t get_backoff(); + + bool write_packet(uint8_t* ptr); + void fprint(FILE *stream); + +private: + bool has_backoff_indicator; + uint8_t backoff_indicator; +}; + +} +} + +#endif + diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h index 25f7c3cb8..408b9f7c0 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_ra.h @@ -37,7 +37,7 @@ #include "srsapps/common/timers.h" #include "srsapps/ue/mac/mux.h" #include "srsapps/ue/mac/demux.h" -#include "srsapps/ue/mac/mac_pdu.h" +#include "srsapps/ue/mac/pdu.h" #ifndef PROCRA_H #define PROCRA_H @@ -50,7 +50,7 @@ namespace ue { class ra_proc : public proc,timer_callback { public: - ra_proc() : rar_pdu(20) {}; + ra_proc() : rar_pdu_msg(20) {}; bool init(mac_params *params_db, phy *phy_h, log *log_h, timers *timers_db, mux *mux_unit, demux *demux_unit); void reset(); @@ -64,10 +64,12 @@ class ra_proc : public proc,timer_callback bool in_progress(); void pdcch_to_crnti(bool is_ul_grant); void timer_expired(uint32_t timer_id); -private: +private: + void process_timeadv_cmd(uint32_t tti, uint32_t ta_cmd); void step_initialization(); + void step_initialization_wait(); void step_resource_selection(); void step_preamble_transmission(); void step_response_reception(); @@ -79,7 +81,7 @@ private: // Buffer to receive RAR PDU static const uint32_t MAX_RAR_PDU_LEN = 2048; uint8_t rar_pdu_buffer[MAX_RAR_PDU_LEN]; - mac_rar_pdu rar_pdu; + rar_pdu rar_pdu_msg; // Random Access parameters provided by higher layers defined in 5.1.1 // They are read from params_db during initialization init() @@ -115,7 +117,8 @@ private: enum { IDLE = 0, - INITIALIZATION, // Section 5.1.1 + INITIALIZATION, // Section 5.1.1 + INITIALIZATION_WAIT, RESOURCE_SELECTION, // Section 5.1.2 PREAMBLE_TRANSMISSION, // Section 5.1.3 RESPONSE_RECEPTION, // Section 5.1.4 @@ -140,6 +143,8 @@ private: mux *mux_unit; demux *demux_unit; + pthread_t pt_init_prach; + uint64_t received_contention_id; uint64_t transmitted_contention_id; uint16_t transmitted_crnti; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h b/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h index e4a2b83ff..42673a383 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/ul_harq.h @@ -54,14 +54,14 @@ public: ul_harq_entity(); ~ul_harq_entity(); - bool init(srslte_cell_t cell, uint32_t max_payload_len, log *log_h, timers* timers_, mux *mux_unit); + bool init(srslte_cell_t cell, log *log_h, timers* timers_, mux *mux_unit); void set_maxHARQ_Tx(uint32_t maxHARQ_Tx, uint32_t maxHARQ_Msg3Tx); void reset(); void reset_ndi(); bool is_sps(uint32_t pid); void run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_); - void run_tti(uint32_t tti, phy *phy_); + void run_tti(uint32_t tti, dl_buffer *dl_buffer, phy *phy_); bool is_last_retx_msg3(); private: @@ -69,7 +69,7 @@ private: class ul_harq_process { public: ul_harq_process(); - bool init(srslte_cell_t cell, uint32_t max_payload_len, ul_harq_entity *parent); + bool init(srslte_cell_t cell, ul_harq_entity *parent); void reset(); void reset_ndi(); void set_maxHARQ_Tx(uint32_t maxHARQ_Tx_, uint32_t maxHARQ_Msg3Tx_); @@ -83,6 +83,7 @@ private: void set_harq_feedback(bool ack); bool get_ndi(); + uint32_t tti; private: uint32_t current_tx_nb; uint32_t current_irv; @@ -91,14 +92,13 @@ private: srslte::log *log_h; ul_harq_entity *harq_entity; ul_sched_grant cur_grant; - uint8_t *payload; - uint32_t max_payload_len; bool is_grant_configured; srslte_softbuffer_tx_t softbuffer; uint32_t maxHARQ_Tx, maxHARQ_Msg3Tx; bool is_msg3; + bool is_initiated; - void generate_tx(ul_buffer* ul); + void generate_tx(uint8_t *pdu_payload, ul_buffer* ul); }; bool last_retx_is_msg3; diff --git a/srsapps/ue/mac/src/demux.cc b/srsapps/ue/mac/src/demux.cc index 898cb47e3..b43e655b2 100644 --- a/srsapps/ue/mac/src/demux.cc +++ b/srsapps/ue/mac/src/demux.cc @@ -81,13 +81,16 @@ void demux::push_pdu_temp_crnti(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bi tti = tti_; if (!pending_temp_rnti) { // Unpack DLSCH MAC PDU - pending_mac_msg.init(nof_bits); + pending_mac_msg.init(nof_bits/8); pending_mac_msg.parse_packet(mac_pdu); + pending_mac_msg.fprint(stdout); + //MIRAR ACK PENDING. EL QUE PASSA ES QUE AL HARQ NO FA RES SI EL CONTENTION RES ID ES 0, PERQUE ES 0??? + // Look for Contention Resolution UE ID contention_resolution_id = 0; - while(pending_mac_msg.read_next()) { - if (pending_mac_msg.get()->ce_type() == mac_pdu::mac_subh::CON_RES_ID) { + while(pending_mac_msg.next()) { + if (pending_mac_msg.get()->ce_type() == sch_subh::CON_RES_ID) { contention_resolution_id = pending_mac_msg.get()->get_con_res_id(); } } @@ -103,7 +106,7 @@ void demux::push_pdu(uint32_t tti_, uint8_t *mac_pdu, uint32_t nof_bits) { tti = tti_; // Unpack DLSCH MAC PDU - mac_msg.init(nof_bits); + mac_msg.init(nof_bits/8); mac_msg.parse_packet(mac_pdu); process_pdu(&mac_msg); Debug("Normal MAC PDU processed\n"); @@ -124,26 +127,26 @@ void demux::demultiplex_pending_pdu(uint32_t tti_) -void demux::process_pdu(mac_pdu *pdu) +void demux::process_pdu(sch_pdu *pdu_msg) { - while(pdu->read_next()) { - if (pdu->get()->is_sdu()) { + while(pdu_msg->next()) { + if (pdu_msg->get()->is_sdu()) { // Route logical channel - if (pdu->get()->get_sdu_lcid() <= mac_io::MAC_LCH_DTCH2_DL) { - qbuff *dest_lch = mac_io_h->get(pdu->get()->get_sdu_lcid()); + if (pdu_msg->get()->get_sdu_lcid() <= mac_io::MAC_LCH_DTCH2_DL) { + qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid()); if (dest_lch) { - dest_lch->send(pdu->get()->get_sdu_ptr(), pdu->get()->get_sdu_nbytes()*8); + dest_lch->send(pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()*8); Debug("Sent MAC SDU len=%d bytes to lchid=%d\n", - pdu->get()->get_sdu_nbytes(), pdu->get()->get_sdu_lcid()); + pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid()); } else { - Error("Getting destination channel LCID=%d\n", pdu->get()->get_sdu_lcid()); + Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid()); } } else { - Warning("Received SDU for unsupported LCID=%d\n", pdu->get()->get_sdu_lcid()); + Warning("Received SDU for unsupported LCID=%d\n", pdu_msg->get()->get_sdu_lcid()); } // Process MAC Control Element } else { - if (!process_ce(pdu->get())) { + if (!process_ce(pdu_msg->get())) { Warning("Received Subheader with invalid or unkonwn LCID\n"); } } @@ -151,13 +154,13 @@ void demux::process_pdu(mac_pdu *pdu) } -bool demux::process_ce(mac_pdu::mac_subh *subh) { +bool demux::process_ce(sch_subh *subh) { switch(subh->ce_type()) { - case mac_pdu::mac_subh::CON_RES_ID: + case sch_subh::CON_RES_ID: contention_resolution_id = subh->get_c_rnti(); Debug("Saved Contention Resolution ID=%d\n", contention_resolution_id); break; - case mac_pdu::mac_subh::TA_CMD: + case sch_subh::TA_CMD: phy_h->set_timeadv(subh->get_ta_cmd()); // Start or restart timeAlignmentTimer diff --git a/srsapps/ue/mac/src/dl_harq.cc b/srsapps/ue/mac/src/dl_harq.cc index 3937e59bf..827aa8c95 100644 --- a/srsapps/ue/mac/src/dl_harq.cc +++ b/srsapps/ue/mac/src/dl_harq.cc @@ -105,10 +105,11 @@ void dl_harq_entity::send_pending_ack_contention_resolution() * HARQ PROCESS * *********************************************************/ - + dl_harq_entity::dl_harq_process::dl_harq_process() : cur_grant(0),pending_ack_grant(0) { is_first_tx = true; is_first_decoded = true; + is_initiated = false; bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant)); payload = NULL; max_payload_len = 0; @@ -118,7 +119,9 @@ void dl_harq_entity::dl_harq_process::reset() { is_first_tx = true; is_first_decoded = true; bzero(&cur_grant, sizeof(srslte::ue::dl_sched_grant)); - srslte_softbuffer_rx_reset(&softbuffer); + if (is_initiated) { + srslte_softbuffer_rx_reset(&softbuffer); + } } void dl_harq_entity::dl_harq_process::send_pending_ack_contention_resolution() @@ -169,6 +172,7 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_ pending_ul_buffer = phy_h->get_ul_buffer(tti+4); harq_entity->pending_ack_pid = pid; memcpy(&pending_ack_grant, &cur_grant, sizeof(dl_sched_grant)); + Debug("ACK pending contention resolution\n"); } else { Debug("Generating ACK\n"); // Generate ACK @@ -209,6 +213,7 @@ bool dl_harq_entity::dl_harq_process::init(srslte_cell_t cell, uint32_t max_payl fprintf(stderr, "Error initiating soft buffer\n"); return false; } else { + is_initiated = true; harq_entity = parent; log_h = harq_entity->log_h; payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * max_payload_len); diff --git a/srsapps/ue/mac/src/mac.cc b/srsapps/ue/mac/src/mac.cc index 93e114a1c..a6c9d2188 100644 --- a/srsapps/ue/mac/src/mac.cc +++ b/srsapps/ue/mac/src/mac.cc @@ -53,7 +53,14 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) reset(); - if (!pthread_create(&mac_thread, NULL, mac_thread_fnc, this)) { + pthread_attr_t attr; + struct sched_param param; + param.sched_priority = -20; + pthread_attr_init(&attr); + pthread_attr_setschedpolicy(&attr, SCHED_FIFO); + pthread_attr_setschedparam(&attr, ¶m); + + if (!pthread_create(&mac_thread, &attr, mac_thread_fnc, this)) { started = true; } else { perror("pthread_create"); @@ -63,8 +70,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) void mac::stop() { - started = false; - + started = false; pthread_join(mac_thread, NULL); } @@ -126,7 +132,7 @@ void mac::main_radio_loop() { // Init HARQ for this cell Info("Init UL/DL HARQ\n"); - ul_harq.init(cell, 8*1024, log_h, &timers_db, &mux_unit); + ul_harq.init(cell, log_h, &timers_db, &mux_unit); dl_harq.init(cell, 8*1024, log_h, &timers_db, &demux_unit); // Set the current PHY cell to the detected cell @@ -134,13 +140,17 @@ void mac::main_radio_loop() { if (phy_h->set_cell(cell)) { Info("Starting RX streaming\n"); if (phy_h->start_rxtx()) { - tti = ttisync->wait(); Info("Receiver synchronized\n"); // Send MIB to RRC mac_io_lch.get(mac_io::MAC_LCH_BCCH_DL)->send(bch_payload, SRSLTE_BCH_PAYLOAD_LEN); - is_synchronized = true; + ttisync->resync(); + Info("Wait to sync\n"); + for (int i=0;i<1000;i++) { + tti = ttisync->wait(); + } + is_synchronized = true; } else { Error("Starting PHY receiver\n"); exit(-1); @@ -151,14 +161,14 @@ void mac::main_radio_loop() { } } else { Warning("Cell not found\n"); + sleep(1); } - sleep(1); } if (is_synchronized) { /* Warning: Here order of invocation of procedures is important!! */ - + tti = ttisync->wait(); - + // Step all procedures ra_procedure.step(tti); sr_procedure.step(tti); @@ -181,10 +191,18 @@ void mac::main_radio_loop() { // Process UL grants if RA procedure is done or in contention resolution if (ra_procedure.is_successful() || ra_procedure.is_contention_resolution()) { - Info("Processing UL grants\n"); process_ul_grants(tti); } timers_db.step_all(); + + // Check if there is pending CCCH SDU in Multiplexing Unit + if (mux_unit.is_pending_sdu()) { + // Start RA procedure + if (!ra_procedure.in_progress() && !ra_procedure.is_successful()) { + Info("Starting RA procedure by RLC order\n"); + ra_procedure.start_rlc_order(); + } + } } } } @@ -267,7 +285,6 @@ void mac::process_dl_grants(uint32_t tti) { for (int i = mac_params::RNTI_C;i<=mac_params::RNTI_RA;i++) { // Check C-RNTI, SPS-RNTI and Temporal RNTI if (params_db.get_param(i) != 0) { - Info("Searching DL grants for RNTI: %d\n", params_db.get_param(i)); dl_sched_grant ue_grant(rnti_type(i), params_db.get_param(i)); if (dl_buffer->get_dl_grant(&ue_grant)) { // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it @@ -362,12 +379,16 @@ void mac::process_ul_grants(uint32_t tti) { if (params_db.get_param(i) != 0) { ul_sched_grant ul_grant(rnti_type(i), params_db.get_param(i)); if (dl_buffer->get_ul_grant(&ul_grant)) { + if (ul_grant.is_from_rar()) { + dl_buffer->release_pending_rar_grant(); + } if (ra_procedure.is_contention_resolution() && i == mac_params::RNTI_C) { ra_procedure.pdcch_to_crnti(true); } if (i == mac_params::RNTI_C || i == mac_params::RNTI_TEMP || ra_procedure.is_running()) { - if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) - ul_grant.set_ndi(true); + if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) { + ul_grant.set_ndi(true); + } ul_harq.run_tti(tti, &ul_grant, phy_h); if (i == mac_params::RNTI_TEMP) { // Discard already processed RAR grant @@ -401,7 +422,7 @@ void mac::process_ul_grants(uint32_t tti) { return; } } - ul_harq.run_tti(tti, phy_h); + ul_harq.run_tti(tti, dl_buffer, phy_h); } diff --git a/srsapps/ue/mac/src/mac_pdu.cc b/srsapps/ue/mac/src/mac_pdu.cc deleted file mode 100644 index af92e2dd6..000000000 --- a/srsapps/ue/mac/src/mac_pdu.cc +++ /dev/null @@ -1,214 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srsapps/ue/mac/mac_pdu.h" - -namespace srslte { - namespace ue { -mac_pdu::mac_subh* mac_pdu::get() -{ - -} -void mac_pdu::init(uint32_t pdu_len) -{ - -} -mac_pdu::mac_pdu(uint32_t max_subheaders) -{ - -} -mac_pdu::mac_subh::cetype mac_pdu::mac_subh::ce_type() -{ - -} -uint16_t mac_pdu::mac_subh::get_c_rnti() -{ - -} -uint64_t mac_pdu::mac_subh::get_con_res_id() -{ - -} -uint8_t mac_pdu::mac_subh::get_phd() -{ - -} -uint32_t mac_pdu::mac_subh::get_sdu_lcid() -{ - -} -uint32_t mac_pdu::mac_subh::get_sdu_nbytes() -{ - -} -uint8_t* mac_pdu::mac_subh::get_sdu_ptr() -{ - -} -uint8_t mac_pdu::mac_subh::get_ta_cmd() -{ - -} -bool mac_pdu::mac_subh::is_sdu() -{ - -} -bool mac_pdu::mac_subh::set_c_rnti(uint16_t crnti) -{ - -} -bool mac_pdu::mac_subh::set_con_res_id(uint64_t con_res_id) -{ - -} -bool mac_pdu::mac_subh::set_phd(uint8_t phd) -{ - -} -bool mac_pdu::mac_subh::set_sdu(uint8_t* ptr, uint32_t nof_bytes) -{ - -} -bool mac_pdu::mac_subh::set_ta_cmd(uint8_t ta_cmd) -{ - -} -void mac_pdu::parse_packet(uint8_t* ptr) -{ - -} -bool mac_pdu::read_next() -{ - -} -void mac_pdu::reset() -{ - -} -bool mac_pdu::write_next() -{ - -} -bool mac_pdu::write_packet(uint8_t* ptr) -{ - -} - - - -mac_rar_pdu::mac_rar* mac_rar_pdu::get() -{ - -} -uint8_t mac_rar_pdu::get_backoff() -{ - -} -void mac_rar_pdu::init(uint32_t pdu_len) -{ - -} -bool mac_rar_pdu::is_backoff() -{ - -} -uint32_t mac_rar_pdu::mac_rar::get_rapid() -{ - -} -void mac_rar_pdu::mac_rar::get_sched_grant(uint8_t grant[]) -{ - -} -uint32_t mac_rar_pdu::mac_rar::get_ta_cmd() -{ - -} -uint16_t mac_rar_pdu::mac_rar::get_temp_crnti() -{ - -} -void mac_rar_pdu::mac_rar::set_rapid(uint32_t rapid) -{ - -} -void mac_rar_pdu::mac_rar::set_sched_grant(uint8_t grant[]) -{ - -} -void mac_rar_pdu::mac_rar::set_ta_cmd(uint32_t ta) -{ - -} -void mac_rar_pdu::mac_rar::set_temp_crnti(uint16_t temp_rnti) -{ - -} -mac_rar_pdu::mac_rar_pdu(uint32_t max_rars) -{ - -} -void mac_rar_pdu::parse_packet(uint8_t* ptr) -{ - -} -bool mac_rar_pdu::read_next() -{ - -} -void mac_rar_pdu::reset() -{ - -} -void mac_rar_pdu::set_backoff(uint8_t bi) -{ - -} -bool mac_rar_pdu::write_next() -{ - -} -bool mac_rar_pdu::write_packet(uint8_t* ptr) -{ - -} - - - - - } -} - -#ifdef kk -bool demux::lcid_is_lch(uint32_t lcid) { - if (lcid <= LIBLTE_MAC_DLSCH_DCCH_LCID_END) { - return true; - } else { - return false; - } -} -#endif diff --git a/srsapps/ue/mac/src/mux.cc b/srsapps/ue/mac/src/mux.cc index 5e85b6caf..52270f1e1 100644 --- a/srsapps/ue/mac/src/mux.cc +++ b/srsapps/ue/mac/src/mux.cc @@ -64,6 +64,11 @@ void mux::reset() } } +bool mux::is_pending_sdu() +{ + return !mac_io_h->get(mac_io::MAC_LCH_CCCH_UL)->isempty(); +} + void mux::set_priority(uint32_t lch_id, uint32_t set_priority, int set_PBR, uint32_t set_BSD) { pthread_mutex_lock(&mutex); @@ -145,7 +150,7 @@ void mux::append_crnti_ce_next_tx(uint16_t crnti) { pending_crnti_ce = crnti; } -bool mux::assemble_pdu(uint32_t pdu_sz) { +bool mux::assemble_pdu(uint32_t pdu_sz_nbits) { uint8_t *buff = (uint8_t*) pdu_buff.request(); if (!buff) { @@ -154,13 +159,13 @@ bool mux::assemble_pdu(uint32_t pdu_sz) { } // Make sure pdu_sz is byte-aligned - pdu_sz = 8*(pdu_sz/8); + pdu_sz_nbits = 8*(pdu_sz_nbits/8); // Acquire mutex. Cannot change priorities, PBR or BSD after assemble finishes pthread_mutex_lock(&mutex); // Update Bj - for (int i=0;i=mac_io::NOF_UL_LCH;i++) { + for (int i=0;i= 0) { Bj[i] += PBR[i]; @@ -174,12 +179,13 @@ bool mux::assemble_pdu(uint32_t pdu_sz) { uint32_t sdu_sz = 0; - pdu_msg.init(pdu_sz); + pdu_msg.init(pdu_sz_nbits/8, true); // MAC control element for C-RNTI or data from UL-CCCH if (!allocate_sdu(UL_IDX(mac_io::MAC_LCH_CCCH_UL), &pdu_msg)) { if (pending_crnti_ce) { - if (pdu_msg.write_next()) { + if (pdu_msg.new_subh()) { + pdu_msg.next(); if (!pdu_msg.get()->set_c_rnti(pending_crnti_ce)) { Warning("Pending C-RNTI CE could not be inserted in MAC PDU\n"); } @@ -225,7 +231,7 @@ bool mux::assemble_pdu(uint32_t pdu_sz) { /* Generate MAC PDU and save to buffer */ if (pdu_msg.write_packet(buff)) { - pdu_buff.push(pdu_sz); + pdu_buff.push(pdu_sz_nbits); } else { Error("Writing PDU message to packet\n"); return false; @@ -234,21 +240,22 @@ bool mux::assemble_pdu(uint32_t pdu_sz) { } -bool mux::allocate_sdu(uint32_t lcid, mac_pdu *pdu) +bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg) { - return allocate_sdu(lcid, pdu, NULL); + return allocate_sdu(lcid, pdu_msg, NULL); } -bool mux::allocate_sdu(uint32_t lcid, mac_pdu *pdu, uint32_t *sdu_sz) +bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz) { // Get n-th pending SDU pointer and length uint32_t buff_len; - uint8_t *buff_ptr = (uint8_t*) mac_io_h->get(lcid)->pop(&buff_len, nof_tx_pkts[lcid]); + uint8_t *buff_ptr = (uint8_t*) mac_io_h->get(mac_io::MAC_LCH_CCCH_UL + lcid)->pop(&buff_len, nof_tx_pkts[lcid]); if (buff_ptr) { // there is pending SDU to allocate - if (pdu->write_next()) { // there is space for a new subheader - if (pdu->get()->set_sdu(buff_ptr, buff_len)) { // new SDU could be added + if (pdu_msg->new_subh()) { // there is space for a new subheader + pdu_msg->next(); + if (pdu_msg->get()->set_sdu(lcid, buff_ptr, buff_len/8)) { // new SDU could be added // Increase number of pop'ed packets from queue nof_tx_pkts[lcid]++; return true; diff --git a/srsapps/ue/mac/src/pdu.cc b/srsapps/ue/mac/src/pdu.cc new file mode 100644 index 000000000..058efae63 --- /dev/null +++ b/srsapps/ue/mac/src/pdu.cc @@ -0,0 +1,497 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 The srsLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE 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 Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include +#include + +#include "srsapps/ue/mac/pdu.h" +#include "srslte/srslte.h" + +namespace srslte { + namespace ue { + + +void sch_pdu::fprint(FILE* stream) +{ + fprintf(stream, "MAC SDU for UL/DL-SCH. "); + pdu::fprint(stream); +} + +void sch_subh::fprint(FILE* stream) +{ + if (is_sdu()) { + fprintf(stream, "SDU LCHID=%d, SDU nof_bytes=%d\n", lcid, nof_bytes); + } else { + switch(lcid) { + case C_RNTI: + fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti()); + break; + case CON_RES_ID: + fprintf(stream, "Contention Resolution ID CE: %d\n", get_con_res_id()); + break; + case TA_CMD: + fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd()); + break; + } + } +} + +// Section 6.1.2 +bool sch_pdu::write_packet(uint8_t* ptr) +{ + // Add single or two-byte padding if required + if (rem_len == 1 || rem_len == 2) { + sch_subh padding; + padding.set_padding(); + for (int i=0;i= 0) { + last_sdu--; + } + int last_ce = nof_subheaders-1; + while(subheaders[last_ce].is_sdu() && last_ce >= 0) { + last_ce--; + } + int last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce; + // Write subheaders for MAC CE first + for (int i=0;i= nbytes + 1) { + return true; + } else { + return false; + } +} +bool sch_pdu::has_space_sdu(uint32_t nbytes) +{ + if (rem_len >= size_plus_header_pdu(nbytes)) { + return true; + } else { + return false; + } +} +bool sch_pdu::update_space_ce(uint32_t nbytes) +{ + if (has_space_ce(nbytes)) { + rem_len -= nbytes + 1; + } +} +bool sch_pdu::update_space_sdu(uint32_t nbytes) +{ + if (has_space_sdu(nbytes)) { + rem_len -= size_plus_header_pdu(nbytes); + } +} + + + +void sch_subh::init() +{ + lcid = 0; + nof_bytes = 0; + sdu_payload_ptr = NULL; + bzero(ce_payload, sizeof(uint8_t) * MAX_CE_PAYLOAD_LEN); +} + +sch_subh::cetype sch_subh::ce_type() +{ + if (lcid >= PHD_REPORT) { + return (cetype) lcid; + } else { + return SDU; + } +} + +uint32_t sch_subh::sizeof_ce(uint32_t lcid, bool is_ul) +{ + if (is_ul) { + switch(lcid) { + case PHD_REPORT: + return 1; + case C_RNTI: + return 2; + case TRUNC_BSR: + return 1; + case SHORT_BSR: + return 1; + case LONG_BSR: + return 3; + case PADDING: + return 0; + } + } else { + switch(lcid) { + case CON_RES_ID: + return 6; + case TA_CMD: + return 1; + case DRX_CMD: + return 0; + case PADDING: + return 0; + } + } +} +bool sch_subh::is_sdu() +{ + return ce_type() == SDU; +} +uint16_t sch_subh::get_c_rnti() +{ + return *((uint16_t*) ce_payload); +} +uint64_t sch_subh::get_con_res_id() +{ + return *((uint64_t*) ce_payload); +} +uint8_t sch_subh::get_phd() +{ + return *((uint8_t*) ce_payload); +} +uint32_t sch_subh::get_sdu_lcid() +{ + return *((uint32_t*) ce_payload); +} +uint32_t sch_subh::get_sdu_nbytes() +{ + return *((uint32_t*) ce_payload); +} +uint8_t* sch_subh::get_sdu_ptr() +{ + return sdu_payload_ptr; +} +uint8_t sch_subh::get_ta_cmd() +{ + return *((uint8_t*) ce_payload); +} +void sch_subh::set_padding() +{ + lcid = PADDING; +} +bool sch_subh::set_c_rnti(uint16_t crnti) +{ + if (((sch_pdu*)parent)->has_space_ce(2)) { + *((uint16_t*) ce_payload) = crnti; + lcid = C_RNTI; + ((sch_pdu*)parent)->update_space_ce(2); + return true; + } else { + return false; + } +} +bool sch_subh::set_con_res_id(uint64_t con_res_id) +{ + if (((sch_pdu*)parent)->has_space_ce(6)) { + *((uint64_t*) ce_payload) = con_res_id; + lcid = CON_RES_ID; + ((sch_pdu*)parent)->update_space_ce(6); + return true; + } else { + return false; + } +} +bool sch_subh::set_phd(uint8_t phd) +{ + if (((sch_pdu*)parent)->has_space_ce(1)) { + *((uint8_t*) ce_payload) = phd; + lcid = PHD_REPORT; + ((sch_pdu*)parent)->update_space_ce(1); + return true; + } else { + return false; + } +} +bool sch_subh::set_sdu(uint32_t lcid_, uint8_t* ptr, uint32_t nof_bytes_) +{ + if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_)) { + sdu_payload_ptr = ptr; + nof_bytes = nof_bytes_; + lcid = lcid_; + ((sch_pdu*)parent)->update_space_sdu(nof_bytes_); + return true; + } else { + return false; + } +} +bool sch_subh::set_ta_cmd(uint8_t ta_cmd) +{ + if (((sch_pdu*)parent)->has_space_ce(1)) { + *((uint8_t*) ce_payload) = ta_cmd; + lcid = TA_CMD; + ((sch_pdu*)parent)->update_space_ce(1); + return true; + } else { + return false; + } +} +// Section 6.2.1 +void sch_subh::write_subheader(uint8_t** ptr, bool is_last) +{ + if (is_sdu()) { + // MAC SDU: R/R/E/LCID/F/L subheader + srslte_bit_pack(0, ptr, 2); // R, R + srslte_bit_pack(is_last?1:0, ptr, 1); // E + srslte_bit_pack(lcid, ptr, 5); // LCID + + // 2nd and 3rd octet + srslte_bit_pack(F_bit?1:0, ptr, 1); // F + srslte_bit_pack(nof_bytes, ptr, nof_bytes<128?7:15); // L + } else { + // MAC CE: R/R/E/LCID MAC Subheader + srslte_bit_pack(0, ptr, 2); // R, R + srslte_bit_pack(is_last?1:0, ptr, 1); // E + srslte_bit_pack(lcid, ptr, 5); // LCID + } +} +void sch_subh::write_payload(uint8_t** ptr) +{ + if (is_sdu()) { + memcpy(*ptr, sdu_payload_ptr, nof_bytes*8*sizeof(uint8_t)); + } else { + srslte_bit_pack_vector(ce_payload, *ptr, nof_bytes*8); + } + *ptr += nof_bytes*8; +} +bool sch_subh::read_subheader(uint8_t** ptr) +{ + // Skip R + *ptr += 2; + bool e_bit = srslte_bit_unpack(ptr, 1)?true:false; + lcid = srslte_bit_unpack(ptr, 5); + if (is_sdu()) { + F_bit = srslte_bit_unpack(ptr, 1)?true:false; + nof_bytes = srslte_bit_unpack(ptr, F_bit?7:15); + } else { + nof_bytes = sizeof_ce(lcid, parent->is_ul()); + } + return e_bit; +} +void sch_subh::read_payload(uint8_t** ptr) +{ + if (is_sdu()) { + sdu_payload_ptr = *ptr; + } else { + srslte_bit_unpack_vector(ce_payload, *ptr, nof_bytes*8); + } + *ptr += nof_bytes*8; +} + + + + + + + + + + + + +void rar_pdu::fprint(FILE* stream) +{ + fprintf(stream, "MAC PDU for RAR. "); + if (has_backoff_indicator) { + fprintf(stream, "Backoff Indicator %d. ", backoff_indicator); + } + pdu::fprint(stream); +} + +void rar_subh::fprint(FILE* stream) +{ + fprintf(stream, "RAPID: %d, Temp C-RNTI: %d, TA: %d, UL Grant: ", preamble, temp_rnti, ta); + srslte_vec_fprint_hex(stream, grant, 20); +} + +rar_pdu::rar_pdu(uint32_t max_rars_) : pdu(max_rars_) +{ + backoff_indicator = 0; + has_backoff_indicator = false; +} +uint8_t rar_pdu::get_backoff() +{ + return backoff_indicator; +} +bool rar_pdu::has_backoff() +{ + return has_backoff_indicator; +} +void rar_pdu::set_backoff(uint8_t bi) +{ + has_backoff_indicator = true; + backoff_indicator = bi; +} + +// Section 6.1.5 +bool rar_pdu::write_packet(uint8_t* ptr) +{ + // Write Backoff Indicator, if any + if (has_backoff_indicator) { + if (nof_subheaders > 0) { + srslte_bit_pack(1, &ptr, 1); // E + srslte_bit_pack(0, &ptr, 1); // T + srslte_bit_pack(0, &ptr, 2); // R, R + srslte_bit_pack(backoff_indicator, &ptr, 4); + } + } + // Write RAR subheaders + for (int i=0;iset_backoff((uint8_t) srslte_bit_unpack(ptr, 4)); + } + return e_bit; +} + + + + + } +} diff --git a/srsapps/ue/mac/src/proc_ra.cc b/srsapps/ue/mac/src/proc_ra.cc index 0fa6c4e8f..c0cc11aa7 100644 --- a/srsapps/ue/mac/src/proc_ra.cc +++ b/srsapps/ue/mac/src/proc_ra.cc @@ -28,6 +28,7 @@ #include #include +#include #include "srsapps/ue/mac/mac_params.h" #include "srsapps/ue/mac/mac_io.h" @@ -126,8 +127,9 @@ uint32_t interval(uint32_t x1, uint32_t x2) { } } -const char* state_str[10] = {"Idle", +const char* state_str[11] = {"Idle", "RA Initializat.: ", + "RA Initial.Wait: ", "RA ResSelection: ", "RA PreambleTx : ", "RA PreambleRx : ", @@ -163,6 +165,15 @@ void ra_proc::process_timeadv_cmd(uint32_t tti, uint32_t ta) { } } +void* init_prach_thread(void *arg) { + phy* phy_h = (phy*) arg; + if (phy_h->init_prach()) { + return (void*) 0; + } else { + return (void*) -1; + } +} + void ra_proc::step_initialization() { read_params(); pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED; @@ -172,10 +183,27 @@ void ra_proc::step_initialization() { first_rar_received = true; mux_unit->msg3_flush(); backoff_param_ms = 0; - phy_h->init_prach(); - state = RESOURCE_SELECTION; - rInfo("Done\n"); + if (pthread_create(&pt_init_prach, NULL, init_prach_thread, phy_h)) { + perror("pthread_create"); + state = RA_PROBLEM; + } else { + state = INITIALIZATION_WAIT; + } +} +void ra_proc::step_initialization_wait() { + int n = pthread_kill(pt_init_prach, 0); + if (n) { + void *status; + pthread_join(pt_init_prach, &status); + if (status) { + rError("Initializing PRACH on PHY\n"); + state = RA_PROBLEM; + } else { + rInfo("PRACH init OK\n"); + state = RESOURCE_SELECTION; + } + } } void ra_proc::step_resource_selection() { @@ -232,8 +260,7 @@ void ra_proc::step_response_reception() { dl_buffer *dl_buffer = phy_h->get_dl_buffer(tti); if (dl_buffer->get_dl_grant(&rar_grant)) { - rInfo("DL grant found RA-RNTI=%d\n", ra_rnti); - + rInfo("DL grant found RA-RNTI=%d\n", ra_rnti); if (rar_grant.get_tbs() > MAX_RAR_PDU_LEN) { rError("RAR PDU exceeds local RAR PDU buffer (%d>%d)\n", rar_grant.get_tbs(), MAX_RAR_PDU_LEN); state = RESPONSE_ERROR; @@ -241,28 +268,33 @@ void ra_proc::step_response_reception() { } // Decode packet + dl_buffer->reset_softbuffer(); if (dl_buffer->decode_data(&rar_grant, rar_pdu_buffer)) { - rar_pdu.init(rar_grant.get_tbs()); + rDebug("RAR decoded successfully TBS=%d\n", rar_grant.get_tbs()); + + rar_pdu_msg.init(rar_grant.get_tbs()/8); + rar_pdu_msg.parse_packet(rar_pdu_buffer); + rar_pdu_msg.fprint(stdout); // Set Backoff parameter - if (rar_pdu.is_backoff()) { - backoff_param_ms = backoff_table[rar_pdu.get_backoff()%16]; + if (rar_pdu_msg.has_backoff()) { + backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16]; } else { backoff_param_ms = 0; } - while(rar_pdu.read_next()) { - if (rar_pdu.get()->get_rapid() == sel_preamble) { + while(rar_pdu_msg.next()) { + if (rar_pdu_msg.get()->get_rapid() == sel_preamble) { rInfo("Received RAPID=%d\n", sel_preamble); - process_timeadv_cmd(tti, rar_pdu.get()->get_ta_cmd()); + process_timeadv_cmd(tti, rar_pdu_msg.get()->get_ta_cmd()); // FIXME: Indicate received target power //phy_h->set_target_power_rar(iniReceivedTargetPower, (preambleTransmissionCounter-1)*powerRampingStep); // Indicate grant to PHY layer. RAR grants have 6 sf delay (4 is the default delay) - uint8_t grant[mac_rar_pdu::mac_rar::RAR_GRANT_LEN]; - rar_pdu.get()->get_sched_grant(grant); + uint8_t grant[rar_subh::RAR_GRANT_LEN]; + rar_pdu_msg.get()->get_sched_grant(grant); phy_h->get_dl_buffer(tti+2)->set_rar_grant(grant); if (preambleIndex > 0) { @@ -270,7 +302,7 @@ void ra_proc::step_response_reception() { state = COMPLETION; } else { // Preamble selected by UE MAC - params_db->set_param(mac_params::RNTI_TEMP, rar_pdu.get()->get_temp_crnti()); + params_db->set_param(mac_params::RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti()); if (first_rar_received) { first_rar_received = false; @@ -287,23 +319,26 @@ void ra_proc::step_response_reception() { } // Get TransportBlock size for the grant - ul_sched_grant msg3_grant(rar_pdu.get()->get_temp_crnti()); + ul_sched_grant msg3_grant(sched_grant::RNTI_TYPE_TEMP, rar_pdu_msg.get()->get_temp_crnti()); phy_h->get_dl_buffer(tti+2)->get_ul_grant(&msg3_grant); // Move MAC PDU from Multiplexing and assembly unit to Msg3 mux_unit->pdu_move_to_msg3(tti, msg3_grant.get_tbs()); // 56 is the minimum grant provided - - state = CONTENTION_RESOLUTION; - - // Start contention resolution timer - timers_db->get(mac::CONTENTION_TIMER)->reset(); - timers_db->get(mac::CONTENTION_TIMER)->run(); - } + } + rDebug("Going to Contention Resolution state\n"); + state = CONTENTION_RESOLUTION; + + // Start contention resolution timer + timers_db->get(mac::CONTENTION_TIMER)->reset(); + timers_db->get(mac::CONTENTION_TIMER)->run(); } + } else { + rDebug("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid()); } } } } + srslte_verbose = SRSLTE_VERBOSE_NONE; } if (interval_ra > 3+responseWindowSize && interval_ra < 10000) { rInfo("Timeout while trying to receive RAR\n"); @@ -344,10 +379,11 @@ void ra_proc::step_backoff_wait() { void ra_proc::step_contention_resolution() { // If Msg3 has been sent - if (mux_unit->msg3_isempty()) { + if (mux_unit->msg3_isempty()) { msg3_transmitted = true; if (pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED) { + rInfo("PDCCH for C-RNTI received\n"); // Random Access initiated by MAC itself or PDCCH order (transmission of MAC C-RNTI CE) if (start_mode == MAC_ORDER && pdcch_to_crnti_received == PDCCH_CRNTI_UL_GRANT || start_mode == PDCCH_ORDER) @@ -363,6 +399,7 @@ void ra_proc::step_contention_resolution() { // Random Access initiated by RRC by the transmission of CCCH SDU received_contention_id = demux_unit->get_contention_resolution_id(); if (received_contention_id) { + rInfo("Received UE Contention Resolution ID\n"); // MAC PDU successfully decoded and contains MAC CE contention Id if (transmitted_contention_id == received_contention_id) { @@ -374,13 +411,17 @@ void ra_proc::step_contention_resolution() { demux_unit->demultiplex_pending_pdu(tti); state = COMPLETION; } else { + rInfo("Transmitted UE Contention Id differs from received Contention ID\n"); // Discard MAC PDU state = RESPONSE_ERROR; } params_db->set_param(mac_params::RNTI_TEMP, 0); } } + } else { + rDebug("Msg3 not yet transmitted\n"); } + } void ra_proc::step_completition() { @@ -400,6 +441,9 @@ void ra_proc::step(uint32_t tti_) case INITIALIZATION: step_initialization(); break; + case INITIALIZATION_WAIT: + step_initialization_wait(); + break; case RESOURCE_SELECTION: step_resource_selection(); break; @@ -430,6 +474,7 @@ void ra_proc::start_mac_order() if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) { start_mode = MAC_ORDER; state = INITIALIZATION; + run(); } } @@ -438,6 +483,7 @@ void ra_proc::start_pdcch_order() if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) { start_mode = PDCCH_ORDER; state = INITIALIZATION; + run(); } } @@ -446,12 +492,14 @@ void ra_proc::start_rlc_order() if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) { start_mode = RLC_ORDER; state = INITIALIZATION; + run(); } } // Contention Resolution Timer is expired (Section 5.1.5) void ra_proc::timer_expired(uint32_t timer_id) { + rInfo("Contention Resolution Timer expired. Going to Response Error\n"); params_db->set_param(mac_params::RNTI_TEMP, 0); state = RESPONSE_ERROR; } diff --git a/srsapps/ue/mac/src/ul_harq.cc b/srsapps/ue/mac/src/ul_harq.cc index 8c6fd431f..1f7de273b 100644 --- a/srsapps/ue/mac/src/ul_harq.cc +++ b/srsapps/ue/mac/src/ul_harq.cc @@ -46,13 +46,13 @@ ul_harq_entity::ul_harq_entity() { ul_harq_entity::~ul_harq_entity() { delete proc; } -bool ul_harq_entity::init(srslte_cell_t cell, uint32_t max_payload_len, log *log_h_, timers *timers_db_, mux *mux_unit_) { +bool ul_harq_entity::init(srslte_cell_t cell, log *log_h_, timers *timers_db_, mux *mux_unit_) { log_h = log_h_; mux_unit = mux_unit_; timers_db = timers_db_; for (uint32_t i=0;ilog_h; - payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * max_payload_len); - return payload?true:false; } } // Retransmission with or w/o grant (Section 5.4.2.2) void ul_harq_entity::ul_harq_process::generate_retx(ul_sched_grant* grant, ul_buffer* ul) { - current_tx_nb++; - + current_tx_nb++; if (grant) { // HARQ entity requests an adaptive transmission memcpy(&cur_grant, grant, sizeof(grant)); current_irv = irv_of_rv[grant->get_rv()%4]; harq_feedback = false; - generate_tx(ul); + generate_tx(NULL, ul); } else { // HARQ entity requests a non-adaptive transmission if (!harq_feedback) { - generate_tx(ul); + generate_tx(NULL, ul); } } @@ -226,17 +225,17 @@ void ul_harq_entity::ul_harq_process::generate_retx(ul_sched_grant* grant, ul_bu // New transmission (Section 5.4.2.2) void ul_harq_entity::ul_harq_process::generate_new_tx(uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul) { - if (ul_grant && pdu_payload && ul_grant->get_tbs() < max_payload_len) { + if (ul_grant && pdu_payload) { current_tx_nb = 0; current_irv = 0; - // Store MAC PDU in the HARQ buffer - srslte_bit_pack_vector(pdu_payload, payload, ul_grant->get_tbs()); + srslte_softbuffer_tx_reset(&softbuffer); // Store the uplink grant - memcpy(&cur_grant, ul_grant, sizeof(ul_grant)); + memcpy(&cur_grant, ul_grant, sizeof(ul_sched_grant)); harq_feedback = false; - generate_tx(ul); + generate_tx(pdu_payload, ul); is_grant_configured = true; is_msg3 = is_msg3_; + Info("New %s transmission PDU Len %d bytes\n", is_msg3_?"Msg3":"", cur_grant.get_tbs()); } } @@ -246,12 +245,13 @@ void ul_harq_entity::ul_harq_process::generate_retx(ul_buffer* ul) } // Transmission of pending frame (Section 5.4.2.2) -void ul_harq_entity::ul_harq_process::generate_tx(ul_buffer* ul) +void ul_harq_entity::ul_harq_process::generate_tx(uint8_t *pdu_payload, ul_buffer* ul) { cur_grant.set_rv(rv_of_irv[current_irv%4]); ul->set_current_tx_nb(current_tx_nb); - ul->generate_data(&cur_grant, &softbuffer, payload); + ul->generate_data(&cur_grant, &softbuffer, pdu_payload); current_irv = (current_irv+1)%4; + Info("UL transmission RV=%d, TBS=%d\n", cur_grant.get_rv(), cur_grant.get_tbs()); if (is_msg3) { if (current_tx_nb == maxHARQ_Msg3Tx) { reset(); diff --git a/srsapps/ue/mac/test/CMakeLists.txt b/srsapps/ue/mac/test/CMakeLists.txt index 412c8f966..9b3c92b00 100644 --- a/srsapps/ue/mac/test/CMakeLists.txt +++ b/srsapps/ue/mac/test/CMakeLists.txt @@ -24,5 +24,5 @@ FIND_PACKAGE(openLTE) IF(UHD_FOUND AND OPENLTE_FOUND) INCLUDE_DIRECTORIES(${OPENLTE_INCLUDE_DIRS}) ADD_EXECUTABLE(mac_test mac_test.cc) - TARGET_LINK_LIBRARIES(mac_test srsapps_ue_mac srsapps_ue_phy srsapps_common srsapps_radio srslte ${OPENLTE_LIBRARIES}) + TARGET_LINK_LIBRARIES(mac_test srsapps_ue_mac srsapps_ue_phy srsapps_common srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd) ENDIF(UHD_FOUND AND OPENLTE_FOUND) diff --git a/srsapps/ue/mac/test/mac_test.cc b/srsapps/ue/mac/test/mac_test.cc index b8a8d812f..564d77ce3 100644 --- a/srsapps/ue/mac/test/mac_test.cc +++ b/srsapps/ue/mac/test/mac_test.cc @@ -122,9 +122,10 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u mac->set_param(srslte::ue::mac_params::RA_MAXTXMSG3, sib2->rr_config_common_sib.rach_cnfg.max_harq_msg3_tx); - printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d\n", + printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n", liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles], - liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size]); + liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size], + liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]); // PDSCH ConfigCommon mac->set_param(srslte::ue::mac_params::PDSCH_RSPOWER, @@ -133,6 +134,7 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u sib2->rr_config_common_sib.pdsch_cnfg.p_b); // PUSCH ConfigCommon + phy->set_param(srslte::ue::phy_params::PUSCH_BETA, 10); phy->set_param(srslte::ue::phy_params::PUSCH_EN_64QAM, sib2->rr_config_common_sib.pusch_cnfg.enable_64_qam); phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, @@ -150,12 +152,14 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u phy->set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch); - printf("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d\n", + printf("Set PUSCH ConfigCommon: HopOffset=%d, RSGroup=%d, RSNcs=%d, N_sb=%d\n", sib2->rr_config_common_sib.pusch_cnfg.pusch_hopping_offset, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_assignment_pusch, - sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift); + sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift, + sib2->rr_config_common_sib.pusch_cnfg.n_sb); // PUCCH ConfigCommon + phy->set_param(srslte::ue::phy_params::PUCCH_BETA, 10); phy->set_param(srslte::ue::phy_params::PUCCH_DELTA_SHIFT, liblte_rrc_delta_pucch_shift_num[sib2->rr_config_common_sib.pucch_cnfg.delta_pucch_shift]); phy->set_param(srslte::ue::phy_params::PUCCH_CYCLIC_SHIFT, @@ -276,7 +280,7 @@ int main(int argc, char *argv[]) liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg); mac.set_param(srslte::ue::mac_params::CONTENTION_ID, ul_ccch_msg.msg.rrc_con_req.ue_id.random); - + // Send ConnectionRequest Packet mac.send_ccch_sdu(bit_msg.msg, bit_msg.N_bits); state = CONNECT; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h index 228777cc4..27a505560 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h @@ -54,7 +54,9 @@ namespace ue { bool get_dl_grant(dl_sched_grant *grant); void discard_pending_rar_grant(); void set_rar_grant(srslte_dci_rar_grant_t *rar_grant); - void set_rar_grant(uint8_t grant[SRSLTE_RAR_GRANT_LEN]); + void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]); + void release_pending_rar_grant(); + void reset_softbuffer(); bool decode_ack(ul_sched_grant *pusch_grant); bool decode_data(dl_sched_grant *pdsch_grant, uint8_t *payload); // returns true or false for CRC OK/NOK bool decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softbuffer, uint8_t *payload); diff --git a/srsapps/ue/phy/src/dl_buffer.cc b/srsapps/ue/phy/src/dl_buffer.cc index 6c4053367..06a24dc40 100644 --- a/srsapps/ue/phy/src/dl_buffer.cc +++ b/srsapps/ue/phy/src/dl_buffer.cc @@ -68,7 +68,7 @@ bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_t { bool ret = false; if (signal_buffer) { - INFO("DL Buffer TTI %d: Receiving packet\n", tti); + DEBUG("DL Buffer TTI %d: Receiving packet\n", tti); cf_t *sf_buffer = NULL; sf_symbols_and_ce_done = false; pdcch_llr_extracted = false; @@ -86,12 +86,14 @@ void dl_buffer::discard_pending_rar_grant() { pending_rar_grant = false; } +void dl_buffer::release_pending_rar_grant() { + pending_rar_grant = false; +} + bool dl_buffer::get_ul_grant(ul_sched_grant *grant) { if (signal_buffer) { - printf("get_ul_grant tti=%d, is_temp_rnti=%d\n", tti, grant->is_temp_rnti()); if (pending_rar_grant && grant->is_temp_rnti()) { - printf("Get pending RAR grant tti=%d\n", tti); return grant->create_from_rar(&rar_grant, cell, 0, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET)); } else { if (!sf_symbols_and_ce_done) { @@ -117,39 +119,41 @@ bool dl_buffer::get_ul_grant(ul_sched_grant *grant) } } -void dl_buffer::set_rar_grant(uint8_t grant[SRSLTE_RAR_GRANT_LEN]) +// Unpack RAR grant as defined in Section 6.2 of 36.213 +void dl_buffer::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) { - srslte_dci_rar_grant_t rar_grant; - + pending_rar_grant = true; + srslte_dci_rar_grant_unpack(&rar_grant, grant_payload); + srslte_dci_rar_grant_fprint(stdout, &rar_grant); } void dl_buffer::set_rar_grant(srslte_dci_rar_grant_t* rar_grant_) { - printf("Set pending RAR grant tti=%d\n", tti); pending_rar_grant = true; memcpy(&rar_grant, rar_grant_, sizeof(srslte_dci_rar_grant_t)); + srslte_dci_rar_grant_fprint(stdout, &rar_grant); } bool dl_buffer::get_dl_grant(dl_sched_grant *grant) { if (signal_buffer && is_ready()) { - INFO("DL Buffer TTI %d: Getting DL grant\n", tti); + DEBUG("DL Buffer TTI %d: Getting DL grant\n", tti); if (!sf_symbols_and_ce_done) { - INFO("DL Buffer TTI %d: Getting DL grant. Calling fft estimate\n", tti); + DEBUG("DL Buffer TTI %d: Getting DL grant. Calling fft estimate\n", tti); if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { return false; } sf_symbols_and_ce_done = true; } if (!pdcch_llr_extracted) { - INFO("DL Buffer TTI %d: Getting DL grant. extracting LLR\n", tti); + DEBUG("DL Buffer TTI %d: Getting DL grant. extracting LLR\n", tti); if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) { return false; } pdcch_llr_extracted = true; } - if (SRSLTE_VERBOSE_ISINFO()) { + if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_save_file((char*) "ce1", ue_dl.ce[0], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t)); srslte_vec_save_file((char*) "ce2", ue_dl.ce[1], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t)); srslte_vec_save_file((char*) "pdcch_d", ue_dl.pdcch.d, 36*ue_dl.pdcch.nof_cce*sizeof(cf_t)); @@ -179,6 +183,11 @@ bool dl_buffer::decode_ack(ul_sched_grant *grant) } } +void dl_buffer::reset_softbuffer() +{ + srslte_softbuffer_rx_reset(&ue_dl.softbuffer); +} + bool dl_buffer::decode_data(dl_sched_grant *grant, uint8_t *payload) { return decode_data(grant, &ue_dl.softbuffer, payload); @@ -187,9 +196,9 @@ bool dl_buffer::decode_data(dl_sched_grant *grant, uint8_t *payload) bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softbuffer, uint8_t *payload) { if (signal_buffer && is_ready()) { - INFO("DL Buffer TTI %d: Decoding PDSCH\n", tti); + DEBUG("DL Buffer TTI %d: Decoding PDSCH\n", tti); if (!sf_symbols_and_ce_done) { - INFO("DL Buffer TTI %d: Decoding PDSCH. Calling fft estimate\n", tti); + DEBUG("DL Buffer TTI %d: Decoding PDSCH. Calling fft estimate\n", tti); if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { return false; } @@ -201,7 +210,7 @@ bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softb int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols, ue_dl.ce, 0, grant->get_rnti(), payload); - if (SRSLTE_VERBOSE_ISINFO()) { + if (SRSLTE_VERBOSE_ISDEBUG()) { srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.pdsch_cfg.grant.nof_re*sizeof(cf_t)); } if (ret == SRSLTE_SUCCESS) { diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index 9277d48ab..22ef60725 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -43,6 +43,7 @@ namespace ue { bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_) { started = false; + radio_is_streaming = false; ttisync = ttisync_; radio_handler = radio_handler_; ul_buffer_queue = new queue(6, sizeof(ul_buffer)); @@ -55,8 +56,7 @@ bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_) pthread_attr_t attr; struct sched_param param; - param.sched_priority = 99; - + param.sched_priority = -20; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); pthread_attr_setschedparam(&attr, ¶m); @@ -115,10 +115,10 @@ void phy::set_param(phy_params::phy_param_t param, int64_t value) { // FIXME: Add PRACH power control bool phy::send_prach(uint32_t preamble_idx) { - send_prach(preamble_idx, -1, 0); + return send_prach(preamble_idx, -1, 0); } bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe) { - send_prach(preamble_idx, allowed_subframe, 0); + return send_prach(preamble_idx, allowed_subframe, 0); } bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe, int target_power_dbm) { @@ -202,7 +202,8 @@ void* phy::phy_thread_fnc(void *arg) { int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestamp_t *rx_time) { radio *radio_handler = (radio*) h; - return radio_handler->rx_now(data, nsamples, rx_time); + int n = radio_handler->rx_now(data, nsamples, rx_time); + return n; } bool phy::set_cell(srslte_cell_t cell_) { @@ -251,6 +252,9 @@ ul_buffer* phy::get_ul_buffer_adv(uint32_t tti) dl_buffer* phy::get_dl_buffer(uint32_t tti) { + if (tti + 6 < get_current_tti()) { + printf("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti()); + } return (dl_buffer*) dl_buffer_queue->get(tti); } diff --git a/srsapps/ue/phy/src/prach.cc b/srsapps/ue/phy/src/prach.cc index af1266568..7e9e3a40e 100644 --- a/srsapps/ue/phy/src/prach.cc +++ b/srsapps/ue/phy/src/prach.cc @@ -42,10 +42,10 @@ namespace ue { void prach::free_cell() { if (initiated) { - for (uint32_t i=0;i<64;i++) { + for (int i=0;i<64;i++) { if (buffer[i]) { - free(buffer[i]); - } + free(buffer[i]); + } } if (signal_buffer) { free(signal_buffer); @@ -69,12 +69,12 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_) } len = prach_obj.N_seq + prach_obj.N_cp; - for (uint32_t i=0;i<64;i++) { + for (int i=0;i<64;i++) { buffer[i] = (cf_t*) srslte_vec_malloc(len*sizeof(cf_t)); if(!buffer[i]) { return false; - } - if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_params::PRACH_FREQ_OFFSET), buffer[i])){ + } + if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_params::PRACH_FREQ_OFFSET), buffer[i])) { return false; } } @@ -86,10 +86,10 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_) } bool prach::prepare_to_send(uint32_t preamble_idx_) { - prepare_to_send(preamble_idx_, -1, 0); + return prepare_to_send(preamble_idx_, -1, 0); } bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_) { - prepare_to_send(preamble_idx_, allowed_subframe_, 0); + return prepare_to_send(preamble_idx_, allowed_subframe_, 0); } bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, int target_power_dbm) { @@ -129,7 +129,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_) { } } } - INFO("PRACH Buffer: Not ready to send at tti: %d\n", current_tti_); + DEBUG("PRACH Buffer: Not ready to send at tti: %d\n", current_tti_); return false; } @@ -149,12 +149,13 @@ bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time) srslte_timestamp_add(&tx_time, 0, 1e-3*tx_advance_sf); // Correct CFO before transmission - srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, 2*cfo / srslte_symbol_sz(cell.nof_prb)); + srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, 1.5*cfo/srslte_symbol_sz(cell.nof_prb)); // transmit radio_handler->tx(signal_buffer, len, tx_time); - INFO("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n", cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs); - //srslte_vec_save_file("prach", buffer[preamble_idx], len*sizeof(cf_t)); + INFO("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n", + cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs); + //srslte_vec_save_file("prach", buffer, len*sizeof(cf_t)); preamble_idx = -1; } diff --git a/srsapps/ue/phy/src/ul_buffer.cc b/srsapps/ue/phy/src/ul_buffer.cc index c10470ed7..f3f227f6c 100644 --- a/srsapps/ue/phy/src/ul_buffer.cc +++ b/srsapps/ue/phy/src/ul_buffer.cc @@ -28,6 +28,8 @@ #include #include #include +#include + #include "srslte/srslte.h" #include "srsapps/ue/phy/sched_grant.h" @@ -99,8 +101,7 @@ bool ul_buffer::uci_ready() { } bool ul_buffer::generate_data() { - ul_sched_grant dummy(0); - return generate_data(&dummy, NULL); + return generate_data(NULL, NULL); } bool ul_buffer::generate_data(ul_sched_grant *grant, @@ -108,7 +109,7 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, { generate_data(grant, &ue_ul.softbuffer, payload); } - + bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload) { if (is_ready()) { @@ -124,13 +125,15 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT); srslte_pusch_hopping_cfg_t pusch_hopping; - bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t)); - pusch_hopping.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB); - pusch_hopping.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ? - pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTRA_SF : - pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTER_SF; - pusch_hopping.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET); - pusch_hopping.current_tx_nb = grant->get_current_tx_nb(); + if (grant) { + bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t)); + pusch_hopping.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB); + pusch_hopping.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ? + pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTRA_SF : + pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTER_SF; + pusch_hopping.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET); + pusch_hopping.current_tx_nb = grant->get_current_tx_nb(); + } srslte_pucch_cfg_t pucch_cfg; bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); @@ -159,7 +162,7 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof int n = 0; // Transmit on PUSCH if UL grant available, otherwise in PUCCH - if (payload) { + if (grant) { grant->to_pusch_cfg(tti%10, cell.cp, &pusch_cfg); n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg, @@ -191,16 +194,26 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo srslte_timestamp_t tx_time; srslte_timestamp_copy(&tx_time, &rx_time); srslte_timestamp_add(&tx_time, 0, tx_advance_sf*1e-3 - time_adv_sec); - INFO("Send PUSCH TTI: %d, CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us\n", + + // Compute peak + float max = -1; + if (SRSLTE_VERBOSE_ISINFO()) { + float *t = (float*) signal_buffer; + for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) { + if (fabsf(t[i]) > max) { + max = fabsf(t[i]); + } + } + } + INFO("Send PUSCH TTI: %d, CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us PeakAmplitude=%f\n", tti, cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb), srslte_timestamp_real(&rx_time), - srslte_timestamp_real(&tx_time), time_adv_sec*1000000); + srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max); // Correct CFO before transmission - srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb)); - - radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); + srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, 1.5*cfo / srslte_symbol_sz(cell.nof_prb)); + radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); ready(); } diff --git a/srsapps/ue/phy/test/CMakeLists.txt b/srsapps/ue/phy/test/CMakeLists.txt index 736011d2e..37535af02 100644 --- a/srsapps/ue/phy/test/CMakeLists.txt +++ b/srsapps/ue/phy/test/CMakeLists.txt @@ -22,8 +22,8 @@ IF(UHD_FOUND) ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc) - TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_ue_phy srsapps_radio srslte) + TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_ue_phy srsapps_radio srslte srslte_uhd) ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc) - TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_ue_phy srsapps_radio srslte) + TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_ue_phy srsapps_radio srslte srslte_uhd) ENDIF(UHD_FOUND) diff --git a/srsapps/ue/phy/test/ue_itf_test_prach.cc b/srsapps/ue/phy/test/ue_itf_test_prach.cc index 74b3701a4..f1daabccf 100644 --- a/srsapps/ue/phy/test/ue_itf_test_prach.cc +++ b/srsapps/ue/phy/test/ue_itf_test_prach.cc @@ -208,7 +208,7 @@ void config_phy() { phy.set_param(srslte::ue::phy_params::PRACH_FREQ_OFFSET, 0); phy.set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, 0); phy.set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, 0); - phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1); + phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 4); phy.set_param(srslte::ue::phy_params::PUSCH_BETA, 10); phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN, 0); @@ -233,6 +233,8 @@ uint32_t interval(uint32_t x1, uint32_t x2) { } } +srslte_softbuffer_rx_t softbuffer; + // This is the MAC implementation void run_tti(uint32_t tti) { INFO("MAC running tti: %d\n", tti); @@ -247,7 +249,7 @@ void run_tti(uint32_t tti) { // Indicate PHY to transmit the PRACH when possible if (phy.send_prach(preamble_idx)) { nof_tx_ra++; - state = RAR; + state = RAR; } else { fprintf(stderr, "Error sending PRACH\n"); exit(-1); @@ -265,12 +267,10 @@ void run_tti(uint32_t tti) { // Get DL grant for RA-RNTI=2 if (dl_buffer->get_dl_grant(&rar_grant)) { + srslte_softbuffer_rx_reset(&softbuffer); // Decode packet - if (dl_buffer->decode_data(&rar_grant, payload)) { + if (dl_buffer->decode_data(&rar_grant, &softbuffer, payload)) { rar_unpack(payload, &rar_msg); - if (!prog_args.continous) { - printf("Received RAR for preamble %d\n", rar_msg.RAPID); - } if (rar_msg.RAPID == preamble_idx) { INFO("Received RAR at TTI: %d\n", tti); @@ -358,6 +358,7 @@ void run_tti(uint32_t tti) { state = RA; } } else { + srslte_softbuffer_rx_reset(&softbuffer); state = CONNSETUP; } } @@ -369,7 +370,7 @@ void run_tti(uint32_t tti) { if (dl_buffer->get_dl_grant(&conn_setup_grant)) { // Decode packet - if (dl_buffer->decode_data(&conn_setup_grant, payload)) { + if (dl_buffer->decode_data(&conn_setup_grant, &softbuffer, payload)) { nof_rx_connsetup++; state = RA; nof_rtx_connsetup=0; @@ -397,6 +398,7 @@ void run_tti(uint32_t tti) { state = RA; } } + if (srslte_verbose == SRSLTE_VERBOSE_NONE && prog_args.continous) { printf("RECV RAR %2.1f \%% RECV ConnSetup %2.1f \%% (%5u/%5u) \r", (float) 100*nof_rx_rar/nof_tx_ra, @@ -404,6 +406,7 @@ void run_tti(uint32_t tti) { nof_rx_connsetup, nof_tx_ra); } + } int main(int argc, char *argv[]) @@ -426,7 +429,7 @@ int main(int argc, char *argv[]) // Setup PHY parameters config_phy(); - + // Set RX freq and gain phy.get_radio()->set_rx_freq(prog_args.uhd_rx_freq); phy.get_radio()->set_tx_freq(prog_args.uhd_tx_freq); @@ -446,6 +449,13 @@ int main(int argc, char *argv[]) exit(-1); } + if (!phy.init_prach()) { + printf("Error initiating PRACH\n"); + exit(-1); + } + + srslte_softbuffer_rx_init(&softbuffer, cell); + /* Instruct the PHY to start RX streaming and synchronize */ if (!phy.start_rxtx()) { printf("Could not start RX\n"); diff --git a/srslte/examples/CMakeLists.txt b/srslte/examples/CMakeLists.txt index 961cae98d..1d03ca2f6 100644 --- a/srslte/examples/CMakeLists.txt +++ b/srslte/examples/CMakeLists.txt @@ -50,11 +50,14 @@ add_executable(pdsch_enodeb pdsch_enodeb.c) target_link_libraries(pdsch_enodeb srslte pthread) IF(UHD_FOUND) + target_link_libraries(pdsch_ue srslte_uhd) + target_link_libraries(pdsch_enodeb srslte_uhd) ELSE(UHD_FOUND) add_definitions(-DDISABLE_UHD) - add_definitions(-DDISABLE_UHD) ENDIF(UHD_FOUND) +FIND_PACKAGE(SRSGUI) + IF(SRSGUI_FOUND) target_link_libraries(pdsch_ue ${SRSGUI_LIBRARIES}) ELSE(SRSGUI_FOUND) @@ -69,19 +72,19 @@ ENDIF(SRSGUI_FOUND) IF(UHD_FOUND) add_executable(cell_search cell_search.c) - target_link_libraries(cell_search srslte ) + target_link_libraries(cell_search srslte srslte_uhd) add_executable(prach_ue prach_ue.c) - target_link_libraries(prach_ue srslte ) + target_link_libraries(prach_ue srslte srslte_uhd) add_executable(cell_measurement cell_measurement.c) - target_link_libraries(cell_measurement srslte) + target_link_libraries(cell_measurement srslte srslte_uhd) add_executable(usrp_capture usrp_capture.c) - target_link_libraries(usrp_capture srslte) + target_link_libraries(usrp_capture srslte srslte_uhd) add_executable(usrp_capture_sync usrp_capture_sync.c) - target_link_libraries(usrp_capture_sync srslte) + target_link_libraries(usrp_capture_sync srslte srslte_uhd) MESSAGE(STATUS " UHD examples will be installed.") diff --git a/srslte/examples/prach_ue.c b/srslte/examples/prach_ue.c index 2e292465e..383e962d5 100644 --- a/srslte/examples/prach_ue.c +++ b/srslte/examples/prach_ue.c @@ -327,6 +327,7 @@ int main(int argc, char **argv) { printf("Tunning TX receiver to %.3f MHz\n", (double ) prog_args.uhd_tx_freq/1000000); +#ifdef kk ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell); if (ret < 0) { fprintf(stderr, "Error searching for cell\n"); @@ -335,6 +336,10 @@ int main(int argc, char **argv) { printf("Cell not found\n"); exit(0); } +#endif +cell.nof_prb = 50; +cell.id = 1; +cell.nof_ports = 1; /* set sampling frequency */ int srate = srslte_sampling_freq_hz(cell.nof_prb); @@ -471,7 +476,7 @@ int main(int argc, char **argv) { cuhd_send_timed(uhd, prach_buffer, prach_buffer_len, next_tx_time.full_secs, next_tx_time.frac_secs); - srslte_vec_save_file("prach_ue", prach_buffer, prach_buffer_len*sizeof(cf_t)); + srslte_vec_save_file("prach_ue.dat", prach_buffer, prach_buffer_len*sizeof(cf_t)); ra_rnti = 2; rar_window_start = sfn+1; @@ -536,6 +541,8 @@ int main(int argc, char **argv) { cuhd_send_timed(uhd, ul_signal, SRSLTE_SF_LEN_PRB(cell.nof_prb), next_tx_time.full_secs, next_tx_time.frac_secs); + srslte_vec_save_file("prach_ue_connreq.dat", ul_signal, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); + //cuhd_start_rx_stream(uhd); state = RECV_CONNSETUP; conn_setup_trial = 0; diff --git a/srslte/examples/tutorial_examples/CMakeLists.txt b/srslte/examples/tutorial_examples/CMakeLists.txt index 0de79c29e..ceeba063d 100644 --- a/srslte/examples/tutorial_examples/CMakeLists.txt +++ b/srslte/examples/tutorial_examples/CMakeLists.txt @@ -27,13 +27,10 @@ IF(SRSGUI_FOUND AND UHD_FOUND) add_executable(pss pss.c) - target_link_libraries(pss srslte ${SRSGUI_LIBRARIES}) - - add_executable(ue_rx ue_rx.c) - target_link_libraries(ue_rx srslte ${SRSGUI_LIBRARIES} pthread) + target_link_libraries(pss srslte ${SRSGUI_LIBRARIES} srslte_uhd) add_executable(simple_tx simple_tx.c) - target_link_libraries(simple_tx srslte) + target_link_libraries(simple_tx srslte srslte_uhd) ENDIF(SRSGUI_FOUND AND UHD_FOUND) diff --git a/srslte/examples/tutorial_examples/ue_rx.c b/srslte/examples/tutorial_examples/ue_rx.c deleted file mode 100644 index fb623ba02..000000000 --- a/srslte/examples/tutorial_examples/ue_rx.c +++ /dev/null @@ -1,629 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srslte/srslte.h" - - -#ifndef DISABLE_UHD -#include "srslte/cuhd/cuhd.h" -#include "cuhd_utils.h" - -cell_search_cfg_t cell_detect_config = { - 5000, - 100, // nof_frames_total - 10.0 // threshold -}; - -#endif - -//#define STDOUT_COMPACT - -#ifndef DISABLE_GRAPHICS -#include "srsgui/srsgui.h" -void init_plots(); -pthread_t plot_thread; -sem_t plot_sem; -uint32_t plot_sf_idx=0; -#endif - - -#define B210_DEFAULT_GAIN 40.0 -#define B210_DEFAULT_GAIN_CORREC 110.0 // Gain of the Rx chain when the gain is set to 40 - -float gain_offset = B210_DEFAULT_GAIN_CORREC; - - -/********************************************************************** - * Program arguments processing - ***********************************************************************/ -typedef struct { - int nof_subframes; - bool disable_plots; - int force_N_id_2; - bool enable_cfo; - int time_offset; - uint16_t rnti; - char *input_file_name; - uint32_t file_nof_prb; - char *uhd_args; - float uhd_freq; - float uhd_freq_offset; - float uhd_gain; - int net_port; - char *net_address; - int net_port_signal; - char *net_address_signal; -}prog_args_t; - -void args_default(prog_args_t *args) { - args->nof_subframes = -1; - args->rnti = SRSLTE_SIRNTI; - args->force_N_id_2 = -1; // Pick the best - args->input_file_name = NULL; - args->enable_cfo = true; - args->time_offset = 0; - args->file_nof_prb = 6; - args->uhd_args = ""; - args->uhd_freq = -1.0; - args->uhd_freq = 8000000.0; - args->uhd_gain = 60.0; - args->net_port = -1; - args->net_address = "127.0.0.1"; - args->net_port_signal = -1; - args->net_address_signal = "127.0.0.1"; -} - -void usage(prog_args_t *args, char *prog) { - printf("Usage: %s [agilcdnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); -#ifndef DISABLE_UHD - printf("\t-a UHD args [Default %s]\n", args->uhd_args); - printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain); - printf("\t-o UHD RX freq offset [Default %.1f MHz]\n", args->uhd_freq_offset/1000000); -#else - printf("\t UHD is disabled. CUHD library not available\n"); -#endif - printf("\t-i input_file [Default USRP]\n"); - printf("\t-p nof_prb for input file [Default %d]\n", args->file_nof_prb); - printf("\t-r RNTI [Default 0x%x]\n",args->rnti); - printf("\t-l Force N_id_2 [Default best]\n"); - printf("\t-c Disable CFO correction [Default %s]\n", args->enable_cfo?"Enabled":"Disabled"); - printf("\t-t Add time offset [Default %d]\n", args->time_offset); -#ifndef DISABLE_GRAPHICS - printf("\t-d disable plots [Default enabled]\n"); -#else - printf("\t plots are disabled. Graphics library not available\n"); -#endif - printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes); - printf("\t-s remote UDP port to send input signal (-1 does nothing with it) [Default %d]\n", args->net_port_signal); - printf("\t-S remote UDP address to send input signal [Default %s]\n", args->net_address_signal); - printf("\t-u remote TCP port to send data (-1 does nothing with it) [Default %d]\n", args->net_port); - printf("\t-U remote TCP address to send data [Default %s]\n", args->net_address); - printf("\t-v [set srslte_verbose to debug, default none]\n"); -} - -void parse_args(prog_args_t *args, int argc, char **argv) { - int opt; - args_default(args); - while ((opt = getopt(argc, argv, "aoglipdnvrfctuUsS")) != -1) { - switch (opt) { - case 'i': - args->input_file_name = argv[optind]; - break; - case 'p': - args->file_nof_prb = atoi(argv[optind]); - break; - case 'a': - args->uhd_args = argv[optind]; - break; - case 'g': - args->uhd_gain = atof(argv[optind]); - break; - case 'o': - args->uhd_freq_offset = atof(argv[optind]); - break; - case 'f': - args->uhd_freq = atof(argv[optind]); - break; - case 'n': - args->nof_subframes = atoi(argv[optind]); - break; - case 'c': - args->enable_cfo = false; - break; - case 't': - args->time_offset = atoi(argv[optind]); - break; - case 'r': - args->rnti = atoi(argv[optind]); - break; - case 'l': - args->force_N_id_2 = atoi(argv[optind]); - break; - case 'u': - args->net_port = atoi(argv[optind]); - break; - case 'U': - args->net_address = argv[optind]; - break; - case 's': - args->net_port_signal = atoi(argv[optind]); - break; - case 'S': - args->net_address_signal = argv[optind]; - break; - case 'd': - args->disable_plots = true; - break; - case 'v': - srslte_verbose++; - break; - default: - usage(args, argv[0]); - exit(-1); - } - } - if (args->uhd_freq < 0 && args->input_file_name == NULL) { - usage(args, argv[0]); - exit(-1); - } -} -/**********************************************************************/ - -/* TODO: Do something with the output data */ -uint8_t data[20000], data_packed[20000]; - -bool go_exit = false; - -void sig_int_handler(int signo) -{ - if (signo == SIGINT) { - go_exit = true; - } -} - -#ifndef DISABLE_UHD -int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv(h, data, nsamples, 1); -} -#endif - -extern float mean_exec_time; - -enum receiver_state { DECODE_MIB, DECODE_PDSCH} state; - -srslte_ue_dl_t ue_dl; -srslte_ue_sync_t ue_sync; -prog_args_t prog_args; - -uint32_t sfn = 0; // system frame number -cf_t *sf_buffer = NULL; -srslte_netsink_t net_sink, net_sink_signal; - -int main(int argc, char **argv) { - int ret; - srslte_cell_t cell; - int64_t sf_cnt; - srslte_ue_mib_t ue_mib; -#ifndef DISABLE_UHD - void *uhd; -#endif - uint32_t nof_trials = 0; - int n; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - uint32_t sfn_offset; - - parse_args(&prog_args, argc, argv); - - if (prog_args.net_port > 0) { - if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_TCP)) { - fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port); - exit(-1); - } - srslte_netsink_set_nonblocking(&net_sink); - } - if (prog_args.net_port_signal > 0) { - if (srslte_netsink_init(&net_sink_signal, prog_args.net_address_signal, prog_args.net_port_signal, SRSLTE_NETSINK_UDP)) { - fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address_signal, prog_args.net_port_signal); - exit(-1); - } - srslte_netsink_set_nonblocking(&net_sink_signal); - } - -#ifndef DISABLE_UHD - if (!prog_args.input_file_name) { - printf("Opening UHD device...\n"); - if (cuhd_open(prog_args.uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } - /* Set receiver gain */ - cuhd_set_rx_gain(uhd, prog_args.uhd_gain); - - /* set receiver frequency */ - cuhd_set_rx_freq_offset(uhd, (double) prog_args.uhd_freq, prog_args.uhd_freq_offset); - cuhd_rx_wait_lo_locked(uhd); - printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); - - ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell); - if (ret < 0) { - fprintf(stderr, "Error searching for cell\n"); - exit(-1); - } else if (ret == 0) { - printf("Cell not found\n"); - exit(0); - } - - /* set sampling frequency */ - int srate = srslte_sampling_freq_hz(cell.nof_prb); - if (srate != -1) { - cuhd_set_rx_srate(uhd, (double) srate); - } else { - fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb); - return SRSLTE_ERROR; - } - - INFO("Stopping UHD and flushing buffer...\r",0); - cuhd_stop_rx_stream(uhd); - cuhd_flush_buffer(uhd); - - if (srslte_ue_mib_init(&ue_mib, cell)) { - fprintf(stderr, "Error initaiting UE MIB decoder\n"); - exit(-1); - } - } -#endif - - /* If reading from file, go straight to PDSCH decoding. Otherwise, decode MIB first */ - if (prog_args.input_file_name) { - state = DECODE_PDSCH; - /* preset cell configuration */ - cell.id = 1; - cell.cp = SRSLTE_CP_NORM; - cell.phich_length = SRSLTE_PHICH_NORM; - cell.phich_resources = SRSLTE_PHICH_R_1; - cell.nof_ports = 1; - cell.nof_prb = prog_args.file_nof_prb; - - if (srslte_ue_sync_init_file(&ue_sync, prog_args.file_nof_prb, prog_args.input_file_name)) { - fprintf(stderr, "Error initiating ue_sync\n"); - exit(-1); - } - - } else { -#ifndef DISABLE_UHD - state = DECODE_MIB; - if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) { - fprintf(stderr, "Error initiating ue_sync\n"); - exit(-1); - } -#endif - } - - if (srslte_ue_dl_init(&ue_dl, cell)) { // This is the User RNTI - fprintf(stderr, "Error initiating UE downlink processing module\n"); - exit(-1); - } - - /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ - srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti); - - /* Initialize subframe counter */ - sf_cnt = 0; - - // Register Ctrl+C handler - signal(SIGINT, sig_int_handler); - -#ifndef DISABLE_GRAPHICS - if (!prog_args.disable_plots) { - init_plots(cell); - } -#endif - -#ifndef DISABLE_UHD - if (!prog_args.input_file_name) { - cuhd_start_rx_stream(uhd); - } -#endif - - // Variables for measurements - uint32_t nframes=0; - float rsrp=0.0, rsrq=0.0, snr=0.0; - bool decode_pdsch; - int pdcch_tx=0; - srslte_ra_dl_dci_t old_ra_dl; - bzero(&old_ra_dl, sizeof(srslte_ra_dl_dci_t)); - - ue_sync.correct_cfo = prog_args.enable_cfo; - - /* Main loop */ - while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { - - ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); - if (ret < 0) { - fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); - } - - /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ - if (ret == 1) { - switch (state) { - case DECODE_MIB: - if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { - srslte_pbch_decode_reset(&ue_mib.pbch); - n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); - if (n < 0) { - fprintf(stderr, "Error decoding UE MIB\n"); - exit(-1); - } else if (n == SRSLTE_UE_MIB_FOUND) { - srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); - srslte_cell_fprint(stdout, &cell, sfn); - printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); - sfn = (sfn + sfn_offset)%1024; - state = DECODE_PDSCH; - } - } - break; - case DECODE_PDSCH: - if (prog_args.rnti != SRSLTE_SIRNTI) { - decode_pdsch = true; - } else { - /* We are looking for SIB1 Blocks, search only in appropiate places */ - if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { - decode_pdsch = true; - } else { - decode_pdsch = false; - } - } - if (decode_pdsch) { - if (prog_args.rnti != SRSLTE_SIRNTI) { - n = srslte_ue_dl_decode(&ue_dl, &sf_buffer[prog_args.time_offset], data_packed, srslte_ue_sync_get_sfidx(&ue_sync)); - } else { - n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data_packed, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, - ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); - } - if (memcmp(&ue_dl.ra_dl, &old_ra_dl, sizeof(srslte_ra_dl_dci_t))) { - memcpy(&old_ra_dl, &ue_dl.ra_dl, sizeof(srslte_ra_dl_dci_t)); - fflush(stdout);printf("\nCFI:\t%d\n", ue_dl.cfi); - printf("Format: %s\n", srslte_dci_format_string(ue_dl.dci_format)); - srslte_ra_pdsch_fprint(stdout, &old_ra_dl, cell.nof_prb); - } - if (n < 0) { - // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); - } else if (n > 0) { - /* Send data if socket active */ - if (prog_args.net_port > 0) { - srslte_bit_unpack_vector(data_packed, data, n); - srslte_netsink_write(&net_sink, data, 1+(n-1)/8); - } - } - nof_trials++; - - rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.05); - rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&ue_dl.chest), rsrp, 0.05); - snr = SRSLTE_VEC_EMA(srslte_chest_dl_get_snr(&ue_dl.chest), snr, 0.01); - nframes++; - if (isnan(rsrq)) { - rsrq = 0; - } - if (isnan(snr)) { - snr = 0; - } - if (isnan(rsrp)) { - rsrp = 0; - } - -#ifdef adjust_estimator - /* Adjust channel estimator based on SNR */ - if (10*log10(snr) < 5.0) { - float f_low_snr[5]={0.05, 0.15, 0.6, 0.15, 0.05}; - srslte_chest_dl_set_filter_freq(&ue_dl.chest, f_low_snr, 5); - } else if (10*log10(snr) < 10.0) { - float f_mid_snr[3]={0.1, 0.8, 0.1}; - srslte_chest_dl_set_filter_freq(&ue_dl.chest, f_mid_snr, 3); - } else { - float f_high_snr[3]={0.05, 0.9, 0.05}; - srslte_chest_dl_set_filter_freq(&ue_dl.chest, f_high_snr, 3); - } -#endif - - } - if (srslte_ue_sync_get_sfidx(&ue_sync) != 5 && srslte_ue_sync_get_sfidx(&ue_sync) != 0) { - pdcch_tx++; - } - - - // Plot and Printf - if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { -#ifdef STDOUT_COMPACT - printf("SFN: %4d, PDCCH-Miss: %5.2f%% (%d missed), PDSCH-BLER: %5.2f%% (%d errors)\r", - sfn, 100*(1-(float) ue_dl.nof_detected/nof_trials),pdcch_tx-ue_dl.nof_detected, - (float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,ue_dl.pkt_errors); -#else - printf("CFO: %+6.2f KHz, SFO: %+6.2f Khz, " - "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, " - "PDCCH-Miss: %5.2f%% (%d), PDSCH-BLER: %5.2f%% (%d)\r", - srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, - 10*log10(rsrp*1000)-gain_offset, - 10*log10(rsrq), 10*log10(snr), - 100*(1-(float) ue_dl.nof_detected/nof_trials), pdcch_tx-ue_dl.nof_detected, - (float) 100*ue_dl.pkt_errors/ue_dl.pkts_total, ue_dl.pkt_errors); - -#endif - } - break; - } - if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) { - sfn++; - if (sfn == 1024) { - sfn = 0; - } - } - - #ifndef DISABLE_GRAPHICS - if (!prog_args.disable_plots) { - plot_sf_idx = srslte_ue_sync_get_sfidx(&ue_sync); - sem_post(&plot_sem); - } - #endif - } else if (ret == 0) { - printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", - srslte_sync_get_peak_value(&ue_sync.sfind), - ue_sync.frame_total_cnt, ue_sync.state); - } - - sf_cnt++; - } // Main loop - - srslte_ue_dl_free(&ue_dl); - srslte_ue_sync_free(&ue_sync); - -#ifndef DISABLE_UHD - if (!prog_args.input_file_name) { - srslte_ue_mib_free(&ue_mib); - cuhd_close(uhd); - } -#endif - printf("\nBye\n"); - exit(0); -} - - - - - - - - -/********************************************************************** - * Plotting Functions - ***********************************************************************/ -#ifndef DISABLE_GRAPHICS - - -plot_real_t poutfft; -plot_real_t pce_angle, pce; -plot_scatter_t pscatequal, pscatequal_pdcch; - -float tmp_plot[SRSLTE_SLOT_LEN_RE(SRSLTE_MAX_PRB, SRSLTE_CP_NORM)]; -float tmp_plot2[SRSLTE_SLOT_LEN_RE(SRSLTE_MAX_PRB, SRSLTE_CP_NORM)]; -float tmp_plot3[SRSLTE_SLOT_LEN_RE(SRSLTE_MAX_PRB, SRSLTE_CP_NORM)]; - -void *plot_thread_run(void *arg) { - int i; - uint32_t nof_re = SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp); - - while(1) { - sem_wait(&plot_sem); - - uint32_t nof_symbols = ue_dl.harq_process[0].dl_alloc.re_sf[plot_sf_idx]; - for (i = 0; i < nof_re; i++) { - tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); - if (isinf(tmp_plot[i])) { - tmp_plot[i] = -80; - } - } - for (i = 0; i < SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0); i++) { - tmp_plot2[i] = 20 * log10f(cabsf(ue_dl.chest.pilot_estimates_average[0][i])); - if (isinf(tmp_plot2[i])) { - tmp_plot2[i] = -80; - } - } - for (i = 0; i < SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0); i++) { - tmp_plot3[i] = cargf(ue_dl.chest.pilot_estimates_average[0][i]); - } - plot_real_setNewData(&poutfft, tmp_plot, nof_re); - plot_real_setNewData(&pce, tmp_plot2, SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0)); - plot_real_setNewData(&pce_angle, tmp_plot3, SRSLTE_REFSIGNAL_NUM_SF(ue_dl.cell.nof_prb,0)); - - plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d, nof_symbols); - plot_scatter_setNewData(&pscatequal_pdcch, ue_dl.pdcch.d, 36*ue_dl.pdcch.nof_cce); - - if (plot_sf_idx == 1) { - if (prog_args.net_port_signal > 0) { - srslte_netsink_write(&net_sink_signal, &sf_buffer[srslte_ue_sync_sf_len(&ue_sync)/7], - srslte_ue_sync_sf_len(&ue_sync)); - } - } - - } - - return NULL; -} - -void init_plots() { - - sdrgui_init(); - - plot_real_init(&poutfft); - plot_real_setTitle(&poutfft, "Output FFT - Magnitude"); - plot_real_setLabels(&poutfft, "Index", "dB"); - plot_real_setYAxisScale(&poutfft, -40, 40); - - plot_real_init(&pce); - plot_real_setTitle(&pce, "Channel Response - Magnitude"); - plot_real_setLabels(&pce, "Index", "dB"); - - plot_real_init(&pce_angle); - plot_real_setTitle(&pce_angle, "Channel Response - Argument"); - plot_real_setLabels(&pce_angle, "Index", "Radiants"); - plot_real_setYAxisScale(&pce_angle, -M_PI, M_PI); - - plot_scatter_init(&pscatequal); - plot_scatter_setTitle(&pscatequal, "PDSCH - Equalized Symbols"); - plot_scatter_setXAxisScale(&pscatequal, -2, 2); - plot_scatter_setYAxisScale(&pscatequal, -2, 2); - - plot_scatter_init(&pscatequal_pdcch); - plot_scatter_setTitle(&pscatequal_pdcch, "PDCCH - Equalized Symbols"); - plot_scatter_setXAxisScale(&pscatequal_pdcch, -2, 2); - plot_scatter_setYAxisScale(&pscatequal_pdcch, -2, 2); - - if (sem_init(&plot_sem, 0, 0)) { - perror("sem_init"); - exit(-1); - } - - if (pthread_create(&plot_thread, NULL, plot_thread_run, NULL)) { - perror("pthread_create"); - exit(-1); - } -} - -#endif diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index f76aaa303..1bd6cc2dc 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -120,6 +120,9 @@ SRSLTE_API int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, SRSLTE_API void srslte_dci_rar_grant_unpack(srslte_dci_rar_grant_t *rar, uint8_t grant[SRSLTE_RAR_GRANT_LEN]); +SRSLTE_API void srslte_dci_rar_grant_fprint(FILE *stream, + srslte_dci_rar_grant_t *rar); + SRSLTE_API srslte_dci_format_t srslte_dci_format_from_string(char *str); SRSLTE_API char* srslte_dci_format_string(srslte_dci_format_t format); diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index 7ce0d8b06..1bd38c370 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -44,11 +44,6 @@ IF(FFTW3F_FOUND) LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) ENDIF(FFTW3F_FOUND) -IF(UHD_FOUND) - INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS}) - LINK_DIRECTORIES(${UHD_LIBRARY_DIRS}) -ENDIF(UHD_FOUND) - IF(SRSGUI_FOUND) INCLUDE_DIRECTORIES(${SRSGUI_INCLUDE_DIRS}) LINK_DIRECTORIES(${SRSGUI_LIBRARY_DIRS}) @@ -62,20 +57,23 @@ FILE(GLOB modules *) SET(SOURCES_ALL "") FOREACH (_module ${modules}) IF(IS_DIRECTORY ${_module}) - IF ((NOT ${_module} MATCHES "cuhd") OR UHD_FOUND) + IF (NOT ${_module} MATCHES "cuhd") FILE(GLOB_RECURSE tmp "${_module}/src/*.c") LIST(APPEND SOURCES_ALL ${tmp}) FILE(GLOB_RECURSE tmp2 "${_module}/src/*.cpp") LIST(APPEND SOURCES_ALL ${tmp2}) - ENDIF ((NOT ${_module} MATCHES "cuhd") OR UHD_FOUND) + ENDIF (NOT ${_module} MATCHES "cuhd") ENDIF(IS_DIRECTORY ${_module}) ENDFOREACH() ADD_LIBRARY(srslte SHARED ${SOURCES_ALL}) - TARGET_LINK_LIBRARIES(srslte m ${FFTW3F_LIBRARIES}) + IF(UHD_FOUND) - TARGET_LINK_LIBRARIES(srslte ${UHD_LIBRARIES}) + INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS}) + LINK_DIRECTORIES(${UHD_LIBRARY_DIRS}) + ADD_LIBRARY(srslte_uhd SHARED ${CMAKE_CURRENT_SOURCE_DIR}/cuhd/src/cuhd_imp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cuhd/src/cuhd_utils.c) + TARGET_LINK_LIBRARIES(srslte_uhd ${UHD_LIBRARIES}) ENDIF(UHD_FOUND) INSTALL(TARGETS srslte DESTINATION ${LIBRARY_DIR}) diff --git a/srslte/lib/phch/src/dci.c b/srslte/lib/phch/src/dci.c index 05740f5b5..94071a709 100644 --- a/srslte/lib/phch/src/dci.c +++ b/srslte/lib/phch/src/dci.c @@ -152,6 +152,15 @@ void srslte_dci_rar_grant_unpack(srslte_dci_rar_grant_t *rar, uint8_t grant[SRSL rar->cqi_request = srslte_bit_unpack(&grant_ptr, 1)?true:false; } +void srslte_dci_rar_grant_fprint(FILE *stream, srslte_dci_rar_grant_t *rar) { + fprintf(stream, "RBA: %d, MCS: %d, TPC: %d, Hopping=%s, UL-Delay=%s, CQI=%s\n", + rar->rba, rar->trunc_mcs, rar->tpc_pusch, + rar->hopping_flag?"yes":"no", + rar->ul_delay?"yes":"no", + rar->cqi_request?"yes":"no" + ); +} + /* Creates the UL PUSCH resource allocation grant from a DCI format 0 message */ int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, srslte_cell_t cell, @@ -171,7 +180,6 @@ int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, srslte_cell_t cell, bzero(grant, sizeof(srslte_ra_ul_dci_t)); if (srslte_dci_msg_unpack_pusch(msg, ul_dci, cell.nof_prb)) { - fprintf(stderr, "Can't unpack PDSCH message\n"); return ret; } @@ -379,8 +387,7 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t return SRSLTE_ERROR; } if (*y++ != 0) { - fprintf(stderr, - "Invalid format differentiation field value. This is SRSLTE_DCI_FORMAT1A\n"); + INFO("DCI message is Format1A\n", 0); return SRSLTE_ERROR; } if (*y++ == 0) { @@ -633,7 +640,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 } if (*y++ != 1) { - fprintf(stderr, "Invalid format differentiation field value. This is SRSLTE_DCI_FORMAT0\n"); + INFO("DCI message is Format0\n", 0); return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/src/pdcch.c b/srslte/lib/phch/src/pdcch.c index 3bd64b911..62d5f20a4 100644 --- a/srslte/lib/phch/src/pdcch.c +++ b/srslte/lib/phch/src/pdcch.c @@ -215,7 +215,7 @@ uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, c[k].L = l; c[k].ncce = ncce; - INFO("UE-specific SS Candidate %d: nCCE: %d, L: %d\n", + DEBUG("UE-specific SS Candidate %d: nCCE: %d, L: %d\n", k, c[k].ncce, c[k].L); k++; @@ -223,7 +223,7 @@ uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, } } - INFO("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", k, rnti); + DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x\n", k, rnti); return k; } @@ -297,7 +297,7 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui x = &data[nof_bits]; p_bits = (uint16_t) srslte_bit_unpack(&x, 16); crc_res = ((uint16_t) srslte_crc_checksum(&q->crc, data, nof_bits) & 0xffff); - INFO("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res, + DEBUG("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res, p_bits ^ crc_res); if (crc) { @@ -331,7 +331,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci uint32_t nof_bits = srslte_dci_format_sizeof(format, q->cell.nof_prb); uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L); - INFO("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n", + DEBUG("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n", location->ncce * 72, e_bits, nof_bits, location->ncce, location->L); ret = dci_decode(q, &q->llr[location->ncce * 72], @@ -369,7 +369,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT nof_symbols = e_bits/2; ret = SRSLTE_ERROR; - INFO("Extracting LLRs: E: %d, SF: %d, CFI: %d\n", + DEBUG("Extracting LLRs: E: %d, SF: %d, CFI: %d\n", e_bits, nsubframe, cfi); /* number of layers equals number of ports */ @@ -427,7 +427,7 @@ static void crc_set_mask_rnti(uint8_t *crc, uint16_t rnti) { uint8_t mask[16]; uint8_t *r = mask; - INFO("Mask CRC with RNTI 0x%x\n", rnti); + DEBUG("Mask CRC with RNTI 0x%x\n", rnti); srslte_bit_pack(rnti, &r, 16); for (i = 0; i < 16; i++) { @@ -508,7 +508,7 @@ int srslte_pdcch_encode(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci_loc if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce && msg->nof_bits < SRSLTE_DCI_MAX_BITS) { - INFO("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", + DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", msg->nof_bits, e_bits, location.ncce, location.L, rnti); dci_encode(q, msg->data, q->e, msg->nof_bits, e_bits, rnti); diff --git a/srslte/lib/phch/src/prach.c b/srslte/lib/phch/src/prach.c index 3975f87be..e44b379d0 100644 --- a/srslte/lib/phch/src/prach.c +++ b/srslte/lib/phch/src/prach.c @@ -44,7 +44,7 @@ #define PHI_4 2 // PRACH phi parameter for format 4 #define MAX_ROOTS 838 // Max number of root sequences -#define PRACH_AMP 0.5 +#define PRACH_AMP 0.4 /****************************************************** * Reference tables from 3GPP TS 36.211 v10.7.0 @@ -346,6 +346,8 @@ int srslte_prach_init(srslte_prach_t *p, p->N_cs = prach_Ncs_unrestricted[p->zczc]; } } + + printf("N_cs=%d, ZCZC=%d\n", p->N_cs, p->zczc); // Set up containers p->prach_bins = srslte_vec_malloc(sizeof(cf_t)*p->N_zc); @@ -438,9 +440,10 @@ int srslte_prach_gen(srslte_prach_t *p, // Copy preamble sequence into buffer for(int i=0;iN_seq;i++){ - signal[p->N_cp+i] = PRACH_AMP*p->ifft_out[i%p->N_ifft_prach]; + signal[p->N_cp+i] = p->ifft_out[i%p->N_ifft_prach]; } - + srslte_vec_sc_prod_cfc(signal, PRACH_AMP, signal, p->N_cp + p->N_seq); + ret = SRSLTE_SUCCESS; } diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index e3e51321c..a6a4ec837 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -410,7 +410,6 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && - data != NULL && cfg != NULL) { if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) { diff --git a/srslte/lib/phch/src/regs.c b/srslte/lib/phch/src/regs.c index 6563a5a51..26f076041 100644 --- a/srslte/lib/phch/src/regs.c +++ b/srslte/lib/phch/src/regs.c @@ -308,7 +308,7 @@ int regs_phich_init(srslte_regs_t *h) { ni=((h->cell.id*n[li]/n[0])+mi+i*n[li]/3) % n[li]; // Step 8 h->phich[mi].regs[i] = regs_phich[li][ni]; h->phich[mi].regs[i]->assigned = true; - INFO("Assigned PHICH REG#%d (%d,%d)\n",nreg,h->phich[mi].regs[i]->k0,li); + DEBUG("Assigned PHICH REG#%d (%d,%d)\n",nreg,h->phich[mi].regs[i]->k0,li); nreg++; } } @@ -487,7 +487,7 @@ int regs_pcfich_init(srslte_regs_t *h) { return SRSLTE_ERROR; } else { ch->regs[i]->assigned = true; - INFO("Assigned PCFICH REG#%d (%d,0)\n", i, k); + DEBUG("Assigned PCFICH REG#%d (%d,0)\n", i, k); } } return SRSLTE_SUCCESS; diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index 195809d4b..9822dea97 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -169,7 +169,6 @@ static int encode_tb(srslte_sch_t *q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && - data != NULL && e_bits != NULL && cb_segm != NULL && soft_buffer != NULL) @@ -182,7 +181,7 @@ static int encode_tb(srslte_sch_t *q, gamma = Gp%cb_segm->C; } - if (rv == 0) { + if (data) { /* Compute transport block CRC */ par = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs); @@ -226,7 +225,7 @@ static int encode_tb(srslte_sch_t *q, INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, cb_len, rlen - F, wp, rp, F, n_e); - if (rv == 0) { + if (data) { /* Copy data to another buffer, making space for the Codeblock CRC */ if (i < cb_segm->C - 1) { diff --git a/srslte/lib/phch/test/prach_test_mex.c b/srslte/lib/phch/test/prach_test_mex.c index 59ba498e4..bb0cda68d 100644 --- a/srslte/lib/phch/test/prach_test_mex.c +++ b/srslte/lib/phch/test/prach_test_mex.c @@ -89,7 +89,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } - uint32_t nof_samples = srslte_sampling_freq_hz(n_ul_rb) * 0.003; + uint32_t nof_samples = srslte_sampling_freq_hz(n_ul_rb) * 0.001; cf_t *signal = srslte_vec_malloc(sizeof(cf_t) * nof_samples); if (!signal) { @@ -102,6 +102,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } + srslte_vec_sc_prod_cfc(signal, 1.0/sqrtf(N_ifft_ul), signal, prach.N_seq+prach.N_cp); if (nlhs >= 0) { mexutils_write_cf(signal, &plhs[0], nof_samples, 1); diff --git a/srslte/lib/sync/src/sync.c b/srslte/lib/sync/src/sync.c index 9aca3bb8d..4f1e325e5 100644 --- a/srslte/lib/sync/src/sync.c +++ b/srslte/lib/sync/src/sync.c @@ -242,7 +242,7 @@ int sync_sss(srslte_sync_t *q, cf_t *input, uint32_t peak_pos, srslte_cp_t cp) { /* Make sure we have enough room to find SSS sequence */ sss_idx = (int) peak_pos-2*q->fft_size-SRSLTE_CP_LEN(q->fft_size, (SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM_LEN:SRSLTE_CP_EXT_LEN)); if (sss_idx < 0) { - INFO("Not enough room to decode CP SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos); + DEBUG("Not enough room to decode CP SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos); return SRSLTE_ERROR; } DEBUG("Searching SSS around sss_idx: %d, peak_pos: %d\n", sss_idx, peak_pos); @@ -321,14 +321,14 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 /* compute cumulative moving average CFO */ q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, CFO_EMA_ALPHA); } else { - INFO("No space for CFO computation. Frame starts at \n",peak_pos); + DEBUG("No space for CFO computation. Frame starts at \n",peak_pos); } if (q->detect_cp) { if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { q->cp = srslte_sync_detect_cp(q, input, peak_pos + find_offset); } else { - INFO("Not enough room to detect CP length. Peak position: %d\n", peak_pos); + DEBUG("Not enough room to detect CP length. Peak position: %d\n", peak_pos); } } @@ -343,7 +343,7 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 q->N_id_1 = 1000; if (sync_sss(q, input, find_offset + peak_pos, q->cp) < 0) { - INFO("No space for SSS processing. Frame starts at %d\n", peak_pos); + DEBUG("No space for SSS processing. Frame starts at %d\n", peak_pos); } } // Return 1 (peak detected) even if we couldn't estimate CFO and SSS @@ -352,7 +352,7 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 ret = 0; } - INFO("SYNC ret=%d N_id_2=%d find_offset=%d pos=%d peak=%.2f threshold=%.2f sf_idx=%d, CFO=%.3f KHz\n", + DEBUG("SYNC ret=%d N_id_2=%d find_offset=%d pos=%d peak=%.2f threshold=%.2f sf_idx=%d, CFO=%.3f KHz\n", ret, q->N_id_2, find_offset, peak_pos, q->peak_value, q->threshold, q->sf_idx, 15*q->mean_cfo); } else if (srslte_N_id_2_isvalid(q->N_id_2)) { diff --git a/srslte/lib/sync/test/CMakeLists.txt b/srslte/lib/sync/test/CMakeLists.txt index 36efa2299..41499a37f 100644 --- a/srslte/lib/sync/test/CMakeLists.txt +++ b/srslte/lib/sync/test/CMakeLists.txt @@ -34,7 +34,7 @@ ENDIF(SRSGUI_FOUND) IF(UHD_FOUND) ADD_EXECUTABLE(pss_usrp pss_usrp.c) - TARGET_LINK_LIBRARIES(pss_usrp srslte) + TARGET_LINK_LIBRARIES(pss_usrp srslte srslte_uhd) IF(SRSGUI_FOUND) target_link_libraries(pss_usrp ${SRSGUI_LIBRARIES}) ELSE(SRSGUI_FOUND) diff --git a/srslte/lib/ue/src/ue_cell_search.c b/srslte/lib/ue/src/ue_cell_search.c index 6246f6ea8..bc00e9ea0 100644 --- a/srslte/lib/ue/src/ue_cell_search.c +++ b/srslte/lib/ue/src/ue_cell_search.c @@ -238,7 +238,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, uint32_t N_id_2 q->candidates[nof_detected_frames].peak = q->ue_sync.strack.pss.peak_value; q->candidates[nof_detected_frames].psr = srslte_sync_get_peak_value(&q->ue_sync.strack); q->candidates[nof_detected_frames].cfo = srslte_ue_sync_get_cfo(&q->ue_sync); - INFO + DEBUG ("CELL SEARCH: [%3d/%3d/%d]: Found peak PSR=%.3f, Cell_id: %d CP: %s\n", nof_detected_frames, nof_scanned_frames, q->nof_frames_to_scan, q->candidates[nof_detected_frames].psr, q->candidates[nof_detected_frames].cell_id, diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index c77d6b587..4b36522e8 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -253,7 +253,7 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } - INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem); + DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); } return crc_rem == rnti; } @@ -289,7 +289,7 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 fprintf(stderr, "Error decoding DCI msg\n"); return SRSLTE_ERROR; } - INFO("Decoded DCI message RNTI: 0x%x\n", crc_rem); + DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem); } } return crc_rem == rnti; diff --git a/srslte/lib/ue/src/ue_mib.c b/srslte/lib/ue/src/ue_mib.c index 69e42cf92..0e8acd330 100644 --- a/srslte/lib/ue/src/ue_mib.c +++ b/srslte/lib/ue/src/ue_mib.c @@ -152,7 +152,7 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, srslte_ue_mib_reset(q); ret = SRSLTE_UE_MIB_FOUND; } else { - INFO("MIB not decoded: %u\n", q->frame_cnt); + DEBUG("MIB not decoded: %u\n", q->frame_cnt); q->frame_cnt++; ret = SRSLTE_UE_MIB_NOTFOUND; } @@ -222,7 +222,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, if (ret == 1) { mib_ret = srslte_ue_mib_decode(&q->ue_mib, sf_buffer, bch_payload, nof_tx_ports, sfn_offset); } else { - INFO("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); + DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); srslte_ue_mib_reset(&q->ue_mib); } nof_frames++; diff --git a/srslte/lib/ue/src/ue_sync.c b/srslte/lib/ue/src/ue_sync.c index 784d0611b..c99cc086d 100644 --- a/srslte/lib/ue/src/ue_sync.c +++ b/srslte/lib/ue/src/ue_sync.c @@ -265,16 +265,16 @@ static int find_peak_ok(srslte_ue_sync_t *q) { /* Get the subframe index (0 or 5) */ q->sf_idx = srslte_sync_get_sf_idx(&q->sfind) + q->nof_recv_sf; } else { - INFO("Found peak at %d, SSS not detected\n", q->peak_idx); + DEBUG("Found peak at %d, SSS not detected\n", q->peak_idx); } q->frame_find_cnt++; - INFO("Found peak %d at %d, value %.3f, Cell_id: %d CP: %s\n", + DEBUG("Found peak %d at %d, value %.3f, Cell_id: %d CP: %s\n", q->frame_find_cnt, q->peak_idx, srslte_sync_get_last_peak_value(&q->sfind), q->cell.id, srslte_cp_string(q->cell.cp)); if (q->frame_find_cnt >= q->nof_avg_find_frames || q->peak_idx < 2*q->fft_size) { - INFO("Realigning frame, reading %d samples\n", q->peak_idx+q->sf_len/2); + DEBUG("Realigning frame, reading %d samples\n", q->peak_idx+q->sf_len/2); /* Receive the rest of the subframe so that we are subframe aligned*/ if (q->recv_callback(q->stream, q->input_buffer, q->peak_idx+q->sf_len/2, &q->last_timestamp) < 0) { return SRSLTE_ERROR; @@ -299,7 +299,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { /* Make sure subframe idx is what we expect */ if ((q->sf_idx != srslte_sync_get_sf_idx(&q->strack)) && q->decode_sss_on_track) { - INFO("Warning: Expected SF idx %d but got %d (%d,%g - %d,%g)!\n", + DEBUG("Warning: Expected SF idx %d but got %d (%d,%g - %d,%g)!\n", q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->strack.m0, q->strack.m0_value, q->strack.m1, q->strack.m1_value); q->sf_idx = srslte_sync_get_sf_idx(&q->strack); @@ -309,7 +309,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { q->time_offset = ((int) track_idx - (int) q->strack.frame_size/2 - (int) q->strack.fft_size); if (q->time_offset) { - INFO("Time offset adjustment: %d samples\n", q->time_offset); + DEBUG("Time offset adjustment: %d samples\n", q->time_offset); } /* compute cumulative moving average time offset */ @@ -318,7 +318,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { /* If the PSS peak is beyond the frame (we sample too slowly), discard the offseted samples to align next frame */ if (q->time_offset > 0 && q->time_offset < MAX_TIME_OFFSET) { - INFO("Positive time offset %d samples. Mean time offset %f.\n", q->time_offset, q->mean_time_offset); + DEBUG("Positive time offset %d samples. Mean time offset %f.\n", q->time_offset, q->mean_time_offset); if (q->recv_callback(q->stream, dummy, (uint32_t) q->time_offset, &q->last_timestamp) < 0) { fprintf(stderr, "Error receiving from USRP\n"); return SRSLTE_ERROR; @@ -338,10 +338,10 @@ static int track_peak_no(srslte_ue_sync_t *q) { /* if we missed too many PSS go back to FIND */ q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { - INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); + DEBUG("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); q->state = SF_FIND; } else { - INFO("Tracking peak not found. Peak %.3f, %d lost\n", + DEBUG("Tracking peak not found. Peak %.3f, %d lost\n", srslte_sync_get_last_peak_value(&q->strack), (int) q->frame_no_cnt); } @@ -398,7 +398,7 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { if (q->sf_idx == 10) { q->sf_idx = 0; } - INFO("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); + DEBUG("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); ret = 1; *sf_symbols = q->input_buffer; } else { diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index 849e93270..5f9151e1b 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -309,7 +309,6 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t * if (q != NULL && grant != NULL && - data != NULL && output_signal != NULL) { @@ -341,7 +340,6 @@ int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg, if (q != NULL && cfg != NULL && - data != NULL && output_signal != NULL) { if (srslte_pusch_encode_rnti(&q->pusch, cfg, &q->softbuffer, data, rnti, q->sf_symbols)) {