mirror of https://github.com/PentHertz/srsLTE.git
Working on mac_test
This commit is contained in:
parent
881a90d62c
commit
68d193a725
|
@ -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;
|
||||
cfo=-angle(mean(r))/pi;
|
|
@ -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')
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
[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));
|
||||
|
||||
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
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
#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
|
||||
|
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
#include "srsapps/common/log.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef MACPDU_H
|
||||
#define MACPDU_H
|
||||
|
||||
/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */
|
||||
|
||||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
|
||||
template<class SubH>
|
||||
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<max_subheaders;i++) {
|
||||
subheaders[i].parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void fprint(FILE *stream) {
|
||||
fprintf(stream, "Number of Subheaders: %d\n", nof_subheaders);
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
fprintf(stream, " -- Subheader %d: ", i);
|
||||
subheaders[i].fprint(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Resets the Read/Write position and remaining PDU length */
|
||||
void reset() {
|
||||
cur_idx = -1;
|
||||
rem_len = pdu_len;
|
||||
}
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
void init(uint32_t pdu_len_bytes) {
|
||||
init(pdu_len_bytes, false);
|
||||
}
|
||||
void init(uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
pdu_is_ul = is_ulsch;
|
||||
reset();
|
||||
for (int i=0;i<max_subheaders;i++) {
|
||||
subheaders[i].init();
|
||||
}
|
||||
}
|
||||
|
||||
bool new_subh() {
|
||||
if (nof_subheaders < max_subheaders - 1) {
|
||||
nof_subheaders++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool next() {
|
||||
if (cur_idx < nof_subheaders - 1) {
|
||||
cur_idx++;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SubH* get() {
|
||||
if (cur_idx >= 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<nof_subheaders;i++) {
|
||||
subheaders[i].read_payload(&ptr);
|
||||
}
|
||||
}
|
||||
bool is_ul() {
|
||||
return pdu_is_ul;
|
||||
}
|
||||
|
||||
virtual bool write_packet(uint8_t *ptr) = 0;
|
||||
|
||||
protected:
|
||||
std::vector<SubH> 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>
|
||||
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<SubH>* parent;
|
||||
|
||||
private:
|
||||
virtual void init() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class sch_subh : public subh<sch_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<sch_subh>
|
||||
{
|
||||
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<rar_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<rar_subh>
|
||||
{
|
||||
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
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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<mac_io::NOF_UL_LCH;i++) {
|
||||
// Add PRB unless it's infinity
|
||||
if (PBR[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;
|
||||
|
|
|
@ -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 <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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<rem_len;i++) {
|
||||
padding.write_subheader(&ptr, false);
|
||||
}
|
||||
rem_len = 0;
|
||||
}
|
||||
// Find last SDU or CE
|
||||
int last_sdu = nof_subheaders-1;
|
||||
while(!subheaders[last_sdu].is_sdu() && last_sdu >= 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<nof_subheaders;i++) {
|
||||
if (!subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_subheader(&ptr, i==last_sh);
|
||||
}
|
||||
}
|
||||
// Then for SDUs
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_subheader(&ptr, i==last_sh);
|
||||
}
|
||||
}
|
||||
// Write payloads in the same order
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (!subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t)*8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t sch_pdu::size_plus_header_pdu(uint32_t nbytes)
|
||||
{
|
||||
if (nbytes < 128) {
|
||||
return nbytes + 2;
|
||||
} else {
|
||||
return nbytes + 3;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::has_space_ce(uint32_t nbytes)
|
||||
{
|
||||
if (rem_len >= 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;i<nof_subheaders;i++) {
|
||||
subheaders[i].write_subheader(&ptr, i==nof_subheaders-1);
|
||||
}
|
||||
// Write payload
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t)*8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rar_subh::init()
|
||||
{
|
||||
bzero(grant, sizeof(uint8_t) * RAR_GRANT_LEN);
|
||||
ta = 0;
|
||||
temp_rnti = 0;
|
||||
}
|
||||
uint32_t rar_subh::get_rapid()
|
||||
{
|
||||
return preamble;
|
||||
}
|
||||
void rar_subh::get_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(grant_, &grant, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
uint32_t rar_subh::get_ta_cmd()
|
||||
{
|
||||
return ta;
|
||||
}
|
||||
uint16_t rar_subh::get_temp_crnti()
|
||||
{
|
||||
return temp_rnti;
|
||||
}
|
||||
void rar_subh::set_rapid(uint32_t rapid)
|
||||
{
|
||||
preamble = rapid;
|
||||
}
|
||||
void rar_subh::set_sched_grant(uint8_t grant_[RAR_GRANT_LEN])
|
||||
{
|
||||
memcpy(&grant, grant_, sizeof(uint8_t)*RAR_GRANT_LEN);
|
||||
}
|
||||
void rar_subh::set_ta_cmd(uint32_t ta_)
|
||||
{
|
||||
ta = ta_;
|
||||
}
|
||||
void rar_subh::set_temp_crnti(uint16_t temp_rnti_)
|
||||
{
|
||||
temp_rnti = temp_rnti_;
|
||||
}
|
||||
// Section 6.2.2
|
||||
void rar_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
srslte_bit_pack(is_last?1:0, ptr, 1); // E
|
||||
srslte_bit_pack(1, ptr, 1); // T
|
||||
srslte_bit_pack(preamble, ptr, 6); // RAPID
|
||||
}
|
||||
// Section 6.2.3
|
||||
void rar_subh::write_payload(uint8_t** ptr)
|
||||
{
|
||||
srslte_bit_pack(0, ptr, 1); // R
|
||||
srslte_bit_pack(ta, ptr, 11); // Timing Adv Cmd
|
||||
memcpy(*ptr, grant, 20*sizeof(uint8_t)); // UL grant
|
||||
*ptr += 20;
|
||||
srslte_bit_pack(temp_rnti, ptr, 16); // Temp C-RNTI
|
||||
}
|
||||
void rar_subh::read_payload(uint8_t** ptr)
|
||||
{
|
||||
*ptr += 1; // R
|
||||
ta = srslte_bit_unpack(ptr, 11); // Timing Adv Cmd
|
||||
memcpy(grant, *ptr, 20*sizeof(uint8_t)); // UL Grant
|
||||
*ptr += 20;
|
||||
temp_rnti = srslte_bit_unpack(ptr, 16); // Temp C-RNTI
|
||||
}
|
||||
bool rar_subh::read_subheader(uint8_t** ptr)
|
||||
{
|
||||
bool e_bit = srslte_bit_unpack(ptr, 1); // E
|
||||
bool type = srslte_bit_unpack(ptr, 1); // T
|
||||
if (type) {
|
||||
preamble = srslte_bit_unpack(ptr, 6); // RAPID
|
||||
} else {
|
||||
// Read Backoff
|
||||
*ptr += 2; // R, R
|
||||
((rar_pdu*)parent)->set_backoff((uint8_t) srslte_bit_unpack(ptr, 4));
|
||||
}
|
||||
return e_bit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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;i<NOF_HARQ_PROC;i++) {
|
||||
if (!proc[i].init(cell, max_payload_len, this)) {
|
||||
if (!proc[i].init(cell, this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -79,15 +79,16 @@ void ul_harq_entity::reset_ndi() {
|
|||
bool ul_harq_entity::is_sps(uint32_t pid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ul_harq_entity::run_tti(uint32_t tti, phy *phy_) {
|
||||
run_tti(tti, NULL, phy_);
|
||||
// Called with no UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, dl_buffer *dl_buffer, phy *phy_) {
|
||||
// TODO: Receive HARQ information from PHY (PHICH) and perform retransmissions
|
||||
}
|
||||
|
||||
// Implements Section 5.4.2.1
|
||||
// Called with UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
|
||||
{
|
||||
uint32_t pid = pidof(tti);
|
||||
proc[pid].tti = tti;
|
||||
last_retx_is_msg3 = false;
|
||||
|
||||
if (grant) {
|
||||
|
@ -148,10 +149,9 @@ static int rv_of_irv[4] = {0, 2, 3, 1};
|
|||
static int irv_of_rv[4] = {0, 3, 1, 2};
|
||||
|
||||
ul_harq_entity::ul_harq_process::ul_harq_process() : cur_grant(0) {
|
||||
payload = NULL;
|
||||
max_payload_len = 0;
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
is_initiated = false;
|
||||
is_grant_configured = false;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
}
|
||||
|
@ -160,7 +160,9 @@ void ul_harq_entity::ul_harq_process::reset() {
|
|||
current_irv = 0;
|
||||
is_grant_configured = false;
|
||||
bzero(&cur_grant, sizeof(ul_sched_grant));
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
if (is_initiated) {
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
}
|
||||
}
|
||||
bool ul_harq_entity::ul_harq_process::has_grant() {
|
||||
return is_grant_configured;
|
||||
|
@ -186,34 +188,31 @@ void ul_harq_entity::ul_harq_process::set_maxHARQ_Tx(uint32_t maxHARQ_Tx_, uint3
|
|||
maxHARQ_Msg3Tx = maxHARQ_Msg3Tx_;
|
||||
}
|
||||
|
||||
bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, uint32_t max_payload_len_, ul_harq_entity *parent) {
|
||||
max_payload_len = max_payload_len_;
|
||||
bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *parent) {
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
|
||||
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);
|
||||
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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#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
|
|
@ -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);
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;i<p->N_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue