mirror of https://github.com/PentHertz/srsLTE.git
MAC test working
This commit is contained in:
parent
1b2c474f25
commit
7e94f82ab6
|
@ -0,0 +1,18 @@
|
|||
function [ out ] = read_uchar( filename, count )
|
||||
%READ_COMPLEX Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
[tidin msg]=fopen(filename,'r');
|
||||
if (tidin==-1)
|
||||
fprintf('error opening %s: %s\n',filename, msg);
|
||||
out=[];
|
||||
return
|
||||
end
|
||||
|
||||
if (nargin==1)
|
||||
count=inf;
|
||||
end
|
||||
|
||||
out=fread(tidin,count,'uint8');
|
||||
end
|
||||
|
|
@ -1,18 +1,21 @@
|
|||
ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',8,'RNTI',77,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0);
|
||||
puschConfig=struct('NTurboDecIts',5,'NLayers',1,'OrthCover','Off','PRBSet',22,'Modulation','16QAM','RV',0);
|
||||
ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',8,'RNTI',85,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0);
|
||||
puschConfig=struct('NTurboDecIts',5,'NLayers',1,'OrthCover','Off','PRBSet',[23 24]','Modulation','16QAM','RV',0);
|
||||
|
||||
TBS=336;
|
||||
TBS=696;
|
||||
cfo=0;
|
||||
t0=68;
|
||||
x=[rx(t0:end); zeros(t0-1,1)];
|
||||
%t0=1;
|
||||
%x=[rx(t0:end); zeros(t0-1,1)];
|
||||
|
||||
x=rx;
|
||||
|
||||
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);
|
||||
dmrs_rx=subframe_rx(ltePUSCHDRSIndices(ueConfig,puschConfig));
|
||||
[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,TBS,cws);
|
||||
disp(blkcrc)
|
||||
scatter(real(symbols),imag(symbols))
|
||||
%plot(angle(hest(:,1)))
|
||||
%plot(angle(hest))
|
|
@ -1,14 +1,14 @@
|
|||
ueConfig=struct('NCellID',1,'NULRB',25,'RNTI',77,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',22,'Shortened',0);
|
||||
ueConfig=struct('NCellID',1,'NULRB',25,'RNTI',84,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[23 24]','Shortened',0);
|
||||
|
||||
addpath('../../build/srslte/lib/phch/test')
|
||||
|
||||
TBs=[111 336];
|
||||
TBs=696;
|
||||
cqilen=0;
|
||||
rvs=[0 2];
|
||||
rvs=0;
|
||||
mods={'16QAM'};
|
||||
betas=0;
|
||||
subf=[0:9];
|
||||
subf=2;
|
||||
|
||||
for i=1:length(TBs)
|
||||
for m=1:length(mods)
|
||||
|
@ -19,7 +19,7 @@ for i=1:length(TBs)
|
|||
for c=1:length(cqilen)
|
||||
for s=1:length(subf)
|
||||
fprintf('Subf=%d, RV=%d\n', subf(s), rvs(r));
|
||||
trblkin=randi(2,TBs(i),1)-1;
|
||||
trblkin=[0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
|
||||
ueConfig.NSubframe=subf(s);
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
|
@ -41,16 +41,16 @@ for i=1:length(TBs)
|
|||
if (cqilen(c)>0 || TBs(i)>0)
|
||||
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
|
||||
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
|
||||
%drs=ltePUSCHDRS(ueConfig,puschConfig);
|
||||
[drs, infodrs]=ltePUSCHDRS(ueConfig,puschConfig);
|
||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||
%drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
|
||||
drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
|
||||
subframe_mat = lteULResourceGrid(ueConfig);
|
||||
subframe_mat(idx)=cw_mat;
|
||||
%subframe_mat(drs_idx)=drs;
|
||||
subframe_mat(drs_idx)=drs;
|
||||
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=max(abs(waveform-waveform_lib));
|
||||
err=max(abs(waveform/0.2041-waveform_lib));
|
||||
if (err > 10^-5)
|
||||
disp(err)
|
||||
error('Error!');
|
||||
|
|
|
@ -84,14 +84,15 @@ public:
|
|||
uint32_t current_tx_nb;
|
||||
srslte_softbuffer_tx_t *softbuffer;
|
||||
srslte_phy_grant_t phy_grant;
|
||||
uint8_t *payload_ptr;
|
||||
} tb_action_ul_t;
|
||||
|
||||
/* Indicate reception of UL grant.
|
||||
* payload_ptr points to memory where MAC PDU must be written by MAC layer */
|
||||
virtual void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) = 0;
|
||||
virtual void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) = 0;
|
||||
|
||||
/* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */
|
||||
virtual void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) = 0;
|
||||
virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0;
|
||||
|
||||
/* Indicate reception of HARQ information only through PHICH. */
|
||||
virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0;
|
||||
|
@ -134,9 +135,11 @@ public:
|
|||
/* MAC calls RLC to get buffer state for a logical channel. This function should return quickly */
|
||||
virtual uint32_t get_buffer_state(uint32_t lcid) = 0;
|
||||
|
||||
const static int MAX_PDU_SEGMENTS = 20;
|
||||
|
||||
/* MAC calls RLC to get RLC segment of nof_bytes length. Segmentation happens in this function. RLC PDU is stored in
|
||||
* payload. */
|
||||
virtual uint32_t read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||
virtual uint32_t read_pdu(uint32_t lcid, uint8_t *payload, uint32_t segment_idx) = 0;
|
||||
|
||||
/* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. PDU gets placed into the
|
||||
* PDCP buffer and higher layer thread gets notified
|
||||
|
|
|
@ -103,6 +103,7 @@ bool qbuff::push(uint32_t len)
|
|||
packets[wp].len = len;
|
||||
packets[wp].valid = true;
|
||||
wp += (wp+1 >= nof_messages)?(1-nof_messages):1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void* qbuff::pop()
|
||||
|
|
|
@ -119,7 +119,7 @@ bool radio_uhd::tx(void* buffer, uint32_t nof_samples, srslte_timestamp_t tx_tim
|
|||
bool radio_uhd::tx_end()
|
||||
{
|
||||
save_trace(2, &end_of_burst_time);
|
||||
cuhd_send_timed2(uhd, zeros, 0, end_of_burst_time.full_secs, end_of_burst_time.frac_secs, false, true);
|
||||
cuhd_send_timed2(uhd, zeros, 10, end_of_burst_time.full_secs, end_of_burst_time.frac_secs, false, true);
|
||||
is_start_of_burst = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,17 +56,16 @@ public:
|
|||
void release_pdu_bcch(uint8_t *buff, uint32_t nof_bytes);
|
||||
void release_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes);
|
||||
|
||||
bool is_temp_crnti_pending();
|
||||
bool is_contention_resolution_id_pending();
|
||||
void demultiplex_pending_pdu();
|
||||
void discard_pending_pdu();
|
||||
|
||||
uint64_t get_contention_resolution_id();
|
||||
void set_uecrid_callback(bool (*callback)(void*, uint64_t), void *arg);
|
||||
bool get_uecrid_successful();
|
||||
|
||||
private:
|
||||
const static int NOF_PDU_Q = 3; // prevents threads from being locked
|
||||
const static int MAX_PDU_LEN = 128*1024;
|
||||
|
||||
bool (*uecrid_callback) (void*, uint64_t);
|
||||
void *uecrid_callback_arg;
|
||||
|
||||
sch_pdu mac_msg;
|
||||
sch_pdu pending_mac_msg;
|
||||
|
||||
|
@ -77,10 +76,8 @@ private:
|
|||
bool find_nonempty_queue(uint8_t *idx);
|
||||
void push_buffer(uint8_t *buff, uint32_t nof_bytes);
|
||||
|
||||
uint64_t contention_resolution_id;
|
||||
bool pending_temp_rnti;
|
||||
bool has_pending_contention_resolution_id;
|
||||
|
||||
bool is_uecrid_successful;
|
||||
|
||||
typedef struct {
|
||||
uint8_t idx;
|
||||
uint8_t dummy[15]; // FIXME: This it to keep 128-bit alignment
|
||||
|
|
|
@ -58,8 +58,8 @@ public:
|
|||
|
||||
/******** Interface from PHY (PHY -> MAC) ****************/
|
||||
/* see mac_interface.h for comments */
|
||||
void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action);
|
||||
void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action);
|
||||
void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action);
|
||||
void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action);
|
||||
void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action);
|
||||
void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action);
|
||||
void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid);
|
||||
|
@ -136,6 +136,7 @@ private:
|
|||
bool si_search_in_progress;
|
||||
int si_window_length;
|
||||
int si_window_start;
|
||||
bool signals_pregenerated;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ public:
|
|||
bool is_pending_any_sdu();
|
||||
bool is_pending_sdu(uint32_t lcid);
|
||||
|
||||
bool pdu_get(uint8_t *payload, uint32_t pdu_sz);
|
||||
|
||||
bool msg3_get(uint8_t *payload, uint32_t pdu_sz);
|
||||
uint8_t* pdu_get(uint8_t *payload, uint32_t pdu_sz);
|
||||
uint8_t* msg3_get(uint8_t* payload, uint32_t pdu_sz);
|
||||
|
||||
void msg3_flush();
|
||||
bool msg3_is_transmitted();
|
||||
|
||||
|
@ -71,6 +71,8 @@ private:
|
|||
bool allocate_sdu(uint32_t lcid, sch_pdu *pdu, int max_sdu_sz, uint32_t *sdu_sz, bool *is_first);
|
||||
|
||||
const static int NOF_UL_LCH = 10;
|
||||
const static int MIN_RLC_SDU_LEN = 0;
|
||||
const static int MAX_NOF_SUBHEADERS = 20;
|
||||
|
||||
int64_t Bj[NOF_UL_LCH];
|
||||
int PBR[NOF_UL_LCH]; // -1 sets to infinity
|
||||
|
@ -94,6 +96,7 @@ private:
|
|||
/* PDU Buffer */
|
||||
sch_pdu pdu_msg;
|
||||
bool msg3_has_been_transmitted;
|
||||
bool phr_included;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -72,21 +72,15 @@ public:
|
|||
rem_len = pdu_len;
|
||||
}
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
void init(uint32_t pdu_len_bytes) {
|
||||
init(pdu_len_bytes, false);
|
||||
void init_rx(uint8_t *payload, uint32_t pdu_len_bytes, bool is_ulsch = false) {
|
||||
init_(NULL, pdu_len_bytes, is_ulsch);
|
||||
parse_packet(payload);
|
||||
}
|
||||
void init(uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
pdu_is_ul = is_ulsch;
|
||||
reset();
|
||||
for (int i=0;i<max_subheaders;i++) {
|
||||
subheaders[i].init();
|
||||
}
|
||||
|
||||
void init_tx(uint8_t *payload, uint32_t pdu_len_bytes, bool is_ulsch = false) {
|
||||
init_(payload, pdu_len_bytes, is_ulsch);
|
||||
}
|
||||
|
||||
|
||||
uint32_t nof_subh() {
|
||||
return nof_subheaders;
|
||||
}
|
||||
|
@ -124,6 +118,30 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool is_ul() {
|
||||
return pdu_is_ul;
|
||||
}
|
||||
|
||||
uint8_t* get_current_sdu_ptr() {
|
||||
return &buffer_tx[total_sdu_len+sdu_offset_start];
|
||||
}
|
||||
|
||||
void add_sdu(uint32_t sdu_sz) {
|
||||
total_sdu_len += sdu_sz;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<SubH> subheaders;
|
||||
uint32_t pdu_len;
|
||||
uint32_t rem_len;
|
||||
int cur_idx;
|
||||
int nof_subheaders;
|
||||
uint32_t max_subheaders;
|
||||
bool pdu_is_ul;
|
||||
uint8_t* buffer_tx;
|
||||
uint32_t total_sdu_len;
|
||||
uint32_t sdu_offset_start;
|
||||
|
||||
// Section 6.1.2
|
||||
void parse_packet(uint8_t *ptr) {
|
||||
uint8_t *init_ptr = ptr;
|
||||
|
@ -136,20 +154,23 @@ public:
|
|||
subheaders[i].read_payload(&ptr);
|
||||
}
|
||||
}
|
||||
bool is_ul() {
|
||||
return pdu_is_ul;
|
||||
|
||||
private:
|
||||
|
||||
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||
void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||
nof_subheaders = 0;
|
||||
pdu_len = pdu_len_bytes;
|
||||
rem_len = pdu_len;
|
||||
pdu_is_ul = is_ulsch;
|
||||
buffer_tx = buffer_tx_ptr;
|
||||
sdu_offset_start = max_subheaders*2 + 13; // Assuming worst-case 2 bytes per sdu subheader + all possible CE
|
||||
total_sdu_len = 0;
|
||||
reset();
|
||||
for (int i=0;i<max_subheaders;i++) {
|
||||
subheaders[i].init();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool write_packet(uint8_t *ptr, rlc_interface_mac *rlc) = 0;
|
||||
|
||||
protected:
|
||||
std::vector<SubH> subheaders;
|
||||
uint32_t pdu_len;
|
||||
uint32_t rem_len;
|
||||
int cur_idx;
|
||||
int nof_subheaders;
|
||||
uint32_t max_subheaders;
|
||||
bool pdu_is_ul;
|
||||
};
|
||||
|
||||
template<class SubH>
|
||||
|
@ -160,7 +181,7 @@ public:
|
|||
virtual bool read_subheader(uint8_t** ptr) = 0;
|
||||
virtual void read_payload(uint8_t **ptr) = 0;
|
||||
virtual void write_subheader(uint8_t** ptr, bool is_last) = 0;
|
||||
virtual void write_payload(uint8_t **ptr, rlc_interface_mac *rlc) = 0;
|
||||
virtual void write_payload(uint8_t **ptr) = 0;
|
||||
virtual void fprint(FILE *stream) = 0;
|
||||
|
||||
pdu<SubH>* parent;
|
||||
|
@ -177,7 +198,7 @@ class sch_subh : public subh<sch_subh>
|
|||
public:
|
||||
|
||||
typedef enum {
|
||||
PHD_REPORT = 26,
|
||||
PHR_REPORT = 26,
|
||||
C_RNTI = 27,
|
||||
CON_RES_ID = 28,
|
||||
TRUNC_BSR = 28,
|
||||
|
@ -204,18 +225,18 @@ public:
|
|||
uint16_t get_c_rnti();
|
||||
uint64_t get_con_res_id();
|
||||
uint8_t get_ta_cmd();
|
||||
uint8_t get_phd();
|
||||
uint8_t get_phr();
|
||||
|
||||
// Writing functions
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t **ptr, rlc_interface_mac *rlc);
|
||||
bool set_sdu(uint32_t lcid, uint32_t nof_bytes);
|
||||
bool set_sdu(uint32_t lcid, uint32_t nof_bytes, bool is_first);
|
||||
void write_payload(uint8_t **ptr);
|
||||
bool set_sdu(uint32_t lcid, uint32_t requested_bytes, rlc_interface_mac *rlc);
|
||||
bool set_sdu(uint32_t lcid, uint32_t requested_bytes, rlc_interface_mac *rlc, bool is_first);
|
||||
bool set_c_rnti(uint16_t crnti);
|
||||
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);
|
||||
bool set_phr(uint8_t phr);
|
||||
void set_padding();
|
||||
void set_padding(uint32_t padding_len);
|
||||
|
||||
|
@ -240,7 +261,7 @@ public:
|
|||
sch_pdu(uint32_t max_rars) : pdu(max_rars) {}
|
||||
|
||||
void parse_packet(uint8_t *ptr);
|
||||
bool write_packet(uint8_t *ptr, rlc_interface_mac *rlc);
|
||||
uint8_t* write_packet();
|
||||
bool has_space_ce(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes);
|
||||
bool has_space_sdu(uint32_t nbytes, bool is_first);
|
||||
|
@ -270,7 +291,7 @@ public:
|
|||
|
||||
// Writing functoins
|
||||
void write_subheader(uint8_t** ptr, bool is_last);
|
||||
void write_payload(uint8_t** ptr, rlc_interface_mac *rlc);
|
||||
void write_payload(uint8_t** ptr);
|
||||
void set_rapid(uint32_t rapid);
|
||||
void set_ta_cmd(uint32_t ta);
|
||||
void set_temp_crnti(uint16_t temp_rnti);
|
||||
|
@ -296,7 +317,7 @@ public:
|
|||
bool has_backoff();
|
||||
uint8_t get_backoff();
|
||||
|
||||
bool write_packet(uint8_t* ptr, rlc_interface_mac *rlc);
|
||||
bool write_packet(uint8_t* ptr);
|
||||
void fprint(FILE *stream);
|
||||
|
||||
private:
|
||||
|
|
|
@ -69,10 +69,11 @@ class ra_proc : public proc,timer_callback
|
|||
void new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action);
|
||||
void tb_decoded_ok();
|
||||
|
||||
void* run_prach_thread();
|
||||
void start_pcap(mac_pcap* pcap);
|
||||
private:
|
||||
|
||||
static bool uecrid_callback(void *arg, uint64_t uecri);
|
||||
|
||||
bool contention_resolution_id_received(uint64_t uecri);
|
||||
void process_timeadv_cmd(uint32_t ta_cmd);
|
||||
void step_initialization();
|
||||
void step_resource_selection();
|
||||
|
|
|
@ -57,10 +57,8 @@ public:
|
|||
|
||||
|
||||
/***************** PHY->MAC interface for UL processes **************************/
|
||||
void new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t *payload_ptr,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t *payload_ptr, bool ack,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t *action);
|
||||
void new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t *action);
|
||||
void harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t *action);
|
||||
|
||||
|
||||
|
@ -73,12 +71,7 @@ private:
|
|||
void reset();
|
||||
void reset_ndi();
|
||||
|
||||
|
||||
void generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action);
|
||||
void generate_retx(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void generate_new_tx(uint32_t tti_tx, bool is_msg3, mac_interface_phy::mac_grant_t *grant,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action);
|
||||
|
||||
uint32_t get_rv();
|
||||
bool has_grant();
|
||||
|
@ -105,12 +98,20 @@ private:
|
|||
bool is_initiated;
|
||||
uint32_t tti_last_tx;
|
||||
|
||||
const static int payload_buffer_len = 128*1024;
|
||||
uint8_t *payload_buffer;
|
||||
uint8_t *pdu_ptr;
|
||||
|
||||
void generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action);
|
||||
void generate_retx(uint32_t tti_tx, mac_interface_phy::mac_grant_t *grant,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void generate_new_tx(uint32_t tti_tx, bool is_msg3, mac_interface_phy::mac_grant_t *grant,
|
||||
mac_interface_phy::tb_action_ul_t *action);
|
||||
void generate_tx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action);
|
||||
};
|
||||
|
||||
|
||||
void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, uint8_t* payload_ptr,
|
||||
mac_interface_phy::tb_action_ul_t* action);
|
||||
void run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action);
|
||||
void set_ack(uint32_t tti, bool ack);
|
||||
|
||||
ul_sps ul_sps_assig;
|
||||
|
|
|
@ -34,9 +34,6 @@ namespace ue {
|
|||
|
||||
demux::demux() : mac_msg(20), pending_mac_msg(20)
|
||||
{
|
||||
contention_resolution_id = 0;
|
||||
pending_temp_rnti = false;
|
||||
has_pending_contention_resolution_id = false;
|
||||
for (int i=0;i<NOF_PDU_Q;i++) {
|
||||
pdu_q[i].init(8, MAX_PDU_LEN);
|
||||
used_q[i] = false;
|
||||
|
@ -54,21 +51,13 @@ void demux::init(phy_interface* phy_h_, rlc_interface_mac *rlc_, log* log_h_, ti
|
|||
timers_db = timers_db_;
|
||||
}
|
||||
|
||||
bool demux::is_temp_crnti_pending()
|
||||
{
|
||||
return pending_temp_rnti;
|
||||
void demux::set_uecrid_callback(bool (*callback)(void*,uint64_t), void *arg) {
|
||||
uecrid_callback = callback;
|
||||
uecrid_callback_arg = arg;
|
||||
}
|
||||
|
||||
bool demux::is_contention_resolution_id_pending() {
|
||||
return has_pending_contention_resolution_id;
|
||||
}
|
||||
|
||||
uint64_t demux::get_contention_resolution_id()
|
||||
{
|
||||
uint64_t x = contention_resolution_id;
|
||||
contention_resolution_id = 0;
|
||||
has_pending_contention_resolution_id = false;
|
||||
return x;
|
||||
bool demux::get_uecrid_successful() {
|
||||
return is_uecrid_successful;
|
||||
}
|
||||
|
||||
bool demux::find_unused_queue(uint8_t *idx) {
|
||||
|
@ -85,10 +74,14 @@ bool demux::find_unused_queue(uint8_t *idx) {
|
|||
|
||||
// Read packets from queues in round robin
|
||||
bool demux::find_nonempty_queue(uint8_t *idx) {
|
||||
uint32_t start=0;
|
||||
if (idx) {
|
||||
start = *idx;
|
||||
}
|
||||
for (uint8_t i=0;i<NOF_PDU_Q;i++) {
|
||||
if (!pdu_q[(i+*idx)%NOF_PDU_Q].isempty()) {
|
||||
if (!pdu_q[(i+start+1)%NOF_PDU_Q].isempty()) {
|
||||
if (idx) {
|
||||
*idx = i;
|
||||
*idx = (i+start+1)%NOF_PDU_Q;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -102,17 +95,18 @@ uint8_t* demux::request_buffer(uint32_t len)
|
|||
return NULL;
|
||||
}
|
||||
pthread_mutex_lock(&mutex);
|
||||
uint8_t idx;
|
||||
uint8_t idx=0;
|
||||
while(!find_unused_queue(&idx)) {
|
||||
pthread_cond_wait(&cvar, &mutex);
|
||||
}
|
||||
if (idx > 0) {
|
||||
Debug("Using queue %d for MAC PDU\n", idx);
|
||||
printf("Using queue %d for MAC PDU\n", idx);
|
||||
}
|
||||
used_q[idx] = true;
|
||||
uint8_t *buff = (uint8_t*) pdu_q[idx].request();
|
||||
buff_header_t *head = (buff_header_t*) buff;
|
||||
head->idx = idx;
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
return &buff[sizeof(buff_header_t)];
|
||||
|
@ -156,27 +150,21 @@ void demux::release_pdu_bcch(uint8_t *buff, uint32_t nof_bytes)
|
|||
*/
|
||||
void demux::release_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes)
|
||||
{
|
||||
if (!pending_temp_rnti) {
|
||||
// Unpack DLSCH MAC PDU
|
||||
pending_mac_msg.init(nof_bytes);
|
||||
pending_mac_msg.parse_packet(buff);
|
||||
//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;
|
||||
Debug("Found Contention Resolution ID CE\n");
|
||||
}
|
||||
// Unpack DLSCH MAC PDU
|
||||
pending_mac_msg.init_rx(buff, nof_bytes);
|
||||
|
||||
// Look for Contention Resolution UE ID
|
||||
is_uecrid_successful = false;
|
||||
while(pending_mac_msg.next() && !is_uecrid_successful) {
|
||||
if (pending_mac_msg.get()->ce_type() == sch_subh::CON_RES_ID) {
|
||||
Debug("Found Contention Resolution ID CE\n");
|
||||
is_uecrid_successful = uecrid_callback(uecrid_callback_arg, pending_mac_msg.get()->get_con_res_id());
|
||||
}
|
||||
pending_mac_msg.reset();
|
||||
pending_temp_rnti = true;
|
||||
Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
push_buffer(buff, 0);
|
||||
} else {
|
||||
Warning("Error pushing PDU with Temporal C-RNTI: Another PDU is still in pending\n");
|
||||
}
|
||||
|
||||
pending_mac_msg.reset();
|
||||
Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n");
|
||||
push_buffer(buff, nof_bytes);
|
||||
}
|
||||
|
||||
/* Demultiplexing of logical channels and dissassemble of MAC CE
|
||||
|
@ -191,13 +179,13 @@ void demux::release_pdu(uint8_t *buff, uint32_t nof_bytes)
|
|||
void demux::process_pdus()
|
||||
{
|
||||
uint32_t len;
|
||||
uint8_t idx;
|
||||
uint8_t idx=0;
|
||||
while(find_nonempty_queue(&idx)) {
|
||||
uint8_t *mac_pdu = (uint8_t*) pdu_q[idx].pop(&len);
|
||||
if (mac_pdu) {
|
||||
process_pdu(mac_pdu, len);
|
||||
pdu_q[idx].release();
|
||||
process_pdu(&mac_pdu[sizeof(buff_header_t)], len);
|
||||
}
|
||||
pdu_q[idx].release();
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
@ -205,27 +193,10 @@ void demux::process_pdus()
|
|||
void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes)
|
||||
{
|
||||
// Unpack DLSCH MAC PDU
|
||||
mac_msg.init(nof_bytes);
|
||||
mac_msg.parse_packet(mac_pdu);
|
||||
mac_msg.fprint(stdout);
|
||||
mac_msg.init_rx(mac_pdu, nof_bytes);
|
||||
//mac_msg.fprint(stdout);
|
||||
process_sch_pdu(&mac_msg);
|
||||
Debug("Normal MAC PDU processed\n");
|
||||
}
|
||||
|
||||
void demux::discard_pending_pdu()
|
||||
{
|
||||
pending_temp_rnti = false;
|
||||
pending_mac_msg.reset();
|
||||
}
|
||||
|
||||
void demux::demultiplex_pending_pdu()
|
||||
{
|
||||
if (pending_temp_rnti) {
|
||||
process_sch_pdu(&pending_mac_msg);
|
||||
discard_pending_pdu();
|
||||
} else {
|
||||
Error("Error demultiplex pending PDU: No pending PDU\n");
|
||||
}
|
||||
Debug("MAC PDU processed\n");
|
||||
}
|
||||
|
||||
void demux::process_sch_pdu(sch_pdu *pdu_msg)
|
||||
|
@ -246,8 +217,7 @@ void demux::process_sch_pdu(sch_pdu *pdu_msg)
|
|||
bool demux::process_ce(sch_subh *subh) {
|
||||
switch(subh->ce_type()) {
|
||||
case sch_subh::CON_RES_ID:
|
||||
contention_resolution_id = subh->get_c_rnti();
|
||||
Debug("Saved Contention Resolution ID=%d\n", contention_resolution_id);
|
||||
// Do nothing
|
||||
break;
|
||||
case sch_subh::TA_CMD:
|
||||
phy_h->set_timeadv(subh->get_ta_cmd());
|
||||
|
|
|
@ -135,7 +135,7 @@ void dl_harq_entity::tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t
|
|||
bool dl_harq_entity::generate_ack_callback(void *arg)
|
||||
{
|
||||
demux *demux_unit = (demux*) arg;
|
||||
return demux_unit->is_contention_resolution_id_pending();
|
||||
return demux_unit->get_uecrid_successful();
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,6 +225,9 @@ void dl_harq_entity::dl_harq_process::new_grant_dl(mac_interface_phy::mac_grant_
|
|||
|
||||
// Save grant
|
||||
memcpy(&cur_grant, &grant, sizeof(mac_interface_phy::mac_grant_t));
|
||||
|
||||
// Fill action structure
|
||||
bzero(action, sizeof(mac_interface_phy::tb_action_dl_t));
|
||||
action->default_ack = ack;
|
||||
action->generate_ack = true;
|
||||
|
||||
|
@ -242,11 +245,11 @@ void dl_harq_entity::dl_harq_process::new_grant_dl(mac_interface_phy::mac_grant_
|
|||
action->decode_enabled = false;
|
||||
Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t));
|
||||
|
||||
} else {
|
||||
action->decode_enabled = false;
|
||||
Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid);
|
||||
}
|
||||
|
||||
|
@ -255,7 +258,7 @@ void dl_harq_entity::dl_harq_process::new_grant_dl(mac_interface_phy::mac_grant_
|
|||
Debug("Not generating ACK\n");
|
||||
action->generate_ack = false;
|
||||
} else {
|
||||
if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) {
|
||||
if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP && ack == false) {
|
||||
// Postpone ACK after contention resolution is resolved
|
||||
action->generate_ack_callback = harq_entity->generate_ack_callback;
|
||||
action->generate_ack_callback_arg = harq_entity->demux_unit;
|
||||
|
@ -279,6 +282,7 @@ void dl_harq_entity::dl_harq_process::tb_decoded(bool ack_)
|
|||
harq_entity->demux_unit->release_pdu_bcch(payload_buffer_ptr, cur_grant.n_bytes);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (harq_entity->pcap) {
|
||||
harq_entity->pcap->write_dl_crnti(payload_buffer_ptr, cur_grant.n_bytes, cur_grant.rnti, ack, cur_grant.tti);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ mac::mac() : ttisync(10240), timers_db((uint32_t) NOF_MAC_TIMERS)
|
|||
si_search_in_progress = false;
|
||||
si_window_length = -1;
|
||||
si_window_start = -1;
|
||||
signals_pregenerated = false;
|
||||
}
|
||||
|
||||
bool mac::init(phy_interface *phy, rlc_interface_mac *rlc, log *log_h_)
|
||||
|
@ -116,6 +117,8 @@ void mac::reset()
|
|||
phy_h->pdcch_dl_search_reset();
|
||||
phy_h->pdcch_ul_search_reset();
|
||||
|
||||
signals_pregenerated = false;
|
||||
|
||||
params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_ST, -1);
|
||||
params_db.set_param(mac_interface_params::BCCH_SI_WINDOW_LEN, -1);
|
||||
}
|
||||
|
@ -134,10 +137,10 @@ void mac::run_thread() {
|
|||
while(started) {
|
||||
|
||||
/* Warning: Here order of invocation of procedures is important!! */
|
||||
tti = ttisync.wait();
|
||||
tti = (ttisync.wait() + 1)%10240;
|
||||
|
||||
log_h->step(tti);
|
||||
|
||||
|
||||
search_si_rnti();
|
||||
|
||||
// Step all procedures
|
||||
|
@ -170,6 +173,22 @@ void mac::run_thread() {
|
|||
|
||||
ra_procedure.step(tti);
|
||||
//phr_procedure.step(tti);
|
||||
|
||||
// FIXME: Do here DTX and look for UL grants only when needed
|
||||
if (ra_procedure.is_successful() && !signals_pregenerated) {
|
||||
// Configure PHY to look for UL C-RNTI grants
|
||||
uint16_t crnti = params_db.get_param(mac_interface_params::RNTI_C);
|
||||
phy_h->pdcch_ul_search(SRSLTE_RNTI_USER, crnti);
|
||||
phy_h->pdcch_dl_search(SRSLTE_RNTI_USER, crnti);
|
||||
|
||||
// Pregenerate UL signals and C-RNTI scrambling sequences
|
||||
Info("Pre-generating UL signals and C-RNTI scrambling sequences\n");
|
||||
((phy*) phy_h)->enable_pregen_signals(true);
|
||||
((phy*) phy_h)->set_crnti(crnti);
|
||||
phy_h->configure_ul_params();
|
||||
Info("Done\n");
|
||||
signals_pregenerated = true;
|
||||
}
|
||||
|
||||
timers_db.step_all();
|
||||
|
||||
|
@ -246,21 +265,19 @@ uint32_t mac::get_current_tti()
|
|||
return phy_h->get_current_tti();
|
||||
}
|
||||
|
||||
void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr,
|
||||
mac_interface_phy::tb_action_ul_t* action)
|
||||
void mac::new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
if (grant.rnti_type == SRSLTE_RNTI_USER) {
|
||||
if (ra_procedure.is_contention_resolution()) {
|
||||
ra_procedure.pdcch_to_crnti(true);
|
||||
}
|
||||
}
|
||||
ul_harq.new_grant_ul(grant, payload_ptr, action);
|
||||
ul_harq.new_grant_ul(grant, action);
|
||||
}
|
||||
|
||||
void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, bool ack,
|
||||
mac_interface_phy::tb_action_ul_t* action)
|
||||
void mac::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
ul_harq.new_grant_ul_ack(grant, payload_ptr, ack, action);
|
||||
ul_harq.new_grant_ul_ack(grant, ack, action);
|
||||
}
|
||||
|
||||
void mac::tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
namespace srslte {
|
||||
namespace ue {
|
||||
|
||||
mux::mux() : pdu_msg(20)
|
||||
mux::mux() : pdu_msg(MAX_NOF_SUBHEADERS)
|
||||
{
|
||||
msg3_buff.init(1, MSG3_BUFF_SZ);
|
||||
|
||||
|
@ -46,6 +46,8 @@ mux::mux() : pdu_msg(20)
|
|||
BSD[i] = 10;
|
||||
lchid_sorted[i] = i;
|
||||
}
|
||||
phr_included = false;
|
||||
pending_crnti_ce = 0;
|
||||
}
|
||||
|
||||
void mux::init(rlc_interface_mac *rlc_, log *log_h_, bsr_proc *bsr_procedure_)
|
||||
|
@ -60,6 +62,7 @@ void mux::reset()
|
|||
for (int i=0;i<NOF_UL_LCH;i++) {
|
||||
Bj[i] = 0;
|
||||
}
|
||||
pending_crnti_ce = 0;
|
||||
}
|
||||
|
||||
bool mux::is_pending_ccch_sdu()
|
||||
|
@ -127,10 +130,8 @@ sch_subh::cetype bsr_format_convert(bsr_proc::bsr_format_t format) {
|
|||
}
|
||||
|
||||
|
||||
int pkt_num = 0;
|
||||
|
||||
// Multiplexing and logical channel priorization as defined in Section 5.4.3
|
||||
bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
||||
uint8_t* mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
@ -148,7 +149,7 @@ bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
|||
|
||||
// Logical Channel Procedure
|
||||
|
||||
pdu_msg.init(pdu_sz, true);
|
||||
pdu_msg.init_tx(payload, pdu_sz, true);
|
||||
|
||||
// MAC control element for C-RNTI or data from UL-CCCH
|
||||
bool is_first = true;
|
||||
|
@ -164,7 +165,6 @@ bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
|||
}
|
||||
pending_crnti_ce = 0;
|
||||
|
||||
#ifdef kk
|
||||
uint32_t bsr_payload_sz = bsr_procedure->need_to_send_bsr_on_ul_grant(pdu_msg.rem_size());
|
||||
bsr_proc::bsr_t bsr;
|
||||
|
||||
|
@ -178,24 +178,24 @@ bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
|||
pdu_msg.update_space_ce(bsr_payload_sz);
|
||||
}
|
||||
}
|
||||
pkt_num++;
|
||||
// MAC control element for PHR
|
||||
if (pkt_num == 2) {
|
||||
if (!phr_included) {
|
||||
if (pdu_msg.new_subh()) {
|
||||
phr_included = true;
|
||||
pdu_msg.next();
|
||||
pdu_msg.get()->set_phd(46);
|
||||
pdu_msg.get()->set_phr(46);
|
||||
}
|
||||
}
|
||||
|
||||
// data from any Logical Channel, except data from UL-CCCH;
|
||||
// first only those with positive Bj
|
||||
uint32_t sdu_sz = 0;
|
||||
for (int i=0;i<1;i++) {
|
||||
for (int i=1;i<NOF_UL_LCH;i++) {
|
||||
uint32_t lcid = lchid_sorted[i];
|
||||
if (lcid != 0) {
|
||||
bool res = true;
|
||||
while ((Bj[lcid] > 0 || PBR[lcid] < 0) && res) {
|
||||
res = allocate_sdu(lcid, &pdu_msg, Bj[lcid], &sdu_sz, &is_first);
|
||||
res = allocate_sdu(lcid, &pdu_msg, (PBR[lcid]<0)?-1:Bj[lcid], &sdu_sz, &is_first);
|
||||
if (res && PBR[lcid] >= 0) {
|
||||
Bj[lcid] -= sdu_sz;
|
||||
}
|
||||
|
@ -221,19 +221,13 @@ bool mux::pdu_get(uint8_t *payload, uint32_t pdu_sz)
|
|||
if (bsr_subh) {
|
||||
bsr_subh->set_bsr(bsr.buff_size, bsr_format_convert(bsr.format), bsr_payload_sz?false:true);
|
||||
}
|
||||
#endif
|
||||
pdu_msg.fprint(stdout);
|
||||
Debug("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.size(), pdu_sz);
|
||||
|
||||
Debug("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.size(), pdu_sz);
|
||||
//pdu_msg.fprint(stdout);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
/* Generate MAC PDU and save to buffer */
|
||||
if (!pdu_msg.write_packet(payload, rlc)) {
|
||||
Error("Writing PDU message to packet\n");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return pdu_msg.write_packet();
|
||||
}
|
||||
|
||||
void mux::append_crnti_ce_next_tx(uint16_t crnti) {
|
||||
|
@ -253,33 +247,37 @@ bool mux::allocate_sdu(uint32_t lcid, sch_pdu *pdu_msg, int max_sdu_sz, uint32_t
|
|||
{
|
||||
|
||||
// Get n-th pending SDU pointer and length
|
||||
uint32_t sdu_len = rlc->get_buffer_state(lcid);
|
||||
int sdu_len = rlc->get_buffer_state(lcid);
|
||||
|
||||
if (sdu_len > 0) { // there is pending SDU to allocate
|
||||
Debug("%d bytes pending on RLC buffer. Maximum rate=%d, available space=%d\n",
|
||||
Info("%d bytes pending on RLC buffer. Maximum rate=%d, available space=%d\n",
|
||||
sdu_len, max_sdu_sz, pdu_msg->rem_size() - 2);
|
||||
|
||||
if (sdu_len > max_sdu_sz && max_sdu_sz >= 0) {
|
||||
sdu_len = max_sdu_sz;
|
||||
}
|
||||
if (sdu_len > pdu_msg->rem_size() - 2) {
|
||||
sdu_len = pdu_msg->rem_size() - 2;
|
||||
}
|
||||
if (pdu_msg->new_subh()) { // there is space for a new subheader
|
||||
pdu_msg->next();
|
||||
if (pdu_msg->get()->set_sdu(lcid, sdu_len, is_first?*is_first:false)) { // new SDU could be added
|
||||
if (is_first) {
|
||||
*is_first = false;
|
||||
if (sdu_len > MIN_RLC_SDU_LEN) {
|
||||
if (pdu_msg->new_subh()) { // there is space for a new subheader
|
||||
pdu_msg->next();
|
||||
if (pdu_msg->get()->set_sdu(lcid, sdu_len, rlc, is_first?*is_first:false)) { // new SDU could be added
|
||||
if (is_first) {
|
||||
*is_first = false;
|
||||
}
|
||||
if (sdu_sz) {
|
||||
*sdu_sz = sdu_len;
|
||||
}
|
||||
|
||||
Info("Allocated SDU lcid=%d nbytes=%d\n", lcid, sdu_len);
|
||||
return true;
|
||||
} else {
|
||||
Info("Could not add SDU rem_size=%d, sdu_len=%d\n", pdu_msg->rem_size(), sdu_len);
|
||||
pdu_msg->del_subh();
|
||||
}
|
||||
if (sdu_sz) {
|
||||
*sdu_sz = sdu_len;
|
||||
}
|
||||
Info("Allocated SDU lcid=%d nbytes=%d\n", lcid, sdu_len);
|
||||
return true;
|
||||
} else {
|
||||
Error("Could not add SDU rem_size=%d, sdu_len=%d\n", pdu_msg->rem_size(), sdu_len);
|
||||
pdu_msg->del_subh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -298,9 +296,11 @@ bool mux::msg3_is_transmitted()
|
|||
|
||||
bool mux::pdu_move_to_msg3(uint32_t pdu_sz)
|
||||
{
|
||||
uint8_t *msg3 = (uint8_t*) msg3_buff.request();
|
||||
if (msg3) {
|
||||
if (pdu_get(msg3, pdu_sz)) {
|
||||
uint8_t *msg3_start = (uint8_t*) msg3_buff.request();
|
||||
if (msg3_start) {
|
||||
uint8_t *msg3_pdu = pdu_get(msg3_start, pdu_sz);
|
||||
if (msg3_pdu) {
|
||||
memmove(msg3_start, msg3_pdu, pdu_sz*sizeof(uint8_t));
|
||||
msg3_buff.push(pdu_sz);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -313,7 +313,7 @@ bool mux::pdu_move_to_msg3(uint32_t pdu_sz)
|
|||
}
|
||||
|
||||
/* Returns a pointer to the Msg3 buffer */
|
||||
bool mux::msg3_get(uint8_t *payload, uint32_t pdu_sz)
|
||||
uint8_t* mux::msg3_get(uint8_t *payload, uint32_t pdu_sz)
|
||||
{
|
||||
if (pdu_move_to_msg3(pdu_sz)) {
|
||||
uint8_t *msg3 = (uint8_t*) msg3_buff.pop();
|
||||
|
@ -321,13 +321,12 @@ bool mux::msg3_get(uint8_t *payload, uint32_t pdu_sz)
|
|||
memcpy(payload, msg3, sizeof(uint8_t)*pdu_sz);
|
||||
msg3_buff.release();
|
||||
msg3_has_been_transmitted = true;
|
||||
srslte_vec_fprint_byte(stdout, payload, pdu_sz);
|
||||
return true;
|
||||
return payload;
|
||||
} else {
|
||||
Error("Generating Msg3\n");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,10 +50,10 @@ void sch_subh::fprint(FILE* stream)
|
|||
if (parent->is_ul()) {
|
||||
switch(lcid) {
|
||||
case C_RNTI:
|
||||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
fprintf(stream, "C-RNTI CE\n");
|
||||
break;
|
||||
case PHD_REPORT:
|
||||
fprintf(stream, "C-RNTI CE: %d\n", get_c_rnti());
|
||||
case PHR_REPORT:
|
||||
fprintf(stream, "PHR\n");
|
||||
break;
|
||||
case TRUNC_BSR:
|
||||
fprintf(stream, "Truncated BSR CE\n");
|
||||
|
@ -104,23 +104,51 @@ void sch_pdu::parse_packet(uint8_t *ptr)
|
|||
}
|
||||
|
||||
// Section 6.1.2
|
||||
bool sch_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc)
|
||||
uint8_t* sch_pdu::write_packet()
|
||||
{
|
||||
uint8_t *init_ptr = ptr;
|
||||
bool last_is_padding = false;
|
||||
|
||||
// Find last SDU or CE
|
||||
int last_sh;
|
||||
int last_sh = 0;
|
||||
int last_sdu = nof_subheaders-1;
|
||||
while(!subheaders[last_sdu].is_sdu() && last_sdu > 0) {
|
||||
last_sdu--;
|
||||
bool is_sdu = false;
|
||||
while(last_sdu >= 0 && !is_sdu) {
|
||||
is_sdu = subheaders[last_sdu].is_sdu();
|
||||
if (!is_sdu && last_sdu>=0) {
|
||||
last_sdu--;
|
||||
}
|
||||
}
|
||||
int last_ce = nof_subheaders-1;
|
||||
while(subheaders[last_ce].is_sdu() && last_ce > 0) {
|
||||
last_ce--;
|
||||
is_sdu = true;
|
||||
while(last_ce >= 0 && is_sdu) {
|
||||
is_sdu = subheaders[last_ce].is_sdu();
|
||||
if (is_sdu && last_ce>=0) {
|
||||
last_ce--;
|
||||
}
|
||||
}
|
||||
if (last_sdu >=0 ) {
|
||||
last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
|
||||
}
|
||||
last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
|
||||
|
||||
// Add subheaders and MAC CE before SDU's
|
||||
uint32_t head_and_ce_sz = pdu_len-total_sdu_len;
|
||||
if (rem_len < 2) {
|
||||
head_and_ce_sz -= rem_len;
|
||||
} else {
|
||||
head_and_ce_sz -= rem_len - 2;
|
||||
}
|
||||
if (head_and_ce_sz >= sdu_offset_start) {
|
||||
fprintf(stderr, "Writting PDU: head_and_ce_sz<sdu_offset_start (%d<%d)\n", head_and_ce_sz, sdu_offset_start);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *ptr = &buffer_tx[sdu_offset_start-head_and_ce_sz];
|
||||
uint8_t *pdu_start_ptr = ptr;
|
||||
|
||||
//printf("Head + CE size: %d bytes, data start 0x%x, pdu_len=%d, total_sdu_len=%d, rem_len=%d\n",
|
||||
// head_and_ce_sz, buffer_tx[sdu_offset_start], pdu_len, total_sdu_len, rem_len);
|
||||
|
||||
|
||||
// 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) {
|
||||
|
@ -135,7 +163,7 @@ bool sch_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc)
|
|||
}
|
||||
rem_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last_is_padding) {
|
||||
last_sh = -1;
|
||||
}
|
||||
|
@ -156,21 +184,17 @@ bool sch_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc)
|
|||
padding.set_padding(rem_len);
|
||||
padding.write_subheader(&ptr, true);
|
||||
}
|
||||
// Write payloads in the same order
|
||||
// Write CE payloads (SDU payloads already in the buffer)
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (!subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr, rlc);
|
||||
}
|
||||
}
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
if (subheaders[i].is_sdu()) {
|
||||
subheaders[i].write_payload(&ptr, rlc);
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t));
|
||||
|
||||
return true;
|
||||
bzero(&pdu_start_ptr[pdu_len-rem_len], rem_len*sizeof(uint8_t));
|
||||
|
||||
return pdu_start_ptr;
|
||||
}
|
||||
|
||||
uint32_t sch_pdu::rem_size() {
|
||||
|
@ -240,7 +264,7 @@ void sch_subh::init()
|
|||
|
||||
sch_subh::cetype sch_subh::ce_type()
|
||||
{
|
||||
if (lcid >= PHD_REPORT) {
|
||||
if (lcid >= PHR_REPORT) {
|
||||
return (cetype) lcid;
|
||||
} else {
|
||||
return SDU;
|
||||
|
@ -263,7 +287,7 @@ uint32_t sch_subh::sizeof_ce(uint32_t lcid, bool is_ul)
|
|||
{
|
||||
if (is_ul) {
|
||||
switch(lcid) {
|
||||
case PHD_REPORT:
|
||||
case PHR_REPORT:
|
||||
return 1;
|
||||
case C_RNTI:
|
||||
return 2;
|
||||
|
@ -304,13 +328,13 @@ uint16_t sch_subh::get_c_rnti()
|
|||
uint64_t sch_subh::get_con_res_id()
|
||||
{
|
||||
if (payload) {
|
||||
return ((uint64_t) payload[0]) | ((uint64_t) payload[1])<<8 | ((uint64_t) payload[2])<<16 | ((uint64_t) payload[3])<<24 |
|
||||
((uint64_t) payload[4])<<32 | ((uint64_t) payload[5])<<48;
|
||||
return ((uint64_t) payload[5]) | (((uint64_t) payload[4])<<8) | (((uint64_t) payload[3])<<16) | (((uint64_t) payload[2])<<24) |
|
||||
(((uint64_t) payload[1])<<32) | (((uint64_t) payload[0])<<40);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
uint8_t sch_subh::get_phd()
|
||||
uint8_t sch_subh::get_phr()
|
||||
{
|
||||
if (payload) {
|
||||
return (uint8_t) payload[0]&0x3f;
|
||||
|
@ -404,11 +428,11 @@ bool sch_subh::set_con_res_id(uint64_t con_res_id)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
bool sch_subh::set_phd(uint8_t phd)
|
||||
bool sch_subh::set_phr(uint8_t phr)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(1)) {
|
||||
w_payload_ce[0] = phd&0x3f;
|
||||
lcid = PHD_REPORT;
|
||||
w_payload_ce[0] = phr&0x3f;
|
||||
lcid = PHR_REPORT;
|
||||
((sch_pdu*)parent)->update_space_ce(1);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -428,17 +452,26 @@ bool sch_subh::set_ta_cmd(uint8_t ta_cmd)
|
|||
}
|
||||
}
|
||||
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_)
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_, rlc_interface_mac *rlc)
|
||||
{
|
||||
return set_sdu(lcid_, nof_bytes_, false);
|
||||
return set_sdu(lcid_, nof_bytes_, rlc, false);
|
||||
}
|
||||
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_, bool is_first)
|
||||
bool sch_subh::set_sdu(uint32_t lcid_, uint32_t requested_bytes, rlc_interface_mac *rlc, bool is_first)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_sdu(nof_bytes_, is_first)) {
|
||||
nof_bytes = nof_bytes_;
|
||||
if (((sch_pdu*)parent)->has_space_sdu(requested_bytes, is_first)) {
|
||||
lcid = lcid_;
|
||||
((sch_pdu*)parent)->update_space_sdu(nof_bytes_, is_first);
|
||||
|
||||
payload = ((sch_pdu*)parent)->get_current_sdu_ptr();
|
||||
|
||||
// Copy data and get final number of bytes written to the MAC PDU
|
||||
uint32_t sdu_sz = rlc->read_pdu(lcid, payload, requested_bytes);
|
||||
|
||||
// Save final number of written bytes
|
||||
nof_bytes = sdu_sz;
|
||||
|
||||
((sch_pdu*)parent)->add_sdu(nof_bytes);
|
||||
((sch_pdu*)parent)->update_space_sdu(sdu_sz, is_first);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -447,10 +480,10 @@ bool sch_subh::set_sdu(uint32_t lcid_, uint32_t nof_bytes_, bool is_first)
|
|||
// Section 6.2.1
|
||||
void sch_subh::write_subheader(uint8_t** ptr, bool is_last)
|
||||
{
|
||||
*(*ptr) = (uint8_t) (is_last?0:(1<<5)) | ((uint8_t) lcid & 0x1f);
|
||||
*ptr += 1;
|
||||
if (is_sdu()) {
|
||||
// MAC SDU: R/R/E/LCID/F/L subheader
|
||||
*(*ptr) = (uint8_t) !is_last<<5 | (lcid & 0x1f);
|
||||
*ptr += 1;
|
||||
// 2nd and 3rd octet
|
||||
if (!is_last) {
|
||||
if (nof_bytes >= 128) {
|
||||
|
@ -463,18 +496,13 @@ void sch_subh::write_subheader(uint8_t** ptr, bool is_last)
|
|||
*ptr += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// MAC CE: R/R/E/LCID MAC Subheader
|
||||
*(*ptr) = (uint8_t) is_last<<5 | (lcid & 0x1f);
|
||||
*ptr += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sch_subh::write_payload(uint8_t** ptr, rlc_interface_mac *rlc)
|
||||
void sch_subh::write_payload(uint8_t** ptr)
|
||||
{
|
||||
if (is_sdu()) {
|
||||
// Read data from RLC interface
|
||||
rlc->read_pdu(lcid, *ptr, nof_bytes);
|
||||
// SDU is written directly during subheader creation
|
||||
} else {
|
||||
nof_bytes = sizeof_ce(lcid, parent->is_ul());
|
||||
memcpy(*ptr, w_payload_ce, nof_bytes*sizeof(uint8_t));
|
||||
|
@ -485,12 +513,12 @@ void sch_subh::write_payload(uint8_t** ptr, rlc_interface_mac *rlc)
|
|||
bool sch_subh::read_subheader(uint8_t** ptr)
|
||||
{
|
||||
// Skip R
|
||||
bool e_bit = (bool) *(*ptr) & 0x20;
|
||||
bool e_bit = (bool) (*(*ptr) & 0x20)?true:false;
|
||||
lcid = (uint8_t) *(*ptr) & 0x1f;
|
||||
*ptr += 1;
|
||||
if (is_sdu()) {
|
||||
if (e_bit) {
|
||||
F_bit = (bool) *(*ptr) & 0x80;
|
||||
F_bit = (bool) (*(*ptr) & 0x80)?true:false;
|
||||
nof_bytes = (uint32_t)*(*ptr) & 0x7f;
|
||||
*ptr += 1;
|
||||
if (F_bit) {
|
||||
|
@ -580,7 +608,7 @@ void rar_pdu::set_backoff(uint8_t bi)
|
|||
}
|
||||
|
||||
// Section 6.1.5
|
||||
bool rar_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc)
|
||||
bool rar_pdu::write_packet(uint8_t* ptr)
|
||||
{
|
||||
// Write Backoff Indicator, if any
|
||||
if (has_backoff_indicator) {
|
||||
|
@ -594,7 +622,7 @@ bool rar_pdu::write_packet(uint8_t* ptr, rlc_interface_mac *rlc)
|
|||
}
|
||||
// Write payload
|
||||
for (int i=0;i<nof_subheaders;i++) {
|
||||
subheaders[i].write_payload(&ptr, rlc);
|
||||
subheaders[i].write_payload(&ptr);
|
||||
}
|
||||
// Set paddint to zeros (if any)
|
||||
bzero(ptr, rem_len*sizeof(uint8_t));
|
||||
|
@ -649,7 +677,7 @@ void rar_subh::write_subheader(uint8_t** ptr, bool is_last)
|
|||
*ptr += 1;
|
||||
}
|
||||
// Section 6.2.3
|
||||
void rar_subh::write_payload(uint8_t** ptr, rlc_interface_mac *rlc)
|
||||
void rar_subh::write_payload(uint8_t** ptr)
|
||||
{
|
||||
*(*ptr + 0) = (uint8_t) (ta&0x7f0)>>4;
|
||||
*(*ptr + 1) = (uint8_t) (ta&0xf) <<4 | grant[0]<<3 | grant[1] << 2 | grant[2] << 1 | grant[3];
|
||||
|
@ -664,7 +692,6 @@ void rar_subh::write_payload(uint8_t** ptr, rlc_interface_mac *rlc)
|
|||
void rar_subh::read_payload(uint8_t** ptr)
|
||||
{
|
||||
ta = ((uint32_t) *(*ptr + 0)&0x7f)<<4 | (*(*ptr + 1)&0xf0)>>4;
|
||||
printf("ta=%d, 0x%x\n", ta, ta);
|
||||
grant[0] = *(*ptr + 1)&0x8;
|
||||
grant[1] = *(*ptr + 1)&0x4;
|
||||
grant[2] = *(*ptr + 1)&0x2;
|
||||
|
|
|
@ -260,9 +260,8 @@ void ra_proc::tb_decoded_ok() {
|
|||
|
||||
rDebug("RAR decoded successfully TBS=%d\n", rar_grant_nbytes);
|
||||
|
||||
rar_pdu_msg.init(rar_grant_nbytes);
|
||||
rar_pdu_msg.parse_packet(rar_pdu_buffer);
|
||||
srslte_vec_fprint_byte(stdout, rar_pdu_buffer, rar_grant_nbytes);
|
||||
rar_pdu_msg.init_rx(rar_pdu_buffer, rar_grant_nbytes);
|
||||
|
||||
// Set Backoff parameter
|
||||
if (rar_pdu_msg.has_backoff()) {
|
||||
backoff_param_ms = backoff_table[rar_pdu_msg.get_backoff()%16];
|
||||
|
@ -273,7 +272,7 @@ void ra_proc::tb_decoded_ok() {
|
|||
while(rar_pdu_msg.next()) {
|
||||
if (rar_pdu_msg.get()->get_rapid() == sel_preamble) {
|
||||
rInfo("Received RAPID=%d\n", sel_preamble);
|
||||
rar_pdu_msg.fprint(stdout);
|
||||
|
||||
process_timeadv_cmd(rar_pdu_msg.get()->get_ta_cmd());
|
||||
|
||||
// FIXME: Indicate received target power
|
||||
|
@ -292,6 +291,7 @@ void ra_proc::tb_decoded_ok() {
|
|||
} else {
|
||||
// Preamble selected by UE MAC
|
||||
params_db->set_param(mac_interface_params::RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti());
|
||||
phy_h->pdcch_dl_search(SRSLTE_RNTI_TEMP, rar_pdu_msg.get()->get_temp_crnti());
|
||||
|
||||
if (first_rar_received) {
|
||||
first_rar_received = false;
|
||||
|
@ -299,14 +299,13 @@ void ra_proc::tb_decoded_ok() {
|
|||
// Save transmitted C-RNTI (if any)
|
||||
transmitted_crnti = params_db->get_param(mac_interface_params::RNTI_C);
|
||||
|
||||
// Save transmitted UE contention id, as defined by higher layers
|
||||
transmitted_contention_id = params_db->get_param(mac_interface_params::CONTENTION_ID);
|
||||
params_db->set_param(mac_interface_params::CONTENTION_ID, 0);
|
||||
|
||||
// If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission
|
||||
if (transmitted_crnti) {
|
||||
mux_unit->append_crnti_ce_next_tx(transmitted_crnti);
|
||||
}
|
||||
|
||||
// Tell demux to call us when a UE CRID is received
|
||||
demux_unit->set_uecrid_callback(uecrid_callback, this);
|
||||
}
|
||||
rDebug("Going to Contention Resolution state\n");
|
||||
state = CONTENTION_RESOLUTION;
|
||||
|
@ -355,9 +354,52 @@ void ra_proc::step_backoff_wait() {
|
|||
}
|
||||
}
|
||||
|
||||
bool ra_proc::uecrid_callback(void *arg, uint64_t uecri) {
|
||||
return ((ra_proc*) arg)->contention_resolution_id_received(uecri);
|
||||
}
|
||||
|
||||
// Random Access initiated by RRC by the transmission of CCCH SDU
|
||||
bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id) {
|
||||
bool uecri_successful = false;
|
||||
|
||||
rDebug("MAC PDU Contains Contention Resolution ID CE\n");
|
||||
|
||||
// MAC PDU successfully decoded and contains MAC CE contention Id
|
||||
timers_db->get(mac::CONTENTION_TIMER)->stop();
|
||||
|
||||
if (transmitted_contention_id == rx_contention_id)
|
||||
{
|
||||
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_interface_params::RNTI_C, params_db->get_param(mac_interface_params::RNTI_TEMP));
|
||||
// finish the disassembly and demultiplexing of the MAC PDU
|
||||
uecri_successful = true;
|
||||
state = COMPLETION;
|
||||
} else {
|
||||
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%lx != 0x%lx)\n",
|
||||
transmitted_contention_id, rx_contention_id);
|
||||
// Discard MAC PDU
|
||||
uecri_successful = false;
|
||||
|
||||
// Contention Resolution not successfully is like RAR not successful
|
||||
// FIXME: Need to flush Msg3 HARQ buffer. Why?
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
params_db->set_param(mac_interface_params::RNTI_TEMP, 0);
|
||||
|
||||
return uecri_successful;
|
||||
}
|
||||
|
||||
void ra_proc::step_contention_resolution() {
|
||||
// If Msg3 has been sent
|
||||
if (mux_unit->msg3_is_transmitted()) {
|
||||
if (mux_unit->msg3_is_transmitted())
|
||||
{
|
||||
// Save transmitted UE contention id, as defined by higher layers
|
||||
if (!transmitted_contention_id) {
|
||||
transmitted_contention_id = params_db->get_param(mac_interface_params::CONTENTION_ID);
|
||||
params_db->set_param(mac_interface_params::CONTENTION_ID, 0);
|
||||
}
|
||||
|
||||
msg3_transmitted = true;
|
||||
if (pdcch_to_crnti_received != PDCCH_CRNTI_NOT_RECEIVED)
|
||||
{
|
||||
|
@ -370,36 +412,9 @@ void ra_proc::step_contention_resolution() {
|
|||
params_db->set_param(mac_interface_params::RNTI_TEMP, 0);
|
||||
state = COMPLETION;
|
||||
}
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
||||
|
||||
} else if (demux_unit->is_temp_crnti_pending())
|
||||
{
|
||||
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()) {
|
||||
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) {
|
||||
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_interface_params::RNTI_C, params_db->get_param(mac_interface_params::RNTI_TEMP));
|
||||
// finish the disassembly and demultiplexing of the MAC PDU
|
||||
demux_unit->demultiplex_pending_pdu();
|
||||
state = COMPLETION;
|
||||
} else {
|
||||
rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%lx != 0x%lx)\n", transmitted_contention_id, rx_contention_id);
|
||||
// Discard MAC PDU
|
||||
demux_unit->discard_pending_pdu();
|
||||
|
||||
// Contention Resolution not successfully is like RAR not successful
|
||||
// FIXME: Need to flush Msg3 HARQ buffer. Why?
|
||||
state = RESPONSE_ERROR;
|
||||
}
|
||||
params_db->set_param(mac_interface_params::RNTI_TEMP, 0);
|
||||
}
|
||||
}
|
||||
pdcch_to_crnti_received = PDCCH_CRNTI_NOT_RECEIVED;
|
||||
}
|
||||
// RA initiated by RLC order is resolved in contention_resolution_id_received() callback function
|
||||
} else {
|
||||
rDebug("Msg3 not yet transmitted\n");
|
||||
}
|
||||
|
@ -410,7 +425,7 @@ void ra_proc::step_completition() {
|
|||
params_db->set_param(mac_interface_params::RA_PREAMBLEINDEX, 0);
|
||||
params_db->set_param(mac_interface_params::RA_MASKINDEX, 0);
|
||||
mux_unit->msg3_flush();
|
||||
msg3_transmitted = false;
|
||||
msg3_transmitted = false;
|
||||
}
|
||||
|
||||
void ra_proc::step(uint32_t tti_)
|
||||
|
|
|
@ -57,7 +57,7 @@ void sr_proc::step(uint32_t tti)
|
|||
if (params_db->get_param(mac_interface_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) {
|
||||
if (last_tx_tti >= 0 && last_tx_tti + 4 < tti || sr_counter == 0) {
|
||||
sr_counter++;
|
||||
Info("SR signalling PHY. sr_counter=%d, PHY TTI=%d\n", sr_counter, phy_h->get_current_tti());
|
||||
phy_h->sr_send();
|
||||
|
|
|
@ -85,12 +85,11 @@ void ul_harq_entity::set_ack(uint32_t tti, bool ack) {
|
|||
void ul_harq_entity::harq_recv(uint32_t tti, bool ack, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
set_ack(tti, ack);
|
||||
run_tti(tti, NULL, NULL, action);
|
||||
run_tti(tti, NULL, action);
|
||||
}
|
||||
|
||||
// Implements Section 5.4.1
|
||||
void ul_harq_entity::new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr,
|
||||
mac_interface_phy::tb_action_ul_t* action)
|
||||
void ul_harq_entity::new_grant_ul(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
if (grant.rnti_type == SRSLTE_RNTI_USER ||
|
||||
grant.rnti_type == SRSLTE_RNTI_TEMP ||
|
||||
|
@ -99,76 +98,34 @@ void ul_harq_entity::new_grant_ul(mac_interface_phy::mac_grant_t grant, uint8_t*
|
|||
if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) {
|
||||
grant.ndi = true;
|
||||
}
|
||||
run_tti(grant.tti, &grant, payload_ptr, action);
|
||||
run_tti(grant.tti, &grant, action);
|
||||
} else if (grant.rnti_type == SRSLTE_RNTI_SPS) {
|
||||
if (grant.ndi) {
|
||||
grant.ndi = proc[pidof(grant.tti)].get_ndi();
|
||||
run_tti(grant.tti, &grant, payload_ptr, action);
|
||||
run_tti(grant.tti, &grant, action);
|
||||
} else {
|
||||
Info("Not implemented\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ul_harq_entity::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, uint8_t* payload_ptr, bool ack,
|
||||
mac_interface_phy::tb_action_ul_t* action)
|
||||
void ul_harq_entity::new_grant_ul_ack(mac_interface_phy::mac_grant_t grant, bool ack, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
set_ack(grant.tti, ack);
|
||||
new_grant_ul(grant, payload_ptr, action);
|
||||
new_grant_ul(grant, action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Implements Section 5.4.2.1
|
||||
// Called with UL grant
|
||||
void ul_harq_entity::run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, uint8_t* payload_ptr,
|
||||
mac_interface_phy::tb_action_ul_t* action)
|
||||
void ul_harq_entity::run_tti(uint32_t tti, mac_interface_phy::mac_grant_t *grant, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
|
||||
uint32_t tti_tx = (tti+4)%10240;
|
||||
uint32_t pid = pidof(tti_tx);
|
||||
|
||||
// Receive and route HARQ feedbacks
|
||||
if (grant) {
|
||||
if ((!grant->rnti_type == SRSLTE_RNTI_TEMP && grant->ndi != proc[pid].get_ndi()) ||
|
||||
(grant->rnti_type == SRSLTE_RNTI_USER && !proc[pid].has_grant()) ||
|
||||
grant->is_from_rar)
|
||||
{
|
||||
// New transmission
|
||||
|
||||
// Uplink grant in a RAR
|
||||
if (grant->is_from_rar) {
|
||||
if (mux_unit->msg3_get(payload_ptr, grant->n_bytes)) {
|
||||
proc[pid].generate_new_tx(tti_tx, true, grant, action);
|
||||
} else {
|
||||
Warning("UL RAR grant available but no Msg3 on buffer\n");
|
||||
}
|
||||
|
||||
// Normal UL grant
|
||||
} else {
|
||||
// Request a MAC PDU from the Multiplexing & Assemble Unit
|
||||
if (mux_unit->pdu_get(payload_ptr, grant->n_bytes)) {
|
||||
proc[pid].generate_new_tx(tti_tx, false, grant, action);
|
||||
} else {
|
||||
Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Adaptive Re-TX
|
||||
proc[pid].generate_retx(tti_tx, grant, action);
|
||||
}
|
||||
} else if (proc[pid].has_grant()) {
|
||||
// Non-Adaptive Re-Tx
|
||||
proc[pid].generate_retx(tti_tx, action);
|
||||
}
|
||||
if (pcap) {
|
||||
pcap->write_ul_crnti(payload_ptr, grant->n_bytes, grant->rnti, proc[pid].get_nof_retx(), tti_tx);
|
||||
}
|
||||
|
||||
proc[pidof(tti_tx)].run_tti(tti_tx, grant, action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* HARQ PROCESS
|
||||
|
@ -236,10 +193,59 @@ bool ul_harq_entity::ul_harq_process::init(uint32_t pid_, ul_harq_entity* parent
|
|||
harq_entity = parent;
|
||||
log_h = harq_entity->log_h;
|
||||
pid = pid_;
|
||||
payload_buffer = (uint8_t*) srslte_vec_malloc(payload_buffer_len*sizeof(uint8_t));
|
||||
if (!payload_buffer) {
|
||||
Error("Allocating memory\n");
|
||||
return false;
|
||||
}
|
||||
pdu_ptr = payload_buffer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::run_tti(uint32_t tti_tx, mac_interface_phy::mac_grant_t* grant, mac_interface_phy::tb_action_ul_t* action)
|
||||
{
|
||||
// Receive and route HARQ feedbacks
|
||||
if (grant) {
|
||||
if ((!grant->rnti_type == SRSLTE_RNTI_TEMP && grant->ndi != get_ndi()) ||
|
||||
(grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) ||
|
||||
grant->is_from_rar)
|
||||
{
|
||||
// New transmission
|
||||
|
||||
// Uplink grant in a RAR
|
||||
if (grant->is_from_rar) {
|
||||
pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes);
|
||||
if (pdu_ptr) {
|
||||
generate_new_tx(tti_tx, true, grant, action);
|
||||
} else {
|
||||
Warning("UL RAR grant available but no Msg3 on buffer\n");
|
||||
}
|
||||
|
||||
// Normal UL grant
|
||||
} else {
|
||||
// Request a MAC PDU from the Multiplexing & Assemble Unit
|
||||
pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes);
|
||||
if (pdu_ptr) {
|
||||
generate_new_tx(tti_tx, false, grant, action);
|
||||
} else {
|
||||
Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Adaptive Re-TX
|
||||
generate_retx(tti_tx, grant, action);
|
||||
}
|
||||
} else if (has_grant()) {
|
||||
// Non-Adaptive Re-Tx
|
||||
generate_retx(tti_tx, action);
|
||||
}
|
||||
if (harq_entity->pcap) {
|
||||
harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes, grant->rnti, get_nof_retx(), tti_tx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, mac_interface_phy::tb_action_ul_t *action)
|
||||
{
|
||||
generate_retx(tti_tx, NULL, action);
|
||||
|
@ -300,6 +306,7 @@ void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, mac_interface
|
|||
action->rv = get_rv();
|
||||
action->softbuffer = &softbuffer;
|
||||
action->tx_enabled = true;
|
||||
action->payload_ptr = pdu_ptr;
|
||||
memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(srslte_phy_grant_t));
|
||||
|
||||
current_irv = (current_irv+1)%4;
|
||||
|
|
|
@ -220,6 +220,9 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
|
|||
sib2->rr_config_common_sib.srs_ul_cnfg.bw_cnfg,
|
||||
sib2->rr_config_common_sib.srs_ul_cnfg.subfr_cnfg,
|
||||
sib2->rr_config_common_sib.srs_ul_cnfg.ack_nack_simul_tx);
|
||||
|
||||
phy->configure_ul_params();
|
||||
|
||||
}
|
||||
|
||||
void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac *mac, srslte::ue::phy *phy) {
|
||||
|
@ -273,6 +276,7 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac
|
|||
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->configure_ul_params();
|
||||
|
||||
// Setup radio bearers
|
||||
for (int i=0;i<msg->rr_cnfg.srb_to_add_mod_list_size;i++) {
|
||||
|
@ -306,6 +310,13 @@ uint8_t setupComplete_segm[2][41] ={ {
|
|||
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}
|
||||
};
|
||||
uint8_t setupComplete[80] = {
|
||||
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, 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};
|
||||
|
||||
|
@ -337,6 +348,7 @@ public:
|
|||
bool sib2_decoded;
|
||||
bool connsetup_decoded;
|
||||
int nsegm_dcch;
|
||||
int send_ack;
|
||||
uint8_t si_window_len, sib2_period;
|
||||
|
||||
rlctest() {
|
||||
|
@ -347,6 +359,7 @@ public:
|
|||
nsegm_dcch = 0;
|
||||
si_window_len = 0;
|
||||
sib2_period = 0;
|
||||
send_ack = 0;
|
||||
}
|
||||
|
||||
uint32_t get_buffer_state(uint32_t lcid) {
|
||||
|
@ -357,7 +370,7 @@ public:
|
|||
} else if (lcid == 1) {
|
||||
if (connsetup_decoded && nsegm_dcch < 2) {
|
||||
return lengths[nsegm_dcch];
|
||||
} else if (nsegm_dcch == 2) {
|
||||
} else if (send_ack == 1) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -388,24 +401,39 @@ public:
|
|||
printf("Send ConnectionRequest %d/%d bytes\n", nbytes, nof_bytes);
|
||||
srslte_bit_unpack_vector(bit_msg.msg, payload, nbytes*8);
|
||||
bzero(&payload[nbytes], (nof_bytes-nbytes)*sizeof(uint8_t));
|
||||
srslte_vec_fprint_byte(stdout, payload, nof_bytes);
|
||||
return nof_bytes;
|
||||
} else if (lcid == 1) {
|
||||
if (nsegm_dcch < 2) {
|
||||
printf("Sending Connection Setup Complete %d length %d\n", nsegm_dcch, lengths[nsegm_dcch]);
|
||||
memcpy(payload, setupComplete_segm[nsegm_dcch], lengths[nsegm_dcch]);
|
||||
nsegm_dcch++;
|
||||
} else if (nsegm_dcch == 2) {
|
||||
if (nof_bytes >= 80) {
|
||||
printf("Sending Connection Setup Complete length 80\n");
|
||||
memcpy(payload, setupComplete, 80);
|
||||
return 80;
|
||||
} else {
|
||||
if (nof_bytes >= lengths[nsegm_dcch]) {
|
||||
printf("Sending Connection Setup Complete %d/2 length %d\n", nsegm_dcch, lengths[nsegm_dcch]);
|
||||
memcpy(payload, setupComplete_segm[nsegm_dcch], lengths[nsegm_dcch]);
|
||||
} else {
|
||||
bzero(payload, nof_bytes);
|
||||
}
|
||||
uint32_t r = lengths[nsegm_dcch];
|
||||
nsegm_dcch++;
|
||||
return r;
|
||||
}
|
||||
} else if (send_ack == 1) {
|
||||
printf("Send RLC ACK\n");
|
||||
memcpy(payload, reply, 2*sizeof(uint8_t));
|
||||
nsegm_dcch++;
|
||||
send_ack = 2;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) {
|
||||
if (lcid == 0) {
|
||||
LIBLTE_RRC_DL_CCCH_MSG_STRUCT dl_ccch_msg;
|
||||
printf("ConnSetup received %d bytes\n", nof_bytes);
|
||||
srslte_vec_fprint_byte(stdout, payload, nof_bytes);
|
||||
srslte_bit_pack_vector(payload, bit_msg.msg, nof_bytes*8);
|
||||
bit_msg.N_bits = nof_bytes*8;
|
||||
liblte_rrc_unpack_dl_ccch_msg(&bit_msg, &dl_ccch_msg);
|
||||
|
@ -422,8 +450,12 @@ public:
|
|||
}
|
||||
} else if (lcid == 1) {
|
||||
printf("Received on DCCH0 %d bytes\n", nof_bytes);
|
||||
if (send_ack == 0) {
|
||||
send_ack = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes)
|
||||
{
|
||||
LIBLTE_RRC_MIB_STRUCT mib;
|
||||
|
|
|
@ -75,7 +75,7 @@ private:
|
|||
bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, uint32_t rv, uint16_t rnti);
|
||||
|
||||
/* ... for UL */
|
||||
void encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, uint32_t rv, uint16_t rnti);
|
||||
void encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, uint32_t rv, uint16_t rnti);
|
||||
void encode_pucch();
|
||||
void encode_srs();
|
||||
void reset_uci();
|
||||
|
@ -104,7 +104,6 @@ private:
|
|||
srslte_timestamp_t tx_time;
|
||||
srslte_uci_data_t uci_data;
|
||||
uint16_t ul_rnti;
|
||||
uint8_t *ul_payload;
|
||||
|
||||
// FIXME: THIS IS TEMPORAL. Need to change srslte to accept bits for payload
|
||||
uint8_t payload_bits[64*1024];
|
||||
|
@ -120,7 +119,6 @@ private:
|
|||
uint32_t I_sr;
|
||||
float cfo;
|
||||
bool rar_cqi_request;
|
||||
uint32_t ul_payload_max_len;
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ phch_common::phch_common()
|
|||
is_first_of_burst = true;
|
||||
is_first_tx = true;
|
||||
rar_grant_pending = false;
|
||||
sr_last_tx_tti = -1;
|
||||
}
|
||||
|
||||
void phch_common::init(phy_params *_params, log *_log, radio *_radio, mac_interface_phy *_mac)
|
||||
|
@ -53,6 +54,7 @@ void phch_common::init(phy_params *_params, log *_log, radio *_radio, mac_interf
|
|||
radio_h = _radio;
|
||||
mac = _mac;
|
||||
is_first_tx = true;
|
||||
sr_last_tx_tti = -1;
|
||||
}
|
||||
|
||||
bool phch_common::ul_rnti_active(uint32_t tti) {
|
||||
|
@ -80,8 +82,6 @@ void phch_common::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_G
|
|||
{
|
||||
srslte_dci_rar_grant_unpack(&rar_grant, grant_payload);
|
||||
rar_grant_pending = true;
|
||||
Info("Setting RAR grant: \n");
|
||||
srslte_dci_rar_grant_fprint(stdout, &rar_grant);
|
||||
// PUSCH is at n+6 or n+7 and phch_worker assumes default delay of 4 ttis
|
||||
if (rar_grant.ul_delay) {
|
||||
rar_grant_tti = (tti + 3) % 10240;
|
||||
|
|
|
@ -39,7 +39,6 @@ phch_worker::phch_worker()
|
|||
{
|
||||
phy = NULL;
|
||||
signal_buffer = NULL;
|
||||
ul_payload = NULL;
|
||||
|
||||
cell_initiated = false;
|
||||
pregen_enabled = false;
|
||||
|
@ -65,12 +64,6 @@ bool phch_worker::init_cell(srslte_cell_t cell_)
|
|||
Error("Allocating memory\n");
|
||||
return false;
|
||||
}
|
||||
ul_payload_max_len = srslte_ra_tbs_from_idx(26, cell.nof_prb);
|
||||
ul_payload = (uint8_t*) srslte_vec_malloc(sizeof(uint8_t) * ul_payload_max_len);
|
||||
if (!ul_payload) {
|
||||
Error("Allocating memory\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (srslte_ue_dl_init(&ue_dl, cell)) {
|
||||
Error("Initiating UE DL\n");
|
||||
|
@ -158,8 +151,10 @@ void phch_worker::work_imp()
|
|||
if (dl_action.decode_enabled) {
|
||||
dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffer, dl_action.rv, dl_action.rnti);
|
||||
}
|
||||
if (dl_action.generate_ack_callback) {
|
||||
if (dl_action.generate_ack_callback && dl_action.decode_enabled) {
|
||||
phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid);
|
||||
dl_action.generate_ack = dl_action.generate_ack_callback(dl_action.generate_ack_callback_arg);
|
||||
Info("Calling generate ACK callback returned=%d\n", dl_action.generate_ack);
|
||||
}
|
||||
if (dl_action.generate_ack) {
|
||||
set_uci_ack(dl_ack);
|
||||
|
@ -184,9 +179,9 @@ void phch_worker::work_imp()
|
|||
|
||||
/* Send UL grant or HARQ information (from PHICH) to MAC */
|
||||
if (ul_grant_available && ul_ack_available) {
|
||||
phy->mac->new_grant_ul_ack(ul_mac_grant, ul_payload, ul_ack, &ul_action);
|
||||
phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action);
|
||||
} else if (ul_grant_available && !ul_ack_available) {
|
||||
phy->mac->new_grant_ul(ul_mac_grant, ul_payload, &ul_action);
|
||||
phy->mac->new_grant_ul(ul_mac_grant, &ul_action);
|
||||
} else if (!ul_grant_available && ul_ack_available) {
|
||||
phy->mac->harq_recv(tti, ul_ack, &ul_action);
|
||||
}
|
||||
|
@ -198,12 +193,12 @@ void phch_worker::work_imp()
|
|||
/* Transmit PUSCH, PUCCH or SRS */
|
||||
bool tx_signal = false;
|
||||
if (ul_action.tx_enabled) {
|
||||
encode_pusch(&ul_action.phy_grant.ul, ul_action.current_tx_nb, ul_action.softbuffer, ul_action.rv, ul_action.rnti);
|
||||
encode_pusch(&ul_action.phy_grant.ul, ul_action.payload_ptr, ul_action.current_tx_nb, ul_action.softbuffer, ul_action.rv, ul_action.rnti);
|
||||
tx_signal = true;
|
||||
if (ul_action.expect_ack) {
|
||||
phy->set_pending_ack(tti + 8, ue_ul.pusch_cfg.grant.n_prb_tilde[0], ul_action.phy_grant.ul.ncs_dmrs);
|
||||
}
|
||||
} else if (dl_action.generate_ack) {
|
||||
} else if (dl_action.generate_ack || uci_data.scheduling_request || uci_data.uci_cqi_len > 0) {
|
||||
encode_pucch();
|
||||
tx_signal = true;
|
||||
} else if (srs_is_ready_to_send()) {
|
||||
|
@ -213,7 +208,7 @@ void phch_worker::work_imp()
|
|||
|
||||
phy->worker_end(tti, tx_signal, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);
|
||||
|
||||
if (dl_action.decode_enabled) {
|
||||
if (dl_action.decode_enabled && !dl_action.generate_ack_callback) {
|
||||
phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid);
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +222,6 @@ bool phch_worker::extract_fft_and_pdcch_llr() {
|
|||
|
||||
/* Without a grant, we might need to do fft processing if need to decode PHICH */
|
||||
if (phy->get_pending_ack(tti) || decode_pdcch) {
|
||||
Debug("Running FFT estimate\n");
|
||||
if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) {
|
||||
Error("Getting PDCCH FFT estimate\n");
|
||||
return false;
|
||||
|
@ -235,7 +229,6 @@ bool phch_worker::extract_fft_and_pdcch_llr() {
|
|||
}
|
||||
|
||||
if (decode_pdcch) { /* and not in DRX mode */
|
||||
Debug("Extracting PDCCH LLR\n");
|
||||
if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) {
|
||||
Error("Extracting PDCCH LLR\n");
|
||||
return false;
|
||||
|
@ -259,15 +252,12 @@ bool phch_worker::decode_pdcch_dl(srslte::ue::mac_interface_phy::mac_grant_t* gr
|
|||
dl_rnti = phy->get_dl_rnti(tti);
|
||||
if (dl_rnti) {
|
||||
|
||||
Debug("PDCCH configured to search for DL RNTI 0x%x\n", dl_rnti);
|
||||
|
||||
srslte_rnti_type_t type = phy->get_dl_rnti_type();
|
||||
|
||||
srslte_dci_msg_t dci_msg;
|
||||
srslte_ra_dl_dci_t dci_unpacked;
|
||||
|
||||
if (srslte_ue_dl_find_dl_dci_type(&ue_dl, &dci_msg, cfi, tti%10, dl_rnti, type) != 1) {
|
||||
Debug("Can't find DL DCI message\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -347,7 +337,7 @@ bool phch_worker::decode_phich(bool *ack)
|
|||
|
||||
bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
|
||||
{
|
||||
phy->reset_pending_ack(tti + 4);
|
||||
phy->reset_pending_ack(tti + 8);
|
||||
|
||||
srslte_dci_msg_t dci_msg;
|
||||
srslte_ra_ul_dci_t dci_unpacked;
|
||||
|
@ -371,9 +361,6 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
|
|||
} else {
|
||||
ul_rnti = phy->get_ul_rnti(tti);
|
||||
if (ul_rnti) {
|
||||
|
||||
Debug("PDCCH configured to search for UL RNTI 0x%x\n", ul_rnti);
|
||||
|
||||
if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, ul_rnti) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -460,20 +447,20 @@ void phch_worker::set_tx_time(srslte_timestamp_t _tx_time)
|
|||
}
|
||||
|
||||
void phch_worker::normalize() {
|
||||
srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_vec_norm_cfc(signal_buffer, 0.6, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
}
|
||||
|
||||
void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint32_t current_tx_nb,
|
||||
void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, uint32_t current_tx_nb,
|
||||
srslte_softbuffer_tx_t* softbuffer, uint32_t rv, uint16_t rnti)
|
||||
{
|
||||
|
||||
if (srslte_ue_ul_cfg_grant(&ue_ul, grant, tti+4, rv, current_tx_nb)) {
|
||||
Error("Configuring UL grant\n");
|
||||
}
|
||||
|
||||
|
||||
// FIXME: TEMPORAL
|
||||
srslte_bit_pack_vector(ul_payload, payload_bits, grant->mcs.tbs);
|
||||
|
||||
srslte_bit_pack_vector(payload, payload_bits, grant->mcs.tbs);
|
||||
|
||||
if (srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul,
|
||||
payload_bits, uci_data,
|
||||
softbuffer,
|
||||
|
@ -505,6 +492,10 @@ void phch_worker::encode_pucch()
|
|||
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
|
||||
ue_ul.pucch.shortened?"yes":"no");
|
||||
}
|
||||
|
||||
if (uci_data.scheduling_request) {
|
||||
phy->sr_enabled = false;
|
||||
}
|
||||
normalize();
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ uint32_t phy::get_current_tti()
|
|||
void phy::sr_send()
|
||||
{
|
||||
workers_common.sr_enabled = true;
|
||||
workers_common.sr_last_tx_tti = -1;
|
||||
}
|
||||
|
||||
int phy::sr_last_tx_tti()
|
||||
|
|
|
@ -220,14 +220,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) {
|
||||
void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) {
|
||||
printf("New grant UL\n");
|
||||
memcpy(payload_ptr, conn_request_msg, grant.n_bytes*sizeof(uint8_t));
|
||||
memcpy(payload, conn_request_msg, grant.n_bytes*sizeof(uint8_t));
|
||||
action->current_tx_nb = nof_rtx_connsetup;
|
||||
action->rv = rv_value[nof_rtx_connsetup%4];
|
||||
action->softbuffer = &softbuffer_tx;
|
||||
action->rnti = temp_c_rnti;
|
||||
action->expect_ack = (nof_rtx_connsetup < 5)?true:false;
|
||||
action->payload_ptr = payload;
|
||||
memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t));
|
||||
memcpy(&last_grant, &grant, sizeof(mac_grant_t));
|
||||
action->tx_enabled = true;
|
||||
|
@ -237,7 +238,7 @@ public:
|
|||
my_phy.pdcch_dl_search(SRSLTE_RNTI_USER, temp_c_rnti);
|
||||
}
|
||||
|
||||
void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) {
|
||||
void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) {
|
||||
printf("New grant UL ACK\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -95,10 +95,10 @@ srslte_softbuffer_rx_t softbuffer;
|
|||
class testmac : public srslte::ue::mac_interface_phy
|
||||
{
|
||||
public:
|
||||
void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) {
|
||||
void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) {
|
||||
printf("New grant UL\n");
|
||||
}
|
||||
void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) {
|
||||
void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) {
|
||||
printf("New grant UL ACK\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -55,12 +55,12 @@ int srslte_dft_precoding_init(srslte_dft_precoding_t *q, uint32_t max_prb)
|
|||
fprintf(stderr, "Error: Creating DFT plan %d\n",i);
|
||||
goto clean_exit;
|
||||
}
|
||||
srslte_dft_plan_set_norm(&q->dft_plan[i], false);
|
||||
srslte_dft_plan_set_norm(&q->dft_plan[i], true);
|
||||
if (srslte_dft_plan_c(&q->idft_plan[i], i*SRSLTE_NRE, SRSLTE_DFT_BACKWARD)) {
|
||||
fprintf(stderr, "Error: Creating DFT plan %d\n",i);
|
||||
goto clean_exit;
|
||||
}
|
||||
srslte_dft_plan_set_norm(&q->idft_plan[i], false);
|
||||
srslte_dft_plan_set_norm(&q->idft_plan[i], true);
|
||||
}
|
||||
}
|
||||
q->max_prb = max_prb;
|
||||
|
|
|
@ -160,6 +160,9 @@ void srslte_softbuffer_tx_reset(srslte_softbuffer_tx_t *q) {
|
|||
for (i=0;i<q->max_cb;i++) {
|
||||
if (q->buffer_b[i]) {
|
||||
bzero(q->buffer_b[i], sizeof(uint8_t) * q->buff_size);
|
||||
/*for (uint32_t j=0;j<q->buff_size;j++) {
|
||||
q->buffer_b[i][j] = SRSLTE_TX_NULL;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -378,7 +378,9 @@ int srslte_pusch_cfg(srslte_pusch_t *q,
|
|||
cfg->cp = q->cell.cp;
|
||||
|
||||
// Save UCI configuration
|
||||
memcpy(&cfg->uci_cfg, uci_cfg, sizeof(srslte_uci_cfg_t));
|
||||
if (uci_cfg) {
|
||||
memcpy(&cfg->uci_cfg, uci_cfg, sizeof(srslte_uci_cfg_t));
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
} else {
|
||||
|
@ -542,7 +544,6 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
|
|||
srslte_scrambling_b_offset_pusch(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
|
||||
}
|
||||
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->nbits.nof_bits);
|
||||
|
||||
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->nbits.nof_symb);
|
||||
|
||||
/* mapping to resource elements */
|
||||
|
|
|
@ -257,6 +257,10 @@ static int encode_tb(srslte_sch_t *q,
|
|||
|
||||
/* Turbo Encoding */
|
||||
srslte_tcod_encode(&q->encoder, q->cb_in, (uint8_t*) q->cb_out, cb_len);
|
||||
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
||||
DEBUG("CB#%d encoded: ", i);
|
||||
srslte_vec_fprint_b(stdout, q->cb_out, cb_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rate matching */
|
||||
|
@ -273,7 +277,7 @@ static int encode_tb(srslte_sch_t *q,
|
|||
wp += n_e;
|
||||
}
|
||||
INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp);
|
||||
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -54,7 +54,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
srslte_cell_t cell;
|
||||
bzero(&cell, sizeof(srslte_cell_t));
|
||||
cell.nof_ports = 1;
|
||||
|
|
|
@ -425,6 +425,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
|
|||
q->pusch_cfg.grant.n_prb_tilde,
|
||||
q->sf_symbols);
|
||||
} else {
|
||||
|
||||
if (srslte_refsignal_dmrs_pusch_gen(&q->signals, q->pusch_cfg.grant.L_prb,
|
||||
q->pusch_cfg.sf_idx,
|
||||
q->pusch_cfg.grant.ncs_dmrs,
|
||||
|
@ -438,7 +439,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
|
|||
q->pusch_cfg.grant.n_prb_tilde,
|
||||
q->sf_symbols);
|
||||
}
|
||||
|
||||
|
||||
if (srslte_ue_ul_srs_tx_enabled(&q->signals.srs_cfg, q->pusch_cfg.tti)) {
|
||||
if (q->signals_pregenerated) {
|
||||
srslte_refsignal_srs_pregen_put(&q->signals, &q->pregen_srs, q->pusch_cfg.tti, q->sf_symbols);
|
||||
|
|
|
@ -173,7 +173,6 @@ void srslte_vec_norm_cfc(cf_t *x, float amplitude, cf_t *y, uint32_t len) {
|
|||
|
||||
// Normalize before TX
|
||||
srslte_vec_sc_prod_cfc(x, amplitude/max, y, len);
|
||||
|
||||
}
|
||||
|
||||
void srslte_vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len) {
|
||||
|
|
Loading…
Reference in New Issue