MAC test working

This commit is contained in:
ismagom 2015-08-04 17:27:14 +02:00
parent 1b2c474f25
commit 7e94f82ab6
34 changed files with 520 additions and 401 deletions

View File

@ -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

View File

@ -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))

View File

@ -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!');

View File

@ -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

View File

@ -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()

View File

@ -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;
}

View File

@ -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

View File

@ -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;
};

View File

@ -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;
};
}

View File

@ -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:

View File

@ -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();

View File

@ -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;

View File

@ -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());

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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_)

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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;

View File

@ -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();
}

View File

@ -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()

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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;

View File

@ -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;
}*/
}
}
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {