diff --git a/matlab/tests/pusch_decode_test.m b/matlab/tests/pusch_decode_test.m index 3ed20c856..3beb2b26d 100644 --- a/matlab/tests/pusch_decode_test.m +++ b/matlab/tests/pusch_decode_test.m @@ -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)) diff --git a/matlab/tests/pusch_test.m b/matlab/tests/pusch_test.m index 5cee60fe0..c54a52d47 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_test.m @@ -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 diff --git a/srsapps/common/CMakeLists.txt b/srsapps/common/CMakeLists.txt index 13a0fbf62..1e0a3ca0a 100644 --- a/srsapps/common/CMakeLists.txt +++ b/srsapps/common/CMakeLists.txt @@ -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) diff --git a/srsapps/common/include/srsapps/common/threads.h b/srsapps/common/include/srsapps/common/threads.h new file mode 100644 index 000000000..2cebb77f7 --- /dev/null +++ b/srsapps/common/include/srsapps/common/threads.h @@ -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 + +#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 + diff --git a/srsapps/common/src/threads.c b/srsapps/common/src/threads.c new file mode 100644 index 000000000..2ffedeaaa --- /dev/null +++ b/srsapps/common/src/threads.c @@ -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 +#include +#include +#include +#include + +#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); +} diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h index 89d36fbdd..739374c81 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h @@ -140,6 +140,7 @@ private: /* Functions for MAC Timers */ timers timers_db; + uint16_t phy_rnti; void setup_timers(); void timeAlignmentTimerExpire(); diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h index 6b6cab6ea..57b95b5e9 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac_io.h @@ -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) { diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mux.h b/srsapps/ue/mac/include/srsapps/ue/mac/mux.h index dd78fadcc..530c77d15 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mux.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mux.h @@ -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 diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h index add002d48..fee7d6c13 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/pdu.h @@ -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 diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h index 2c45b3d6f..955901c67 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h @@ -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); }; } } diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h index 8ae9a8a32..5ea43cff5 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_sr.h @@ -58,6 +58,7 @@ private: phy *phy_h; log *log_h; bool initiated; + bool do_ra; }; } } diff --git a/srsapps/ue/mac/src/demux.cc b/srsapps/ue/mac/src/demux.cc index 5875aa4b1..4a3bf5570 100644 --- a/srsapps/ue/mac/src/demux.cc +++ b/srsapps/ue/mac/src/demux.cc @@ -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()); diff --git a/srsapps/ue/mac/src/dl_harq.cc b/srsapps/ue/mac/src/dl_harq.cc index eab05fdbf..c84df32e1 100644 --- a/srsapps/ue/mac/src/dl_harq.cc +++ b/srsapps/ue/mac/src/dl_harq.cc @@ -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 diff --git a/srsapps/ue/mac/src/mac.cc b/srsapps/ue/mac/src/mac.cc index 44a0572e4..33908642d 100644 --- a/srsapps/ue/mac/src/mac.cc +++ b/srsapps/ue/mac/src/mac.cc @@ -30,6 +30,7 @@ #include #include +#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); } diff --git a/srsapps/ue/mac/src/mux.cc b/srsapps/ue/mac/src/mux.cc index bbab90c9a..c79b1d4dc 100644 --- a/srsapps/ue/mac/src/mux.cc +++ b/srsapps/ue/mac/src/mux.cc @@ -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 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;ineed_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; } diff --git a/srsapps/ue/mac/src/pdu.cc b/srsapps/ue/mac/src/pdu.cc index 25ffb4c64..95f606389 100644 --- a/srsapps/ue/mac/src/pdu.cc +++ b/srsapps/ue/mac/src/pdu.cc @@ -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= 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= 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; } } diff --git a/srsapps/ue/mac/src/proc_bsr.cc b/srsapps/ue/mac/src/proc_bsr.cc index 8a8f98c0e..34ec3dd03 100644 --- a/srsapps/ue/mac/src/proc_bsr.cc +++ b/srsapps/ue/mac/src/proc_bsr.cc @@ -38,9 +38,11 @@ bsr_proc::bsr_proc() initiated = false; timer_periodic = false; timer_retx = false; + reset_sr = false; for (int i=0;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;jget(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;iNOF_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;iNOF_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;iNOF_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; } diff --git a/srsapps/ue/mac/src/proc_ra.cc b/srsapps/ue/mac/src/proc_ra.cc index ae31ec767..17f92095a 100644 --- a/srsapps/ue/mac/src/proc_ra.cc +++ b/srsapps/ue/mac/src/proc_ra.cc @@ -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; diff --git a/srsapps/ue/mac/src/proc_sr.cc b/srsapps/ue/mac/src/proc_sr.cc index 2ee147447..a2c9193c7 100644 --- a/srsapps/ue/mac/src/proc_sr.cc +++ b/srsapps/ue/mac/src/proc_sr.cc @@ -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()); } } diff --git a/srsapps/ue/mac/src/ul_harq.cc b/srsapps/ue/mac/src/ul_harq.cc index 945678095..8132e84ab 100644 --- a/srsapps/ue/mac/src/ul_harq.cc +++ b/srsapps/ue/mac/src/ul_harq.cc @@ -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); } } diff --git a/srsapps/ue/mac/test/CMakeLists.txt b/srsapps/ue/mac/test/CMakeLists.txt index ec65de6fc..0bedf25be 100644 --- a/srsapps/ue/mac/test/CMakeLists.txt +++ b/srsapps/ue/mac/test/CMakeLists.txt @@ -24,5 +24,5 @@ FIND_PACKAGE(openLTE) IF(UHD_FOUND AND OPENLTE_FOUND) INCLUDE_DIRECTORIES(${OPENLTE_INCLUDE_DIRS}) ADD_EXECUTABLE(mac_test mac_test.cc) - TARGET_LINK_LIBRARIES(mac_test srsapps_ue_mac srsapps_ue_phy srsapps_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) diff --git a/srsapps/ue/mac/test/mac_test.cc b/srsapps/ue/mac/test/mac_test.cc index 71d0dd6d6..b954317d8 100644 --- a/srsapps/ue/mac/test/mac_test.cc +++ b/srsapps/ue/mac/test/mac_test.cc @@ -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;irr_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; } diff --git a/srsapps/ue/phy/CMakeLists.txt b/srsapps/ue/phy/CMakeLists.txt index 198ee85d0..911f00073 100644 --- a/srsapps/ue/phy/CMakeLists.txt +++ b/srsapps/ue/phy/CMakeLists.txt @@ -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) diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h index 16b0d1e55..c060012b5 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h @@ -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); diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h index 8e8d6695b..45f862b8f 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h @@ -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; }; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h index 8a4469744..aff04a192 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h @@ -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]); diff --git a/srsapps/ue/phy/src/dl_buffer.cc b/srsapps/ue/phy/src/dl_buffer.cc index f562a9ab0..71891d2cc 100644 --- a/srsapps/ue/phy/src/dl_buffer.cc +++ b/srsapps/ue/phy/src/dl_buffer.cc @@ -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)); } diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index 56472d639..563549456 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -29,9 +29,11 @@ #include #include #include +#include #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); } diff --git a/srsapps/ue/phy/src/ul_buffer.cc b/srsapps/ue/phy/src/ul_buffer.cc index cec870e89..722f9bf4f 100644 --- a/srsapps/ue/phy/src/ul_buffer.cc +++ b/srsapps/ue/phy/src/ul_buffer.cc @@ -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(); } diff --git a/srsapps/ue/phy/test/CMakeLists.txt b/srsapps/ue/phy/test/CMakeLists.txt index 37535af02..d5cc0af97 100644 --- a/srsapps/ue/phy/test/CMakeLists.txt +++ b/srsapps/ue/phy/test/CMakeLists.txt @@ -22,8 +22,8 @@ IF(UHD_FOUND) ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc) - TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_ue_phy srsapps_radio srslte 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) diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 7a0d9b348..e9a234541 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -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; diff --git a/srslte/lib/ch_estimation/src/refsignal_ul.c b/srslte/lib/ch_estimation/src/refsignal_ul.c index 9b6216419..e4fd7dc2a 100644 --- a/srslte/lib/ch_estimation/src/refsignal_ul.c +++ b/srslte/lib/ch_estimation/src/refsignal_ul.c @@ -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)); diff --git a/srslte/lib/common/src/phy_common.c b/srslte/lib/common/src/phy_common.c index 7b2fdd72b..52c226832 100644 --- a/srslte/lib/common/src/phy_common.c +++ b/srslte/lib/common/src/phy_common.c @@ -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"; } diff --git a/srslte/lib/cuhd/src/cuhd_imp.cpp b/srslte/lib/cuhd/src/cuhd_imp.cpp index 0c6ce30c9..ba2809213 100644 --- a/srslte/lib/cuhd/src/cuhd_imp.cpp +++ b/srslte/lib/cuhd/src/cuhd_imp.cpp @@ -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; } diff --git a/srslte/lib/phch/src/dci.c b/srslte/lib/phch/src/dci.c index 0f596eee8..54a9ed702 100644 --- a/srslte/lib/phch/src/dci.c +++ b/srslte/lib/phch/src/dci.c @@ -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; diff --git a/srslte/lib/phch/src/pdcch.c b/srslte/lib/phch/src/pdcch.c index c8627ba21..054761f97 100644 --- a/srslte/lib/phch/src/pdcch.c +++ b/srslte/lib/phch/src/pdcch.c @@ -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;illr[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); diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index 2a103be51..574850d06 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -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; + } } diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index 5e60f8bbe..97ec24e35 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -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 &&