mirror of https://github.com/PentHertz/srsLTE.git
MAC test working until ConnectionSetupComplete
This commit is contained in:
parent
8f40bb2f73
commit
4a909ef56c
|
@ -1,15 +1,15 @@
|
|||
ueConfig=struct('NCellID',1,'NULRB',6,'NSubframe',8,'RNTI',81,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',(1:4)','Modulation','QPSK','RV',0,'Shortened',0);
|
||||
ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',0,'RNTI',65,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',24,'Modulation','QPSK','RV',0,'Shortened',0);
|
||||
|
||||
subframe_rx=lteSCFDMADemodulate(ueConfig,x.*transpose(exp(-1i*2*pi*0.26*(1:length(x))/128)));
|
||||
TBS=72;
|
||||
cfo=1146;
|
||||
|
||||
subframe_rx=lteSCFDMADemodulate(ueConfig,x.*exp(-1i*2*pi*cfo/15000*transpose(1:length(x))/512));
|
||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||
pusch_rx=subframe_rx(idx);
|
||||
[hest, noiseest] = lteULChannelEstimate(ueConfig,puschConfig,subframe_rx);
|
||||
ce=hest(idx);
|
||||
[cws,symbols] = ltePUSCHDecode(ueConfig,puschConfig,pusch_rx,ce,noiseest);
|
||||
[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,88,cws);
|
||||
[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,TBS,cws);
|
||||
disp(blkcrc)
|
||||
subplot(1,2,1)
|
||||
scatter(real(symbols),imag(symbols))
|
||||
subplot(1,2,2)
|
||||
plot(angle(hest))
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
clear
|
||||
ueConfig=struct('NCellID',1,'NULRB',6,'NSubframe',1,'RNTI',18,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[1:4]','Modulation','QPSK','RV',0,'Shortened',0);
|
||||
ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',8,'RNTI',77,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',24,'Modulation','QAM16','RV',0,'Shortened',0);
|
||||
|
||||
addpath('../../debug/srslte/lib/phch/test')
|
||||
|
||||
TBs=0:13:211;
|
||||
cqilen=[0, 8, 17];
|
||||
mods={'QPSK','16QAM','64QAM'};
|
||||
TBs=336;
|
||||
cqilen=0;
|
||||
rvs=0;
|
||||
betas=[2.0 2.5 6.25];
|
||||
mods={'16QAM'};
|
||||
betas=0;
|
||||
subf=8;
|
||||
|
||||
trblkin=[0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
for i=1:length(TBs)
|
||||
for m=1:length(mods)
|
||||
|
@ -17,39 +19,46 @@ for i=1:length(TBs)
|
|||
for bri=1:length(betas)
|
||||
for back=1:length(betas)
|
||||
for c=1:length(cqilen)
|
||||
|
||||
trblkin=randi(2,TBs(i),1)-1;
|
||||
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
puschConfig.BetaCQI = betas(bcqi);
|
||||
puschConfig.BetaRI = betas(bri);
|
||||
puschConfig.BetaACK = betas(back);
|
||||
for s=1:length(subf)
|
||||
fprintf('Subf=%d, RV=%d\n', subf(s), rvs(r));
|
||||
%trblkin=randi(2,TBs(i),1)-1;
|
||||
ueConfig.NSubframe=subf(s);
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
puschConfig.BetaCQI = betas(bcqi);
|
||||
puschConfig.BetaRI = betas(bri);
|
||||
puschConfig.BetaACK = betas(back);
|
||||
|
||||
if (betas(bri)>0)
|
||||
ri_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ri_bit=[];
|
||||
end
|
||||
if (betas(back)>0)
|
||||
ack_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ack_bit=[];
|
||||
end
|
||||
|
||||
if (cqilen(c)>0 || TBs(i)>0)
|
||||
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]);
|
||||
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
|
||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||
subframe_mat = lteULResourceGrid(ueConfig);
|
||||
subframe_mat(idx)=cw_mat;
|
||||
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
|
||||
|
||||
[waveform_lib, subframe_lib, cwlib]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
|
||||
err=mean(abs(waveform-waveform_lib));
|
||||
if (err > 10^-6)
|
||||
disp(err)
|
||||
error('Error!');
|
||||
if (betas(bri)>0)
|
||||
ri_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ri_bit=[];
|
||||
end
|
||||
if (betas(back)>0)
|
||||
ack_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ack_bit=[];
|
||||
end
|
||||
|
||||
if (cqilen(c)>0 || TBs(i)>0)
|
||||
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
|
||||
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
|
||||
drs=ltePUSCHDRS(ueConfig,puschConfig);
|
||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||
drs_ind = ltePUSCHDRSIndices(ueConfig,puschConfig);
|
||||
subframe_mat = lteULResourceGrid(ueConfig);
|
||||
subframe_mat(idx)=cw_mat;
|
||||
subframe_mat(drs_ind)=drs;
|
||||
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
|
||||
plot(abs(x-waveform*sqrt(512)))
|
||||
|
||||
|
||||
% [waveform_lib, subframe_lib, cwlib]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
|
||||
% err=mean(abs(waveform-waveform_lib));
|
||||
% if (err > 10^-6)
|
||||
% disp(err)
|
||||
% error('Error!');
|
||||
% end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -60,10 +69,3 @@ for i=1:length(TBs)
|
|||
end
|
||||
end
|
||||
|
||||
if (length(TBs) == 1)
|
||||
%disp(info)
|
||||
%n=1:length(mat);
|
||||
%plot(abs(double(mat)-double(lib)))
|
||||
%plot(n,real(lib(n)),n,real(mat(n)))
|
||||
plot(abs(waveform_lib-waveform))
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ INSTALL(DIRECTORY include/
|
|||
)
|
||||
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_common SHARED ${SOURCES})
|
||||
ADD_LIBRARY(srsapps_common SHARED ${SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src/threads.c)
|
||||
INSTALL(TARGETS srsapps_common DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_common)
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg);
|
||||
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu);
|
||||
void threads_print_self();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 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 Lesser 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser 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 <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "srsapps/common/threads.h"
|
||||
|
||||
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg) {
|
||||
return threads_new_rt_cpu(thread, start_routine, arg, -1);
|
||||
}
|
||||
|
||||
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu) {
|
||||
bool ret = false;
|
||||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
|
||||
perror("pthread_attr_setinheritsched");
|
||||
}
|
||||
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
|
||||
perror("pthread_attr_setschedpolicy");
|
||||
}
|
||||
if (pthread_attr_setschedparam(&attr, ¶m)) {
|
||||
perror("pthread_attr_setschedparam");
|
||||
fprintf(stderr, "Error not enough privileges to set Scheduling priority\n");
|
||||
}
|
||||
if (cpu != -1) {
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET((size_t) cpu, &cpuset);
|
||||
if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset)) {
|
||||
perror("pthread_attr_setaffinity_np");
|
||||
}
|
||||
}
|
||||
if (pthread_create(thread, &attr, start_routine, arg)) {
|
||||
perror("pthread_create");
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void threads_print_self() {
|
||||
pthread_t thread;
|
||||
cpu_set_t cpuset;
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
const char *p;
|
||||
int s,j;
|
||||
|
||||
thread = pthread_self();
|
||||
|
||||
s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
|
||||
if (s != 0) {
|
||||
printf("error pthread_getaffinity_np: %s\n",strerror(s));
|
||||
}
|
||||
|
||||
printf("Set returned by pthread_getaffinity_np() contained:\n");
|
||||
for (j = 0; j < CPU_SETSIZE; j++) {
|
||||
if (CPU_ISSET(j, &cpuset)) {
|
||||
printf(" CPU %d\n", j);
|
||||
}
|
||||
}
|
||||
|
||||
s = pthread_getschedparam(thread, &policy, ¶m);
|
||||
if (s != 0) {
|
||||
printf("error pthread_getaffinity_np: %s\n", strerror(s));
|
||||
}
|
||||
|
||||
switch(policy) {
|
||||
case SCHED_FIFO:
|
||||
p = "SCHED_FIFO";
|
||||
break;
|
||||
case SCHED_RR:
|
||||
p = "SCHED_RR";
|
||||
break;
|
||||
default:
|
||||
p = "Other";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Sched policy is %s. Priority is %d\n",p,param.sched_priority);
|
||||
}
|
|
@ -140,6 +140,7 @@ private:
|
|||
|
||||
/* Functions for MAC Timers */
|
||||
timers timers_db;
|
||||
uint16_t phy_rnti;
|
||||
void setup_timers();
|
||||
void timeAlignmentTimerExpire();
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace ue {
|
|||
const static int NOF_UL_LCH = MAC_LCH_DTCH2_UL - MAC_LCH_CCCH_UL;
|
||||
|
||||
const static int DEFAULT_MSG_SZ = 8*1024; // 8 Kbytes
|
||||
const static int DEFAULT_NOF_MESSAGES = 8;
|
||||
const static int DEFAULT_NOF_MESSAGES = 64;
|
||||
|
||||
|
||||
qbuff* get(mac_lch_t ch) {
|
||||
|
|
|
@ -69,7 +69,8 @@ public:
|
|||
private:
|
||||
bool assemble_pdu(uint32_t pdu_sz);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, uint32_t *sdu_sz);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, bool *is_first);
|
||||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, uint32_t *sdu_sz, bool *is_first);
|
||||
|
||||
int64_t Bj[mac_io::NOF_UL_LCH];
|
||||
int PBR[mac_io::NOF_UL_LCH]; // -1 sets to infinity
|
||||
|
|
|
@ -86,6 +86,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t nof_subh() {
|
||||
return nof_subheaders;
|
||||
}
|
||||
|
||||
bool new_subh() {
|
||||
if (nof_subheaders < max_subheaders - 1) {
|
||||
nof_subheaders++;
|
||||
|
@ -103,6 +107,13 @@ public:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void del_subh() {
|
||||
if (cur_idx > 0 && nof_subheaders > 0) {
|
||||
cur_idx--;
|
||||
nof_subheaders--;
|
||||
}
|
||||
}
|
||||
|
||||
SubH* get() {
|
||||
if (cur_idx >= 0) {
|
||||
|
@ -196,8 +207,9 @@ public:
|
|||
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_sdu(uint32_t lcid, uint8_t *ptr, uint32_t nof_bytes, bool is_first);
|
||||
bool set_c_rnti(uint16_t crnti);
|
||||
bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format);
|
||||
bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format, bool update_size);
|
||||
bool set_con_res_id(uint64_t con_res_id);
|
||||
bool set_ta_cmd(uint8_t ta_cmd);
|
||||
bool set_phd(uint8_t phd);
|
||||
|
@ -228,13 +240,15 @@ public:
|
|||
bool write_packet(uint8_t *ptr);
|
||||
bool has_space_ce(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes, bool is_first);
|
||||
uint32_t size();
|
||||
uint32_t rem_size();
|
||||
static uint32_t size_plus_header_sdu(uint32_t nbytes);
|
||||
bool update_space_ce(uint32_t nbytes);
|
||||
bool update_space_sdu(uint32_t nbytes);
|
||||
bool update_space_sdu(uint32_t nbytes, bool is_first);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class rar_subh : public subh<rar_subh>
|
||||
|
|
|
@ -65,12 +65,14 @@ public:
|
|||
uint32_t buff_size[4];
|
||||
} bsr_t;
|
||||
|
||||
bool need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t nof_padding_bytes, bsr_t *bsr);
|
||||
uint32_t need_to_send_bsr_on_ul_grant(uint32_t grant_size);
|
||||
bool generate_bsr_on_ul_grant(uint32_t nof_padding_bytes, bsr_t *bsr);
|
||||
bool need_to_send_sr();
|
||||
bool need_to_reset_sr();
|
||||
|
||||
private:
|
||||
|
||||
bool is_pending_sr;
|
||||
bool reset_sr;
|
||||
mac_params *params_db;
|
||||
mac_io *mac_io_h;
|
||||
timers *timers_db;
|
||||
|
@ -78,19 +80,21 @@ private:
|
|||
bool initiated;
|
||||
const static int MAX_LCID = 20;
|
||||
int lcg[MAX_LCID];
|
||||
uint32_t last_pending_data[MAX_LCID];
|
||||
int priorities[MAX_LCID];
|
||||
uint32_t find_max_priority_lcid();
|
||||
enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type;
|
||||
typedef enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type_t;
|
||||
triggered_bsr_type_t triggered_bsr_type;
|
||||
bool timer_periodic;
|
||||
bool timer_retx;
|
||||
|
||||
bsr_t pending_bsr;
|
||||
bool sr_is_sent;
|
||||
bool check_all_channels();
|
||||
void update_pending_data();
|
||||
bool check_highest_channel();
|
||||
bool check_single_channel();
|
||||
void get_pending_bsr_format(uint32_t nof_padding_bytes);
|
||||
|
||||
bool generate_bsr(bsr_t *bsr, uint32_t nof_padding_bytes);
|
||||
char* bsr_type_tostring(triggered_bsr_type_t type);
|
||||
char* bsr_format_tostring(bsr_format_t format);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
phy *phy_h;
|
||||
log *log_h;
|
||||
bool initiated;
|
||||
bool do_ra;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,19 +92,19 @@ void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits)
|
|||
// Unpack DLSCH MAC PDU
|
||||
pending_mac_msg.init(nof_bits/8);
|
||||
pending_mac_msg.parse_packet(mac_pdu);
|
||||
pending_mac_msg.fprint(stdout);
|
||||
//pending_mac_msg.fprint(stdout);
|
||||
|
||||
// Look for Contention Resolution UE 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();
|
||||
has_pending_contention_resolution_id = true;
|
||||
Info("Found Contention Resolution ID CE\n");
|
||||
Debug("Found Contention Resolution ID CE\n");
|
||||
}
|
||||
}
|
||||
pending_mac_msg.reset();
|
||||
pending_temp_rnti = true;
|
||||
Info("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
} else {
|
||||
Warning("Error pushing PDU with Temporal C-RNTI: Another PDU is still in pending\n");
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ void demux::process_pdu(sch_pdu *pdu_msg)
|
|||
qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid());
|
||||
if (dest_lch) {
|
||||
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",
|
||||
Info("Sent MAC SDU len=%d bytes to lchid=%d\n",
|
||||
pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid());
|
||||
} else {
|
||||
Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid());
|
||||
|
|
|
@ -178,7 +178,7 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
|
|||
}
|
||||
}
|
||||
|
||||
Info("DL PID %d: TBS=%d, RV=%d, MCS=%d, crc=%s\n", pid, cur_grant.get_tbs(), cur_grant.get_rv(), cur_grant.get_mcs(), ack?"OK":"NOK");
|
||||
Info("DL PID %d: TBS=%d, RV=%d, MCS=%d, crc=%s, PHY TTI: %d\n", pid, cur_grant.get_tbs(), cur_grant.get_rv(), cur_grant.get_mcs(), ack?"OK":"NOK", phy_h->get_current_tti());
|
||||
|
||||
}
|
||||
// Implement 5.3.2.2
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "srsapps/common/threads.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/mac/mac.h"
|
||||
|
@ -47,7 +48,8 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
|
|||
tti = 0;
|
||||
is_synchronized = false;
|
||||
last_temporal_crnti = 0;
|
||||
|
||||
phy_rnti = 0;
|
||||
|
||||
bsr_procedure.init(log_h, &timers_db, ¶ms_db, &mac_io_lch);
|
||||
mux_unit.init(log_h, &mac_io_lch, &bsr_procedure);
|
||||
demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db);
|
||||
|
@ -55,18 +57,10 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
|
|||
sr_procedure.init(log_h, ¶ms_db, phy_h);
|
||||
reset();
|
||||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = sched_get_priority_min(SCHED_FIFO) ;
|
||||
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");
|
||||
if (threads_new_rt(&mac_thread, mac_thread_fnc, this)) {
|
||||
started = true;
|
||||
}
|
||||
|
||||
return started;
|
||||
}
|
||||
|
||||
|
@ -179,14 +173,18 @@ void mac::main_radio_loop() {
|
|||
// Check if BSR procedure need to start SR
|
||||
|
||||
if (bsr_procedure.need_to_send_sr()) {
|
||||
Info("Starting SR procedure by BSR request\n");
|
||||
Info("Starting SR procedure by BSR request, PHY TTI=%d\n", phy_h->get_current_tti());
|
||||
sr_procedure.start();
|
||||
} else if (bsr_procedure.need_to_reset_sr()) {
|
||||
Info("Resetting SR procedure by BSR request\n");
|
||||
sr_procedure.reset();
|
||||
}
|
||||
sr_procedure.step(tti);
|
||||
|
||||
// Check SR if we need to start RA
|
||||
if (sr_procedure.need_random_access()) {
|
||||
ra_procedure.start_mac_order();
|
||||
Info("Starting RA procedure by MAC order\n");
|
||||
//ra_procedure.start_mac_order();
|
||||
}
|
||||
|
||||
ra_procedure.step(tti);
|
||||
|
@ -197,23 +195,21 @@ void mac::main_radio_loop() {
|
|||
|
||||
// Process DL grants always
|
||||
process_dl_grants(tti);
|
||||
|
||||
// Process UL grants if RA procedure is done and we have pending data or in contention resolution
|
||||
if (ra_procedure.is_contention_resolution() ||
|
||||
ra_procedure.is_successful() && mux_unit.is_pending_ccch_sdu())
|
||||
{
|
||||
process_ul_grants(tti);
|
||||
}
|
||||
|
||||
|
||||
// Send pending HARQ ACK, if any, and contention resolution is resolved
|
||||
if (dl_harq.is_ack_pending_resolution()) {
|
||||
ra_procedure.step(tti);
|
||||
if (ra_procedure.is_successful() || ra_procedure.is_response_error()) {
|
||||
Info("Sending pending ACK for contention resolution\n");
|
||||
Info("Sending pending ACK for contention resolution PHY TTI: %d\n", phy_h->get_current_tti());
|
||||
dl_harq.send_pending_ack_contention_resolution();
|
||||
}
|
||||
}
|
||||
|
||||
// Process UL grants if RA procedure is done and we have pending data or in contention resolution
|
||||
if (ra_procedure.is_contention_resolution() || ra_procedure.is_successful()) {
|
||||
process_ul_grants(tti);
|
||||
}
|
||||
|
||||
timers_db.step_all();
|
||||
|
||||
// Check if there is pending CCCH SDU in Multiplexing Unit
|
||||
|
@ -223,7 +219,17 @@ void mac::main_radio_loop() {
|
|||
Info("Starting RA procedure by RLC order\n");
|
||||
ra_procedure.start_rlc_order();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ra_procedure.is_successful() && phy_rnti != params_db.get_param(mac_params::RNTI_C) && params_db.get_param(mac_params::RNTI_C) > 0) {
|
||||
phy_rnti = params_db.get_param(mac_params::RNTI_C);
|
||||
Info("Setting PHY RNTI=%d\n", phy_rnti);
|
||||
|
||||
// This operation takes a while, do nothing for the rest 100 slots to re-align with PHY
|
||||
phy_h->set_crnti(phy_rnti);
|
||||
for (int i=0;i<100;i++) {
|
||||
tti = ttisync->wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,7 +481,7 @@ int mac::recv_dtch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
|||
|
||||
int mac::recv_dcch0_sdu(uint8_t* sdu_payload, uint32_t buffer_len_nbytes)
|
||||
{
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DTCH0_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
return mac_io_lch.get(mac_io::MAC_LCH_DCCH0_DL)->recv(sdu_payload, buffer_len_nbytes);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -211,7 +211,8 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
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)) {
|
||||
bool is_first = true;
|
||||
if (!allocate_sdu(UL_IDX(mac_io::MAC_LCH_CCCH_UL), &pdu_msg, &is_first)) {
|
||||
if (pending_crnti_ce) {
|
||||
if (pdu_msg.new_subh()) {
|
||||
pdu_msg.next();
|
||||
|
@ -223,15 +224,19 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
}
|
||||
pending_crnti_ce = 0;
|
||||
|
||||
uint32_t bsr_payload_sz = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_msg.rem_size());
|
||||
bsr_proc::bsr_t bsr;
|
||||
bool send_bsr_normal = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_sz_nbits/8, 0, &bsr);
|
||||
|
||||
// MAC control element for BSR, with exception of BSR included for padding;
|
||||
if (send_bsr_normal) {
|
||||
pdu_msg.next();
|
||||
pdu_msg.get()->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format));
|
||||
sch_subh *bsr_subh = NULL;
|
||||
if (bsr_payload_sz) {
|
||||
Info("Including BSR CE size %d\n", bsr_payload_sz);
|
||||
if (pdu_msg.new_subh()) {
|
||||
pdu_msg.next();
|
||||
bsr_subh = pdu_msg.get();
|
||||
pdu_msg.update_space_ce(bsr_payload_sz);
|
||||
}
|
||||
}
|
||||
|
||||
// MAC control element for PHR
|
||||
// TODO
|
||||
|
||||
|
@ -240,23 +245,30 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
bool res = true;
|
||||
while ((Bj[i] > 0 || PBR[i] < 0) && res) {
|
||||
res = allocate_sdu(lchid_sorted[i], &pdu_msg, &sdu_sz);
|
||||
res = allocate_sdu(lchid_sorted[i], &pdu_msg, &sdu_sz, &is_first);
|
||||
if (res && PBR[i] >= 0) {
|
||||
Bj[i] -= sdu_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If resources remain, allocate regardless of their Bj value
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
|
||||
while (allocate_sdu(lchid_sorted[i], &pdu_msg));
|
||||
}
|
||||
|
||||
// MAC control element for BSR included for padding.
|
||||
bool send_bsr_padding = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_sz_nbits/8, pdu_msg.rem_size(), &bsr);
|
||||
if (send_bsr_padding) {
|
||||
pdu_msg.next();
|
||||
pdu_msg.get()->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format));
|
||||
|
||||
bool send_bsr = bsr_procedure->generate_bsr_on_ul_grant(pdu_msg.rem_size(), &bsr);
|
||||
// Insert Padding BSR if not inserted Regular/Periodic BSR
|
||||
if (!bsr_payload_sz && send_bsr) {
|
||||
if (pdu_msg.new_subh()) {
|
||||
pdu_msg.next();
|
||||
bsr_subh = pdu_msg.get();
|
||||
}
|
||||
}
|
||||
|
||||
// And set the BSR
|
||||
if (bsr_subh) {
|
||||
bsr_subh->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format), bsr_payload_sz?false:true);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
@ -269,7 +281,9 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
}
|
||||
}
|
||||
|
||||
Info("Assembled MAC PDU msg size %d bytes\n", pdu_msg.size());
|
||||
Info("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.size(), pdu_sz_nbits/8);
|
||||
pdu_msg.fprint(stdout);
|
||||
|
||||
/* Generate MAC PDU and save to buffer */
|
||||
if (pdu_msg.write_packet(buff)) {
|
||||
pdu_buff.push(pdu_sz_nbits);
|
||||
|
@ -282,25 +296,34 @@ bool mux::assemble_pdu(uint32_t pdu_sz_nbits) {
|
|||
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg)
|
||||
{
|
||||
return allocate_sdu(lcid, pdu_msg, NULL);
|
||||
return allocate_sdu(lcid, pdu_msg, NULL, NULL);
|
||||
}
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz)
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, bool *is_first)
|
||||
{
|
||||
return allocate_sdu(lcid, pdu_msg, NULL, is_first);
|
||||
}
|
||||
bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, uint32_t *sdu_sz, bool *is_first)
|
||||
{
|
||||
|
||||
// Get n-th pending SDU pointer and length
|
||||
uint32_t buff_len;
|
||||
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 (buff_ptr && buff_len > 0) { // there is pending SDU to allocate
|
||||
if (sdu_sz) {
|
||||
*sdu_sz = buff_len;
|
||||
}
|
||||
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
|
||||
if (pdu_msg->get()->set_sdu(lcid, buff_ptr, buff_len/8, is_first?*is_first:false)) { // new SDU could be added
|
||||
if (is_first) {
|
||||
*is_first = false;
|
||||
}
|
||||
// Increase number of pop'ed packets from queue
|
||||
nof_tx_pkts[lcid]++;
|
||||
return true;
|
||||
} else {
|
||||
pdu_msg->del_subh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,15 +353,17 @@ uint8_t* mux::msg3_pop(uint32_t TB_size)
|
|||
{
|
||||
uint32_t len;
|
||||
uint8_t *msg3 = (uint8_t*) msg3_buff.pop(&len);
|
||||
if (len < TB_size) {
|
||||
// Pad with zeros without exceeding maximum buffer size
|
||||
if (TB_size <= MSG3_BUFF_SZ) {
|
||||
bzero(&msg3[len], (TB_size-len)*sizeof(uint8_t));
|
||||
} else {
|
||||
Error("Requested TB size from Msg3 buffer exceeds buffer size (%d>%d)\n", TB_size, MSG3_BUFF_SZ);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (msg3) {
|
||||
if (len < TB_size) {
|
||||
// Pad with zeros without exceeding maximum buffer size
|
||||
if (TB_size <= MSG3_BUFF_SZ) {
|
||||
bzero(&msg3[len], (TB_size-len)*sizeof(uint8_t));
|
||||
} else {
|
||||
Error("Requested TB size from Msg3 buffer exceeds buffer size (%d>%d)\n", TB_size, MSG3_BUFF_SZ);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg3;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,19 +47,41 @@ 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: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
if (parent->is_ul()) {
|
||||
switch(lcid) {
|
||||
case C_RNTI:
|
||||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
break;
|
||||
case PHD_REPORT:
|
||||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
break;
|
||||
case TRUNC_BSR:
|
||||
fprintf(stream, "Truncated BSR CE\n");
|
||||
break;
|
||||
case SHORT_BSR:
|
||||
fprintf(stream, "Short BSR CE\n");
|
||||
break;
|
||||
case LONG_BSR:
|
||||
fprintf(stream, "Long BSR CE\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
} else {
|
||||
switch(lcid) {
|
||||
case CON_RES_ID:
|
||||
fprintf(stream, "Contention Resolution ID CE: 0x%lx\n", get_con_res_id());
|
||||
break;
|
||||
case TA_CMD:
|
||||
fprintf(stream, "Time Advance Command CE: %d\n", get_ta_cmd());
|
||||
break;
|
||||
case DRX_CMD:
|
||||
fprintf(stream, "DRX Command CE: Not implemented\n");
|
||||
break;
|
||||
case PADDING:
|
||||
fprintf(stream, "PADDING\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,32 +108,38 @@ bool sch_pdu::write_packet(uint8_t* ptr)
|
|||
{
|
||||
uint8_t *init_ptr = ptr;
|
||||
bool last_is_padding = false;
|
||||
// Add multi-byte padding if necessary
|
||||
if (rem_len > 2) {
|
||||
last_is_padding = true;
|
||||
}
|
||||
// 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_sh;
|
||||
if (!last_is_padding) {
|
||||
// Find last SDU or CE
|
||||
int last_sdu = nof_subheaders-1;
|
||||
while(!subheaders[last_sdu].is_sdu() && last_sdu >= 0) {
|
||||
last_sdu--;
|
||||
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--;
|
||||
}
|
||||
last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
|
||||
|
||||
// Add multi-byte padding if there are more than 2 bytes or there are 2 bytes
|
||||
// and there is at least one SDU
|
||||
if (rem_len > 2 || (rem_len==2 && subheaders[last_sdu].is_sdu())) {
|
||||
last_is_padding = true;
|
||||
} else if (rem_len > 0) {
|
||||
if (subheaders[last_sdu].is_sdu()) {
|
||||
rem_len++;
|
||||
}
|
||||
int last_ce = nof_subheaders-1;
|
||||
while(subheaders[last_ce].is_sdu() && last_ce >= 0) {
|
||||
last_ce--;
|
||||
}
|
||||
last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
if (last_is_padding) {
|
||||
last_sh = -1;
|
||||
}
|
||||
// Write subheaders for MAC CE first
|
||||
|
@ -172,9 +200,16 @@ bool sch_pdu::has_space_ce(uint32_t nbytes)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sch_pdu::has_space_sdu(uint32_t nbytes)
|
||||
{
|
||||
if (rem_len >= size_plus_header_sdu(nbytes)) {
|
||||
return has_space_sdu(nbytes, false);
|
||||
}
|
||||
|
||||
bool sch_pdu::has_space_sdu(uint32_t nbytes, bool is_first)
|
||||
{
|
||||
uint32_t sizeh_first=is_first?1:0;
|
||||
if (rem_len >= size_plus_header_sdu(nbytes)-sizeh_first) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -186,10 +221,15 @@ bool sch_pdu::update_space_ce(uint32_t nbytes)
|
|||
rem_len -= nbytes + 1;
|
||||
}
|
||||
}
|
||||
bool sch_pdu::update_space_sdu(uint32_t nbytes)
|
||||
bool sch_pdu::update_space_sdu(uint32_t nbytes) {
|
||||
return update_space_sdu(nbytes, false);
|
||||
}
|
||||
|
||||
bool sch_pdu::update_space_sdu(uint32_t nbytes, bool is_first)
|
||||
{
|
||||
if (has_space_sdu(nbytes)) {
|
||||
rem_len -= size_plus_header_sdu(nbytes);
|
||||
uint32_t sizeh_first=is_first?1:0;
|
||||
if (has_space_sdu(nbytes, is_first)) {
|
||||
rem_len -= (size_plus_header_sdu(nbytes)-sizeh_first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +345,7 @@ void sch_subh::set_padding()
|
|||
}
|
||||
|
||||
|
||||
bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
||||
bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format, bool update_size)
|
||||
{
|
||||
uint32_t nonzero_lcg=0;
|
||||
for (int i=0;i<4;i++) {
|
||||
|
@ -314,18 +354,22 @@ bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
|||
}
|
||||
}
|
||||
uint32_t ce_size = format==LONG_BSR?3:1;
|
||||
if (((sch_pdu*)parent)->has_space_ce(ce_size)) {
|
||||
if (((sch_pdu*)parent)->has_space_ce(ce_size) || !update_size) {
|
||||
uint8_t *ptr = ce_payload;
|
||||
if (format==LONG_BSR) {
|
||||
bzero(ce_payload, 3*8*sizeof(uint8_t));
|
||||
for (int i=0;i<4;i++) {
|
||||
srslte_bit_pack(buff_size_table(buff_size[i]), &ptr, 6);
|
||||
}
|
||||
} else {
|
||||
bzero(ce_payload, 8*sizeof(uint8_t));
|
||||
srslte_bit_pack(nonzero_lcg, &ptr, 2);
|
||||
srslte_bit_pack(buff_size_table(buff_size[nonzero_lcg]), &ptr, 6);
|
||||
}
|
||||
lcid = format;
|
||||
((sch_pdu*)parent)->update_space_ce(ce_size);
|
||||
if (update_size) {
|
||||
((sch_pdu*)parent)->update_space_ce(ce_size);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -371,13 +415,19 @@ bool sch_subh::set_phd(uint8_t phd)
|
|||
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_)) {
|
||||
return set_sdu(lcid_, ptr, nof_bytes_, false);
|
||||
}
|
||||
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint8_t* ptr, uint32_t nof_bytes_, bool is_first)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_, is_first)) {
|
||||
sdu_payload_ptr = ptr;
|
||||
nof_bytes = nof_bytes_;
|
||||
lcid = lcid_;
|
||||
((sch_pdu*)parent)->update_space_sdu(nof_bytes_);
|
||||
((sch_pdu*)parent)->update_space_sdu(nof_bytes_, is_first);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -423,6 +473,7 @@ void sch_subh::write_payload(uint8_t** ptr)
|
|||
if (is_sdu()) {
|
||||
src = sdu_payload_ptr;
|
||||
} else {
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
src = ce_payload;
|
||||
}
|
||||
memcpy(*ptr, src, nof_bytes*8*sizeof(uint8_t));
|
||||
|
@ -618,7 +669,7 @@ uint8_t sch_subh::buff_size_table(uint32_t buffer_size) {
|
|||
return 63;
|
||||
} else {
|
||||
for (int i=0;i<61;i++) {
|
||||
if (buffer_size > btable[i]) {
|
||||
if (buffer_size < btable[i]) {
|
||||
return 1+i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,11 @@ bsr_proc::bsr_proc()
|
|||
initiated = false;
|
||||
timer_periodic = false;
|
||||
timer_retx = false;
|
||||
reset_sr = false;
|
||||
for (int i=0;i<MAX_LCID;i++) {
|
||||
lcg[i] = -1;
|
||||
priorities[i] = -1;
|
||||
last_pending_data[i] = 0;
|
||||
}
|
||||
triggered_bsr_type=NONE;
|
||||
}
|
||||
|
@ -65,53 +67,50 @@ void bsr_proc::timer_expired(uint32_t timer_id) {
|
|||
case mac::BSR_TIMER_PERIODIC:
|
||||
if (triggered_bsr_type == NONE) {
|
||||
// Check condition 4 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
triggered_bsr_type = PERIODIC;
|
||||
Info("BSR set to PERIODIC\n");
|
||||
}
|
||||
//triggered_bsr_type = PERIODIC;
|
||||
Info("BSR PERIODIC disabled\n");
|
||||
}
|
||||
break;
|
||||
case mac::BSR_TIMER_RETX:
|
||||
// Check condition 3 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
Info("BSR set to REGULAR RETX\n");
|
||||
triggered_bsr_type = REGULAR;
|
||||
sr_is_sent = false; // Enable reTx of SR
|
||||
}
|
||||
// Enable reTx of SR
|
||||
//triggered_bsr_type = REGULAR;
|
||||
Info("BSR reTX disabled\n");
|
||||
sr_is_sent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if data is available for a a channel with higher priority than others
|
||||
bool bsr_proc::check_highest_channel() {
|
||||
uint32_t pending_data = 0;
|
||||
uint32_t pending_data_lcid = 0;
|
||||
int pending_data_lcid = -1;
|
||||
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH && !pending_data;i++) {
|
||||
for (int i=0;i<mac_io::NOF_UL_LCH && pending_data_lcid == -1;i++) {
|
||||
if (lcg[i] >= 0) {
|
||||
pending_data = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
if (pending_data > 0) {
|
||||
if (!mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->isempty()) {
|
||||
pending_data_lcid = i;
|
||||
for (int j=0;j<mac_io::NOF_UL_LCH;j++) {
|
||||
if (!mac_io_h->get(j+mac_io::MAC_LCH_CCCH_UL)->isempty()) {
|
||||
if (priorities[j] > priorities[i]) {
|
||||
pending_data = 0;
|
||||
pending_data_lcid = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pending_data) {
|
||||
pending_bsr.buff_size[lcg[pending_data_lcid]] = pending_data;
|
||||
if (triggered_bsr_type != REGULAR) {
|
||||
Info("Triggered REGULAR BSR for Max Priority LCID=%d\n", pending_data_lcid);
|
||||
}
|
||||
triggered_bsr_type = REGULAR;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
if (pending_data_lcid >= 0) {
|
||||
// If there is new data available for this logical channel
|
||||
uint32_t nbytes = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
if (nbytes > last_pending_data[pending_data_lcid])
|
||||
{
|
||||
if (triggered_bsr_type != REGULAR) {
|
||||
Info("Triggered REGULAR BSR for Max Priority LCID=%d\n", pending_data_lcid);
|
||||
}
|
||||
triggered_bsr_type = REGULAR;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if only one logical channel has data avaiable for Tx
|
||||
|
@ -128,61 +127,62 @@ bool bsr_proc::check_single_channel() {
|
|||
}
|
||||
}
|
||||
if (nof_nonzero_lcid == 1) {
|
||||
pending_bsr.buff_size[lcg[pending_data_lcid]] = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
triggered_bsr_type = REGULAR;
|
||||
Info("Triggered REGULAR BSR for single LCID=%d\n", pending_data_lcid);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
uint32_t nbytes = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
// If there is new data available for this logical channel
|
||||
if (nbytes > last_pending_data[pending_data_lcid]) {
|
||||
triggered_bsr_type = REGULAR;
|
||||
Info("Triggered REGULAR BSR for single LCID=%d\n", pending_data_lcid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void bsr_proc::update_pending_data() {
|
||||
for (int i=0;i<mac_io_h->NOF_UL_LCH;i++) {
|
||||
last_pending_data[i] = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
}
|
||||
}
|
||||
|
||||
bool bsr_proc::check_all_channels() {
|
||||
bool bsr_proc::generate_bsr(bsr_t *bsr, uint32_t nof_padding_bytes) {
|
||||
bool ret = false;
|
||||
bzero(&pending_bsr, sizeof(bsr_t));
|
||||
uint32_t nof_lcg=0;
|
||||
bzero(bsr, sizeof(bsr_t));
|
||||
for (int i=0;i<mac_io_h->NOF_UL_LCH;i++) {
|
||||
if (lcg[i] >= 0) {
|
||||
uint32_t n = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
|
||||
pending_bsr.buff_size[lcg[i]] += n;
|
||||
bsr->buff_size[lcg[i]] += n;
|
||||
if (n > 0) {
|
||||
nof_lcg++;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bsr_proc::get_pending_bsr_format(uint32_t nof_padding_bytes) {
|
||||
uint32_t nof_lcg=0;
|
||||
for (int i=0;i<4;i++) {
|
||||
if (pending_bsr.buff_size[i] > 0) {
|
||||
nof_lcg++;
|
||||
}
|
||||
}
|
||||
if (triggered_bsr_type == PADDING) {
|
||||
if (nof_padding_bytes < 4) {
|
||||
// If space only for short
|
||||
if (nof_lcg > 1) {
|
||||
pending_bsr.format = TRUNC_BSR;
|
||||
bsr->format = TRUNC_BSR;
|
||||
uint32_t max_prio_ch = find_max_priority_lcid();
|
||||
for (int i=0;i<4;i++) {
|
||||
if (lcg[max_prio_ch] != i) {
|
||||
pending_bsr.buff_size[i] = 0;
|
||||
bsr->buff_size[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pending_bsr.format = SHORT_BSR;
|
||||
bsr->format = SHORT_BSR;
|
||||
}
|
||||
} else {
|
||||
// If space for long BSR
|
||||
pending_bsr.format = LONG_BSR;
|
||||
bsr->format = LONG_BSR;
|
||||
}
|
||||
} else {
|
||||
pending_bsr.format = SHORT_BSR;
|
||||
bsr->format = SHORT_BSR;
|
||||
if (nof_lcg > 1) {
|
||||
pending_bsr.format = LONG_BSR;
|
||||
bsr->format = LONG_BSR;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Checks if Regular BSR must be assembled, as defined in 5.4.5
|
||||
|
@ -214,47 +214,87 @@ void bsr_proc::step(uint32_t tti)
|
|||
}
|
||||
// Higher priority channel is reported regardless of a BSR being already triggered
|
||||
check_highest_channel();
|
||||
|
||||
update_pending_data();
|
||||
}
|
||||
|
||||
bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t nof_padding_bytes, bsr_t *bsr)
|
||||
char* bsr_proc::bsr_type_tostring(triggered_bsr_type_t type) {
|
||||
switch(type) {
|
||||
case bsr_proc::REGULAR:
|
||||
return (char*) "Regular";
|
||||
case bsr_proc::PADDING:
|
||||
return (char*) "Padding";
|
||||
case bsr_proc::PERIODIC:
|
||||
return (char*) "Periodic";
|
||||
}
|
||||
}
|
||||
|
||||
char* bsr_proc::bsr_format_tostring(bsr_format_t format) {
|
||||
switch(format) {
|
||||
case bsr_proc::LONG_BSR:
|
||||
return (char*) "Long";
|
||||
case bsr_proc::SHORT_BSR:
|
||||
return (char*) "Short";
|
||||
case bsr_proc::TRUNC_BSR:
|
||||
return (char*) "Truncated";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t grant_size)
|
||||
{
|
||||
uint32_t bsr_sz = 0;
|
||||
if (triggered_bsr_type == PERIODIC || triggered_bsr_type == REGULAR) {
|
||||
uint32_t total_data = 0;
|
||||
/* Check if grant + MAC SDU headers is enough to accomodate all pending data */
|
||||
for (int i=0;i<mac_io_h->NOF_UL_LCH && total_data < grant_size;i++) {
|
||||
uint32_t idx = 0;
|
||||
uint32_t sdu_len = 0;
|
||||
while(mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pop(&sdu_len, idx) && total_data < grant_size) {
|
||||
idx++;
|
||||
total_data += sch_pdu::size_plus_header_sdu(sdu_len/8);
|
||||
}
|
||||
}
|
||||
total_data--; // Because last SDU has no size header
|
||||
|
||||
/* All triggered BSRs shall be cancelled in case the UL grant can accommodate all pending data available for transmission
|
||||
but is not sufficient to additionally accommodate the BSR MAC control element plus its subheader.
|
||||
*/
|
||||
bsr_t bsr;
|
||||
generate_bsr(&bsr, 0);
|
||||
bsr_sz = bsr.format==LONG_BSR?3:1;
|
||||
if (total_data <= grant_size && total_data + 1 + bsr_sz > grant_size) {
|
||||
bsr_sz = 0;
|
||||
Info("Grant is not enough to accomodate the BSR MAC CE\n");
|
||||
triggered_bsr_type = NONE;
|
||||
}
|
||||
Info("Checking if Regular BSR is sent: grant_size=%d, total_data=%d, bsr_sz=%d\n",
|
||||
grant_size, total_data, bsr_sz);
|
||||
}
|
||||
return bsr_sz;
|
||||
}
|
||||
|
||||
bool bsr_proc::generate_bsr_on_ul_grant(uint32_t nof_padding_bytes, bsr_t *bsr)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (triggered_bsr_type == NONE) {
|
||||
// If enough space for at least truncated BSR
|
||||
if (nof_padding_bytes >= 2) {
|
||||
// Check condition 2 in Sec 5.4.5
|
||||
if (check_all_channels()) {
|
||||
triggered_bsr_type = PADDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (triggered_bsr_type != NONE) {
|
||||
// If no more data is pending and there is no space for MAC CE
|
||||
uint32_t nof_pending_bytes = 0;
|
||||
for (int i=0;i<4;i++) {
|
||||
nof_pending_bytes += pending_bsr.buff_size[i];
|
||||
}
|
||||
Info("Triggered BSR: nof_grant_bytes=%d, nof_padding_bytes=%d, nof_pending_bytes=%d\n", nof_grant_bytes, nof_padding_bytes, nof_pending_bytes);
|
||||
if (triggered_bsr_type != NONE || nof_padding_bytes >= 2) {
|
||||
|
||||
get_pending_bsr_format(nof_padding_bytes);
|
||||
|
||||
// Do not include BSR CE if the UL grant can accomodate all pending data but is not sufficient
|
||||
// to additionally accomodate the BSR MAC CE plus its header
|
||||
uint32_t bsr_sz_plus_header = pending_bsr.format == LONG_BSR?4:2;
|
||||
if (nof_pending_bytes + bsr_sz_plus_header == nof_grant_bytes) {
|
||||
triggered_bsr_type = NONE;
|
||||
} else {
|
||||
// Instruct MUX unit to generate MAC CE
|
||||
ret = true;
|
||||
memcpy(bsr, &pending_bsr, sizeof(bsr_t));
|
||||
if (timer_periodic && pending_bsr.format != TRUNC_BSR) {
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->reset();
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->run();
|
||||
}
|
||||
// Cancel all triggered BSR
|
||||
triggered_bsr_type = NONE;
|
||||
|
||||
if (triggered_bsr_type == NONE) {
|
||||
triggered_bsr_type = PADDING;
|
||||
}
|
||||
generate_bsr(bsr, nof_padding_bytes);
|
||||
ret = true;
|
||||
Info("Sending BSR type %s, format %s, nof_padding_bytes=%d\n",
|
||||
bsr_type_tostring(triggered_bsr_type), bsr_format_tostring(bsr->format), nof_padding_bytes);
|
||||
|
||||
if (timer_periodic && bsr->format != TRUNC_BSR) {
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->reset();
|
||||
timers_db->get(mac::BSR_TIMER_PERIODIC)->run();
|
||||
}
|
||||
// Cancel all triggered BSR
|
||||
triggered_bsr_type = NONE;
|
||||
reset_sr = true;
|
||||
}
|
||||
|
||||
// Restart or Start ReTX timer
|
||||
|
@ -265,8 +305,18 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t n
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool bsr_proc::need_to_reset_sr() {
|
||||
if (reset_sr) {
|
||||
reset_sr = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool bsr_proc::need_to_send_sr() {
|
||||
if (!sr_is_sent && triggered_bsr_type == REGULAR) {
|
||||
reset_sr = false;
|
||||
sr_is_sent = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -398,18 +398,17 @@ void ra_proc::step_contention_resolution() {
|
|||
|
||||
} else if (demux_unit->is_temp_crnti_pending())
|
||||
{
|
||||
rInfo("MAC PDU with Temporal C-RNTI has been decoded\n");
|
||||
rDebug("MAC PDU with Temporal C-RNTI has been decoded\n");
|
||||
// Random Access initiated by RRC by the transmission of CCCH SDU
|
||||
if (demux_unit->is_contention_resolution_id_pending()) {
|
||||
rInfo("MAC PDU Contains Contention Resolution ID CE\n");
|
||||
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
||||
// MAC PDU successfully decoded and contains MAC CE contention Id
|
||||
uint64_t rx_contention_id = demux_unit->get_contention_resolution_id();
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
if (transmitted_contention_id == rx_contention_id) {
|
||||
rInfo("MAC PDU Contention Resolution ID matches the one transmitted in CCCH SDU\n");
|
||||
rDebug("MAC PDU Contention Resolution ID matches the one transmitted in CCCH SDU\n");
|
||||
// UE Contention Resolution ID included in MAC CE matches the CCCH SDU transmitted in Msg3
|
||||
params_db->set_param(mac_params::RNTI_C, params_db->get_param(mac_params::RNTI_TEMP));
|
||||
|
||||
// finish the disassembly and demultiplexing of the MAC PDU
|
||||
demux_unit->demultiplex_pending_pdu();
|
||||
state = COMPLETION;
|
||||
|
|
|
@ -42,11 +42,12 @@ void sr_proc::init(log* log_h_, mac_params* params_db_, phy* phy_h_)
|
|||
params_db = params_db_;
|
||||
phy_h = phy_h_;
|
||||
initiated = true;
|
||||
do_ra = false;
|
||||
}
|
||||
|
||||
void sr_proc::reset()
|
||||
{
|
||||
is_pending_sr = false;
|
||||
is_pending_sr = false;
|
||||
phy_h->send_sr(false);
|
||||
}
|
||||
|
||||
|
@ -54,11 +55,20 @@ void sr_proc::step(uint32_t tti)
|
|||
{
|
||||
if (initiated) {
|
||||
if (is_pending_sr) {
|
||||
if (sr_counter < dsr_transmax) {
|
||||
sr_counter++;
|
||||
Info("SR stepping: sr_counter=%d\n", sr_counter);
|
||||
phy_h->send_sr(true);
|
||||
if (params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
|
||||
if (sr_counter < dsr_transmax) {
|
||||
int last_tx_tti = phy_h->sr_last_tx_tti();
|
||||
if (last_tx_tti >= 0 && last_tx_tti + 4 < tti) {
|
||||
sr_counter++;
|
||||
Info("SR signalling PHY. sr_counter=%d, PHY TTI=%d\n", sr_counter, phy_h->get_current_tti());
|
||||
phy_h->send_sr(true);
|
||||
}
|
||||
} else {
|
||||
do_ra = true;
|
||||
reset();
|
||||
}
|
||||
} else {
|
||||
do_ra = true;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
@ -67,11 +77,9 @@ void sr_proc::step(uint32_t tti)
|
|||
|
||||
bool sr_proc::need_random_access() {
|
||||
if (initiated) {
|
||||
if (sr_counter == dsr_transmax && dsr_transmax > 0 &&
|
||||
params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
|
||||
|
||||
Info("SR checking need RA: sr_counter=%d, dsr_transmax=%d, configured=%d\n", sr_counter, dsr_transmax, params_db->get_param(mac_params::SR_PUCCH_CONFIGURED));
|
||||
return true;
|
||||
if (do_ra) {
|
||||
do_ra = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -81,14 +89,12 @@ bool sr_proc::need_random_access() {
|
|||
void sr_proc::start()
|
||||
{
|
||||
if (initiated) {
|
||||
if (params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
|
||||
if (!is_pending_sr) {
|
||||
sr_counter = 0;
|
||||
is_pending_sr = true;
|
||||
dsr_transmax = params_db->get_param(mac_params::SR_TRANS_MAX);
|
||||
Info("SR starting dsrTransMax=%d. Setting sr_counter=0\n", dsr_transmax);
|
||||
}
|
||||
if (!is_pending_sr) {
|
||||
sr_counter = 0;
|
||||
is_pending_sr = true;
|
||||
}
|
||||
dsr_transmax = params_db->get_param(mac_params::SR_TRANS_MAX);
|
||||
Info("SR starting dsrTransMax=%d. sr_counter=%d, PHY TTI=%d\n", dsr_transmax, sr_counter, phy_h->get_current_tti());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -239,14 +239,14 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *
|
|||
{
|
||||
if (ul_grant && pdu_payload) {
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
// Store the uplink grant
|
||||
memcpy(&cur_grant, ul_grant, sizeof(ul_sched_grant));
|
||||
harq_feedback = false;
|
||||
is_grant_configured = true;
|
||||
current_tx_nb = 0;
|
||||
current_irv = 0;
|
||||
is_msg3 = is_msg3_;
|
||||
Info("UL PID %d: New TX%s, RV=%d, TBS=%d, MCS=%d\n", pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.get_tbs(), cur_grant.get_mcs());
|
||||
Info("UL PID %d: New TX%s, RV=%d, TBS=%d, MCS=%d, RNTI=%d\n", pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.get_tbs(),
|
||||
cur_grant.get_mcs(), cur_grant.get_rnti());
|
||||
generate_tx(tti_tx, pdu_payload, ul);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd)
|
||||
TARGET_LINK_LIBRARIES(mac_test srsapps_common srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd)
|
||||
ENDIF(UHD_FOUND AND OPENLTE_FOUND)
|
||||
|
|
|
@ -199,37 +199,39 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
|
|||
}
|
||||
|
||||
void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac *mac, srslte::ue::phy *phy) {
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXTX,
|
||||
liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]);
|
||||
printf("Set MAX HARQ reTX: %d\n", liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]);
|
||||
|
||||
// FIXME: There's an error parsing the connectionSetup message. This value is hard-coded:
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx = 35;
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::SR_PUCCH_RESINDEX,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx);
|
||||
phy->set_param(srslte::ue::phy_params::SR_CONFIG_INDEX,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx);
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx);
|
||||
|
||||
printf("Set PHY configuration: n_pucch=%d, configIndex=%d\n",
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx);
|
||||
|
||||
mac->set_param(srslte::ue::mac_params::HARQ_MAXTX,
|
||||
liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx]);
|
||||
mac->set_param(srslte::ue::mac_params::SR_TRANS_MAX,
|
||||
liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max]);
|
||||
mac->set_param(srslte::ue::mac_params::SR_PUCCH_CONFIGURED, 1);
|
||||
|
||||
printf("Set SR configuration: TransMAX: %d, n_pucch=%d, configIndex=%d\n",
|
||||
liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max],
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_pucch_resource_idx,
|
||||
msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.sr_cnfg_idx);
|
||||
|
||||
mac->set_param(srslte::ue::mac_params::BSR_TIMER_RETX,
|
||||
liblte_rrc_retransmission_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.retx_bsr_timer]);
|
||||
mac->set_param(srslte::ue::mac_params::BSR_TIMER_PERIODIC,
|
||||
liblte_rrc_periodic_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.periodic_bsr_timer]);
|
||||
|
||||
printf("Set MAC BSR configuration: ReTX timer: %d, Periodic: %d\n",
|
||||
liblte_rrc_retransmission_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.retx_bsr_timer],
|
||||
|
||||
printf("Set MAC configuration: dsr-TransMAX: %d, harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d\n",
|
||||
liblte_rrc_dsr_trans_max_num[msg->rr_cnfg.phy_cnfg_ded.sched_request_cnfg.dsr_trans_max],
|
||||
liblte_rrc_max_harq_tx_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.max_harq_tx],
|
||||
liblte_rrc_retransmission_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.retx_bsr_timer],
|
||||
liblte_rrc_periodic_bsr_timer_num[msg->rr_cnfg.mac_main_cnfg.explicit_value.ulsch_cnfg.periodic_bsr_timer]);
|
||||
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_ACK, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ack_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_CQI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_cqi_idx);
|
||||
phy->set_param(srslte::ue::phy_params::UCI_I_OFFSET_RI, msg->rr_cnfg.phy_cnfg_ded.pusch_cnfg_ded.beta_offset_ri_idx);
|
||||
|
||||
|
||||
// Setup radio bearers
|
||||
for (int i=0;i<msg->rr_cnfg.srb_to_add_mod_list_size;i++) {
|
||||
|
@ -254,18 +256,17 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac
|
|||
|
||||
// Hex bytes for the connection setup complete packet
|
||||
// Got hex bytes from http://www.sharetechnote.com/html/RACH_LTE.html
|
||||
uint8_t setupComplete_segm[10][12] ={{0x88, 0x00, 0x00, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x01, 0x20, 0x80, 0x01, 0x00, 0x59, 0x17, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x02, 0x39, 0x45, 0xE5, 0x34, 0x0B, 0x07, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x03, 0x41, 0x02, 0x0B, 0xF6, 0x03, 0x02, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x04, 0x27, 0x80, 0x01, 0x00, 0xD0, 0xCC, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x05, 0x71, 0x51, 0x04, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x06, 0xE0, 0xC0, 0x40, 0x00, 0x21, 0x02, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x07, 0x03, 0xD0, 0x11, 0xD1, 0x27, 0x1A, 0x0, 0x0, 0x0, 0x0},
|
||||
{0x98, 0x08, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x0, 0x0, 0x0, 0x0},
|
||||
{0xB0, 0x09, 0x00, 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06}};
|
||||
uint8_t last_segm[54];
|
||||
uint32_t lengths[10] = {4, 8, 8, 8, 8, 6, 8, 8, 8, 12};
|
||||
uint8_t setupComplete_segm[2][41] ={ {
|
||||
0x88, 0x00, 0x00, 0x20, 0x21, 0x90, 0xa0, 0x12, 0x00, 0x00, 0x80, 0xf0, 0x5e, 0x3b, 0xf1, 0x04,
|
||||
0x64, 0x04, 0x1d, 0x20, 0x44, 0x2f, 0xd8, 0x4b, 0xd1, 0x02, 0x00, 0x00, 0x83, 0x03, 0x41, 0xb0,
|
||||
0xe5, 0x60, 0x13, 0x81, 0x83},
|
||||
|
||||
{0xb0, 0x01, 0x01, 0x01, 0x48, 0x4b, 0xd1, 0x00, 0x7d, 0x21, 0x70, 0x28, 0x01, 0x5c, 0x08, 0x80,
|
||||
0x00, 0xc4, 0x0f, 0x97, 0x80, 0xd0, 0x4c, 0x4b, 0xd1, 0x00, 0xc0, 0x58, 0x44, 0x0d, 0x5d, 0x62,
|
||||
0x99, 0x74, 0x04, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
uint32_t lengths[2] = {37, 41};
|
||||
uint8_t reply[2] = {0x00, 0x04};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -290,7 +291,7 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
// Init Radio and PHY
|
||||
// Init Radio and PHY
|
||||
if (prog_args.uhd_rx_gain > 0 && prog_args.uhd_tx_gain > 0) {
|
||||
radio_uhd.init();
|
||||
radio_uhd.set_rx_gain(prog_args.uhd_rx_gain);
|
||||
|
@ -316,7 +317,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
uint32_t si_window_len, sib2_period;
|
||||
int tti;
|
||||
enum {START, SIB1, SIB2, CONNECT, SETUPCOMPLETE} state = START;
|
||||
enum {START, SIB1, SIB2, CONNECT, SETUPCOMPLETE, IDLE} state = START;
|
||||
int n;
|
||||
|
||||
while(1) {
|
||||
|
@ -359,7 +360,7 @@ int main(int argc, char *argv[])
|
|||
ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REQ;
|
||||
ul_ccch_msg.msg.rrc_con_req.ue_id_type = LIBLTE_RRC_CON_REQ_UE_ID_TYPE_RANDOM_VALUE;
|
||||
ul_ccch_msg.msg.rrc_con_req.ue_id.random = 1000;
|
||||
ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_DATA;
|
||||
ul_ccch_msg.msg.rrc_con_req.cause = LIBLTE_RRC_CON_REQ_EST_CAUSE_MO_SIGNALLING;
|
||||
liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, &bit_msg);
|
||||
|
||||
uint64_t uecri=0;
|
||||
|
@ -395,26 +396,15 @@ int main(int argc, char *argv[])
|
|||
process_connsetup(&dl_ccch_msg.msg.rrc_con_setup, &mac, &phy);
|
||||
|
||||
// Generate and send ConnectionSetupComplete
|
||||
for (int i=0;i<9;i++) {
|
||||
for (int i=0;i<2;i++) {
|
||||
printf("Sending Connection Setup Complete %d\n", i);
|
||||
srslte_bit_pack_vector(setupComplete_segm[i], bit_msg.msg, lengths[i]);
|
||||
srslte_bit_pack_vector(setupComplete_segm[i], bit_msg.msg, lengths[i]*8);
|
||||
n=mac.send_dcch0_sdu(bit_msg.msg, lengths[i]*8);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error writting to DCCH0\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
// Last segment is 54 bytes long
|
||||
printf("Sending Connection Setup Complete Last segment\n");
|
||||
bzero(last_segm, 54*sizeof(uint8_t));
|
||||
memcpy(last_segm, setupComplete_segm[9], lengths[9]*sizeof(uint8_t));
|
||||
srslte_bit_pack_vector(last_segm, bit_msg.msg, 54);
|
||||
n=mac.send_dcch0_sdu(bit_msg.msg, 54*8);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error writting to DCCH0\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
state = SETUPCOMPLETE;
|
||||
break;
|
||||
case LIBLTE_RRC_DL_CCCH_MSG_TYPE_RRC_CON_REJ:
|
||||
|
@ -426,10 +416,20 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
case SETUPCOMPLETE:
|
||||
// Wait for ConnectionSetup
|
||||
n = mac.recv_dtch0_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
n = mac.recv_dcch0_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
|
||||
if (n > 0) {
|
||||
printf("Received on DTCH0 %d bytes\n", n/8);
|
||||
}
|
||||
printf("Received on DCCH0 %d bytes\n", n/8);
|
||||
printf("Send RLC ACK\n");
|
||||
srslte_bit_pack_vector(reply, bit_msg.msg, 2*8);
|
||||
n=mac.send_dcch0_sdu(bit_msg.msg, 2*8);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error writting to DCCH0\n");
|
||||
exit(-1);
|
||||
}
|
||||
state = IDLE;
|
||||
}
|
||||
break;
|
||||
case IDLE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ INSTALL(DIRECTORY include/
|
|||
|
||||
FILE(GLOB SOURCES "src/*.cc")
|
||||
ADD_LIBRARY(srsapps_ue_phy SHARED ${SOURCES})
|
||||
TARGET_LINK_LIBRARIES(srsapps_ue_phy srsapps_common)
|
||||
INSTALL(TARGETS srsapps_ue_phy DESTINATION ${LIBRARY_DIR})
|
||||
SRSLTE_SET_PIC(srsapps_ue_phy)
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace ue {
|
|||
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h_);
|
||||
void free_cell();
|
||||
void set_crnti(uint16_t rnti);
|
||||
bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time);
|
||||
bool get_ul_grant(ul_sched_grant *grant);
|
||||
bool get_dl_grant(dl_sched_grant *grant);
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
|
||||
float get_agc_gain();
|
||||
|
||||
void set_crnti(uint16_t rnti);
|
||||
|
||||
// Indicate the PHY to send PRACH as soon as possible
|
||||
bool init_prach();
|
||||
bool send_prach(uint32_t preamble_idx);
|
||||
|
@ -89,6 +91,7 @@ public:
|
|||
|
||||
// Indicate the PHY to send SR as soon as possible or not
|
||||
void send_sr(bool enable);
|
||||
int sr_last_tx_tti();
|
||||
|
||||
// Returns TTI when PRACH was transmitted. -1 if not yet transmitted
|
||||
int get_prach_transmitted_tti();
|
||||
|
@ -162,6 +165,7 @@ private:
|
|||
void run_rx_tx_state();
|
||||
ul_buffer* get_ul_buffer_adv(uint32_t tti);
|
||||
float old_gain;
|
||||
uint32_t sr_tx_tti;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace ue {
|
|||
public:
|
||||
bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h);
|
||||
void free_cell();
|
||||
void set_crnti(uint16_t rnti);
|
||||
void set_current_tx_nb(uint32_t current_tx_nb);
|
||||
bool generate_ack(bool ack, dl_sched_grant *last_dl_grant);
|
||||
bool generate_ack(bool ack[2]);
|
||||
|
|
|
@ -65,6 +65,11 @@ void dl_buffer::free_cell()
|
|||
srslte_ue_dl_free(&ue_dl);
|
||||
}
|
||||
|
||||
void dl_buffer::set_crnti(uint16_t rnti)
|
||||
{
|
||||
srslte_ue_dl_set_rnti(&ue_dl, rnti);
|
||||
}
|
||||
|
||||
// FIXME: Avoid this memcpy modifying ue_sync to directly write into provided pointer
|
||||
bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time)
|
||||
{
|
||||
|
@ -111,7 +116,6 @@ bool dl_buffer::get_ul_grant(ul_sched_grant *grant)
|
|||
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, grant->get_rnti()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return grant->create_from_dci(&dci_msg, cell, 0, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET));
|
||||
}
|
||||
}
|
||||
|
@ -160,6 +164,8 @@ bool dl_buffer::get_dl_grant(dl_sched_grant *grant)
|
|||
if (srslte_ue_dl_find_dl_dci(&ue_dl, &dci_msg, cfi, tti%10, grant->get_rnti()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Info("Found DL DCI cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits);
|
||||
|
||||
return grant->create_from_dci(&dci_msg, cell, cfi, tti%10, srslte_ue_dl_get_ncce(&ue_dl));
|
||||
}
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
#include <strings.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srsapps/common/threads.h"
|
||||
#include "srsapps/common/log.h"
|
||||
#include "srsapps/ue/phy/phy.h"
|
||||
#include "srsapps/ue/phy/prach.h"
|
||||
|
@ -57,8 +59,12 @@ bool phy::init_agc(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_
|
|||
return init_(radio_handler_, ttisync_, log_h, true);
|
||||
}
|
||||
|
||||
|
||||
bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h_, bool do_agc_)
|
||||
{
|
||||
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
|
||||
started = false;
|
||||
radio_is_streaming = false;
|
||||
ttisync = ttisync_;
|
||||
|
@ -74,18 +80,9 @@ bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, l
|
|||
params_db.set_param(phy_params::CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD, 160);
|
||||
params_db.set_param(phy_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES, 100);
|
||||
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
param.sched_priority = sched_get_priority_min(SCHED_FIFO) ;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
|
||||
pthread_attr_setschedparam(&attr, ¶m);
|
||||
if (!pthread_create(&phy_thread, &attr, phy_thread_fnc, this)) {
|
||||
started = true;
|
||||
} else {
|
||||
perror("pthread_create");
|
||||
if (threads_new_rt(&phy_thread, phy_thread_fnc, this)) {
|
||||
started = true;
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
return started;
|
||||
}
|
||||
|
||||
|
@ -186,14 +183,25 @@ void phy::send_sr(bool enable)
|
|||
}
|
||||
sr_n_pucch = params_db.get_param(phy_params::SR_PUCCH_RESINDEX);
|
||||
Info("SR I_sr=%d, periodicity=%d, N_offset=%d, n_pucch=%d\n", I_sr, sr_periodicity, sr_N_offset, sr_n_pucch);
|
||||
sr_tx_tti = get_current_tti();
|
||||
}
|
||||
sr_enabled = enable;
|
||||
}
|
||||
|
||||
int phy::sr_last_tx_tti() {
|
||||
if (sr_enabled) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int) sr_tx_tti;
|
||||
}
|
||||
}
|
||||
|
||||
bool phy::sr_is_ready_to_send(uint32_t tti_) {
|
||||
if (sr_enabled) {
|
||||
if ((10*tti_to_SFN(tti_)+tti_to_subf(tti_)-sr_N_offset)%sr_periodicity==0) {
|
||||
Info("SR ready to send\n");
|
||||
sr_enabled = false;
|
||||
sr_tx_tti = tti_;
|
||||
Debug("SR ready to send for TTI=%d\n", tti_);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -214,6 +222,14 @@ bool phy::measure()
|
|||
return false;
|
||||
}
|
||||
|
||||
void phy::set_crnti(uint16_t rnti) {
|
||||
for(uint32_t i=0;i<6;i++) {
|
||||
((ul_buffer*) ul_buffer_queue->get(i))->set_crnti(rnti);
|
||||
((dl_buffer*) dl_buffer_queue->get(i))->set_crnti(rnti);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool phy::start_rxtx()
|
||||
{
|
||||
if (phy_state == IDLE) {
|
||||
|
@ -328,6 +344,9 @@ bool phy::init_prach() {
|
|||
|
||||
ul_buffer* phy::get_ul_buffer(uint32_t tti)
|
||||
{
|
||||
if (tti + 1 < get_current_tti()) {
|
||||
Warning("Warning access to PHY UL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
|
||||
}
|
||||
return (ul_buffer*) ul_buffer_queue->get(tti);
|
||||
}
|
||||
|
||||
|
@ -339,7 +358,8 @@ ul_buffer* phy::get_ul_buffer_adv(uint32_t tti)
|
|||
dl_buffer* phy::get_dl_buffer(uint32_t tti)
|
||||
{
|
||||
if (tti + 4 < get_current_tti()) {
|
||||
Debug("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
|
||||
Warning("Warning access to PHY DL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
|
||||
// return NULL;
|
||||
}
|
||||
return (dl_buffer*) dl_buffer_queue->get(tti);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_
|
|||
params_db = params_db_;
|
||||
current_tx_nb = 0;
|
||||
if (!srslte_ue_ul_init(&ue_ul, cell)) {
|
||||
srslte_ue_ul_set_normalization(&ue_ul, false);
|
||||
signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
cell_initiated = signal_buffer?true:false;
|
||||
srslte_ue_ul_set_cfo_enable(&ue_ul, false);
|
||||
|
@ -67,6 +68,11 @@ void ul_buffer::free_cell() {
|
|||
}
|
||||
}
|
||||
|
||||
void ul_buffer::set_crnti(uint16_t rnti)
|
||||
{
|
||||
srslte_ue_ul_set_rnti(&ue_ul, rnti);
|
||||
}
|
||||
|
||||
bool ul_buffer::generate_ack(bool ack, dl_sched_grant *last_dl_grant)
|
||||
{
|
||||
uci_data.uci_ack_len = 1;
|
||||
|
@ -96,7 +102,7 @@ bool ul_buffer::generate_cqi_report()
|
|||
bool ul_buffer::generate_sr() {
|
||||
uci_data.scheduling_request = true;
|
||||
uci_pending = true;
|
||||
Info("SR Generating\n");
|
||||
Debug("SR Generating\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -113,6 +119,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant,
|
|||
{
|
||||
generate_data(grant, &ue_ul.softbuffer, payload);
|
||||
}
|
||||
//int nof_tx=0;
|
||||
|
||||
|
||||
bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload)
|
||||
{
|
||||
|
@ -128,6 +136,13 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
|
|||
dmrs_cfg.cyclic_shift = params_db->get_param(phy_params::PUSCH_RS_CYCLIC_SHIFT);
|
||||
dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT);
|
||||
|
||||
// Get cyclic shift for DMRS if PUSCH is not for RAR or (TODO) is not SPS
|
||||
if (grant) {
|
||||
if (!grant->is_from_rar()) {
|
||||
dmrs_cfg.en_dmrs_2 = true;
|
||||
dmrs_cfg.cyclic_shift_for_dmrs = grant->get_n_dmrs();
|
||||
}
|
||||
}
|
||||
srslte_pusch_hopping_cfg_t pusch_hopping;
|
||||
if (grant) {
|
||||
bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t));
|
||||
|
@ -168,17 +183,20 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
|
|||
// Transmit on PUSCH if UL grant available, otherwise in PUCCH
|
||||
if (grant) {
|
||||
|
||||
INFO("Encoding PUSCH TBS=%d, rb_start=%d n_prb=%d, rv=%d, rnti=%d\n",
|
||||
grant->get_tbs(), pusch_cfg.grant.L_prb, pusch_cfg.grant.n_prb[0], grant->get_rv(), grant->get_rnti());
|
||||
|
||||
grant->to_pusch_cfg(tti%10, cell.cp, &pusch_cfg);
|
||||
|
||||
Info("Encoding PUSCH TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, sf_idx=%d\n",
|
||||
grant->get_tbs(), srslte_mod_string(pusch_cfg.grant.mcs.mod), pusch_cfg.grant.n_prb[0], pusch_cfg.grant.L_prb,
|
||||
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
|
||||
grant->get_rnti(), tti%10);
|
||||
|
||||
n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg,
|
||||
payload, uci_data,
|
||||
softbuffer,
|
||||
grant->get_rnti(),
|
||||
signal_buffer);
|
||||
signal_buffer);
|
||||
} else {
|
||||
Info("Encoding PUCCH n_cce=%d, ack=%d\n", last_n_cce, uci_data.uci_ack);
|
||||
Info("Encoding PUCCH n_cce=%d, ack=%d, sr=%d\n", last_n_cce, uci_data.uci_ack, uci_data.scheduling_request);
|
||||
|
||||
n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti&10, signal_buffer);
|
||||
}
|
||||
|
@ -198,6 +216,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
|
|||
}
|
||||
}
|
||||
|
||||
int nof_tx = 0;
|
||||
|
||||
bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time)
|
||||
{
|
||||
// send packet through usrp
|
||||
|
@ -216,19 +236,23 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo
|
|||
max = fabsf(t[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize before TX
|
||||
srslte_vec_sc_prod_cfc(signal_buffer, 0.9/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us PeakAmplitude=%.2f\n",
|
||||
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us PeakAmplitude=%.2f PKT#%d\n",
|
||||
cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb),
|
||||
srslte_timestamp_real(&rx_time),
|
||||
srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max);
|
||||
|
||||
if (max > 1.0) {
|
||||
srslte_vec_save_file((char*) "first_pusch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
}
|
||||
|
||||
srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max, nof_tx);
|
||||
|
||||
radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);
|
||||
|
||||
//srslte_vec_save_file("pucch_tx", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
|
||||
char filename[25];
|
||||
sprintf(filename, "pusch%d",nof_tx);
|
||||
srslte_vec_save_file(filename, signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
nof_tx++;
|
||||
|
||||
|
||||
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 srslte_uhd)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_common 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 srslte_uhd)
|
||||
TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd)
|
||||
ENDIF(UHD_FOUND)
|
||||
|
|
|
@ -169,6 +169,7 @@ typedef struct SRSLTE_API {
|
|||
uint32_t n_dmrs;
|
||||
bool ndi;
|
||||
bool cqi_request;
|
||||
uint32_t tpc_pusch;
|
||||
|
||||
} srslte_ra_ul_dci_t;
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ bool srslte_refsignal_dmrs_pusch_cfg_isvalid(srslte_refsignal_ul_t *q, srslte_re
|
|||
void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q, cf_t *r_pusch, uint32_t nof_prb, uint32_t n_prb[2], cf_t *sf_symbols)
|
||||
{
|
||||
for (uint32_t ns_idx=0;ns_idx<2;ns_idx++) {
|
||||
DEBUG("Putting DRMS to n_prb: %d, L: %d, ns_idx: %d\n", n_prb[ns_idx], nof_prb, ns_idx);
|
||||
INFO("Putting DRMS to n_prb: %d, L: %d, ns_idx: %d\n", n_prb[ns_idx], nof_prb, ns_idx);
|
||||
uint32_t L = (ns_idx+1)*SRSLTE_CP_NSYMB(q->cell.cp)-4;
|
||||
memcpy(&sf_symbols[SRSLTE_RE_IDX(q->cell.nof_prb, L, n_prb[ns_idx]*SRSLTE_NRE)],
|
||||
&r_pusch[ns_idx*SRSLTE_NRE*nof_prb], nof_prb*SRSLTE_NRE*sizeof(cf_t));
|
||||
|
|
|
@ -127,9 +127,9 @@ char *srslte_mod_string(srslte_mod_t mod) {
|
|||
case SRSLTE_MOD_QPSK:
|
||||
return "QPSK";
|
||||
case SRSLTE_MOD_16QAM:
|
||||
return "QAM16";
|
||||
return "16QAM";
|
||||
case SRSLTE_MOD_64QAM:
|
||||
return "QAM64";
|
||||
return "64QAM";
|
||||
default:
|
||||
return "N/A";
|
||||
}
|
||||
|
|
|
@ -122,10 +122,12 @@ double cuhd_set_rx_gain_th(void *h, double gain)
|
|||
{
|
||||
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
|
||||
gain = handler->rx_gain_range.clip(gain);
|
||||
pthread_mutex_lock(&handler->mutex);
|
||||
handler->new_rx_gain = gain;
|
||||
pthread_cond_signal(&handler->cond);
|
||||
pthread_mutex_unlock(&handler->mutex);
|
||||
if (gain != handler->new_rx_gain) {
|
||||
pthread_mutex_lock(&handler->mutex);
|
||||
handler->new_rx_gain = gain;
|
||||
pthread_cond_signal(&handler->cond);
|
||||
pthread_mutex_unlock(&handler->mutex);
|
||||
}
|
||||
return gain;
|
||||
}
|
||||
|
||||
|
|
|
@ -414,9 +414,11 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t
|
|||
|
||||
data->ndi = *y++ ? true : false;
|
||||
|
||||
// TPC and DM RS commands not implemented
|
||||
y += 5;
|
||||
data->n_dmrs = 0;
|
||||
// TPC command for scheduled PUSCH
|
||||
data->tpc_pusch = srslte_bit_unpack(&y, 2);
|
||||
|
||||
// Cyclic shift for DMRS
|
||||
data->n_dmrs = srslte_bit_unpack(&y, 3);
|
||||
|
||||
// CQI request
|
||||
data->cqi_request = *y++ ? true : false;
|
||||
|
|
|
@ -283,7 +283,8 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui
|
|||
E <= q->max_bits &&
|
||||
nof_bits <= SRSLTE_DCI_MAX_BITS)
|
||||
{
|
||||
|
||||
bzero(q->rm_f, sizeof(float)*3 * (SRSLTE_DCI_MAX_BITS + 16));
|
||||
|
||||
/* unrate matching */
|
||||
srslte_rm_conv_rx(e, E, q->rm_f, 3 * (nof_bits + 16));
|
||||
|
||||
|
@ -315,7 +316,11 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui
|
|||
* The decoded message is stored in msg and the CRC remainder in crc_rem pointer
|
||||
*
|
||||
*/
|
||||
int srslte_pdcch_decode_msg(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci_location_t *location, srslte_dci_format_t format, uint16_t *crc_rem)
|
||||
int srslte_pdcch_decode_msg(srslte_pdcch_t *q,
|
||||
srslte_dci_msg_t *msg,
|
||||
srslte_dci_location_t *location,
|
||||
srslte_dci_format_t format,
|
||||
uint16_t *crc_rem)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
|
@ -333,12 +338,21 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, srslte_dci_msg_t *msg, srslte_dci
|
|||
|
||||
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],
|
||||
msg->data, e_bits, nof_bits, crc_rem);
|
||||
if (ret == SRSLTE_SUCCESS) {
|
||||
msg->nof_bits = nof_bits;
|
||||
}
|
||||
|
||||
double mean = 0;
|
||||
for (int i=0;i<e_bits;i++) {
|
||||
mean += fabsf(q->llr[location->ncce * 72 + i]);
|
||||
}
|
||||
mean /= e_bits;
|
||||
if (mean > 0.5) {
|
||||
ret = dci_decode(q, &q->llr[location->ncce * 72],
|
||||
msg->data, e_bits, nof_bits, crc_rem);
|
||||
if (ret == SRSLTE_SUCCESS) {
|
||||
msg->nof_bits = nof_bits;
|
||||
}
|
||||
} else {
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -368,7 +382,8 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT
|
|||
uint32_t e_bits = 72*q->nof_cce;
|
||||
nof_symbols = e_bits/2;
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
bzero(q->llr, sizeof(float) * q->max_bits);
|
||||
|
||||
DEBUG("Extracting LLRs: E: %d, SF: %d, CFI: %d\n",
|
||||
e_bits, nsubframe, cfi);
|
||||
|
||||
|
|
|
@ -265,9 +265,16 @@ 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;
|
||||
}
|
||||
if (dci_msg->data[0] != 0) {
|
||||
crc_rem = 0;
|
||||
}
|
||||
DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem);
|
||||
}
|
||||
return crc_rem == rnti;
|
||||
if (crc_rem == rnti) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) {
|
||||
|
@ -301,10 +308,19 @@ 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;
|
||||
}
|
||||
if (formats[f] == SRSLTE_DCI_FORMAT1A) {
|
||||
if (dci_msg->data[0] != 1) {
|
||||
crc_rem = 0;
|
||||
}
|
||||
}
|
||||
DEBUG("Decoded DCI message RNTI: 0x%x\n", crc_rem);
|
||||
}
|
||||
}
|
||||
return crc_rem == rnti;
|
||||
if (crc_rem == rnti) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -265,7 +265,6 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
|||
}
|
||||
srslte_refsignal_dmrs_pucch_put(&q->dmrs, format, n_pucch, q->refsignal, q->sf_symbols);
|
||||
|
||||
|
||||
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);
|
||||
|
||||
if (q->cfo_en) {
|
||||
|
@ -339,6 +338,7 @@ int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
|
|||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp));
|
||||
|
||||
if (q != NULL &&
|
||||
cfg != NULL &&
|
||||
|
|
Loading…
Reference in New Issue