Commit 3370570e authored by Melissa's avatar Melissa

Merge branch 'episys/ea/mac_headers_validation' into 'episys/sl-eurecom2'

Added SLSCH MAC sub-header, updated MAC sub-headers based on spec. 38321

See merge request aburger/openairinterface5g!269
parents a2e75e10 29b74e74
...@@ -114,23 +114,50 @@ typedef struct { ...@@ -114,23 +114,50 @@ typedef struct {
uint8_t R: 2; // octet 1 [7:6] uint8_t R: 2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; } __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
// 38321 section 6.1.6 Figure 6.1.6-1
typedef struct {
uint8_t V: 4; // octet 1 [7:4]
uint8_t R: 4; // octet 1 [3:0]
uint16_t SRC: 16; // octet 2, octet 3
uint8_t DST: 8; // octet 4
}__attribute__ ((__packed__)) NR_SLSCH_MAC_SUBHEADER_FIXED;
static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) { static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) {
if ( pdu_len < (int)sizeof(NR_MAC_SUBHEADER_SHORT)) uint8_t sl_sch_header_len = (int)sizeof(NR_SLSCH_MAC_SUBHEADER_FIXED);
if (pdu_len < sl_sch_header_len)
return false;
NR_SLSCH_MAC_SUBHEADER_FIXED *sl_sch_subheader = (NR_SLSCH_MAC_SUBHEADER_FIXED*) pdu;
pdu += sl_sch_header_len;
if ( pdu_len < sl_sch_header_len + (int)sizeof(NR_MAC_SUBHEADER_SHORT))
return false; return false;
NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu; NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu;
NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu; NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu;
if (s->F && pdu_len < (int)sizeof(NR_MAC_SUBHEADER_LONG)) if (s->F && pdu_len < sl_sch_header_len + (int)sizeof(NR_MAC_SUBHEADER_LONG))
return false; return false;
if (s->F) { if (s->F) {
*mac_subheader_len = sizeof(*l); *mac_subheader_len = sizeof(*l) + sizeof(*sl_sch_subheader);
*mac_ce_len = ntohs(l->L); *mac_ce_len = ntohs(l->L);
} else { } else {
*mac_subheader_len = sizeof(*s); *mac_subheader_len = sizeof(*s) + sizeof(*sl_sch_subheader);
*mac_ce_len = s->L; *mac_ce_len = s->L;
} }
LOG_D(NR_MAC, "V %hhu, SRC %hu, DST %hhu\n", sl_sch_subheader->V, sl_sch_subheader->SRC, sl_sch_subheader->DST);
LOG_D(NR_MAC, "R %hhu, F %hhu, LCID %hhu, L %hu\n", l->R, l->F, l->LCID, ntohs(l->L));
LOG_D(NR_MAC, "mac_subheader_len %hu, mac_ce_len %hu\n", *mac_subheader_len, *mac_ce_len);
return true; return true;
} }
// SL BSR MAC CEs
// TS 38.321 ch. 6.1.3.33
// Short BSR for a specific logical channel group ID
typedef struct {
uint8_t destination_index: 5; // octet 1 MSB
uint8_t LcgID: 3; // octet 1 LSB
uint8_t Buffer_size: 8;
} __attribute__ ((__packed__)) NR_SL_BSR_SHORT;
typedef NR_SL_BSR_SHORT NR_SL_BSR_SHORT_TRUNCATED;
// BSR MAC CEs // BSR MAC CEs
// TS 38.321 ch. 6.1.3.1 // TS 38.321 ch. 6.1.3.1
// Short BSR for a specific logical channel group ID // Short BSR for a specific logical channel group ID
...@@ -552,10 +579,24 @@ typedef struct nr_csi_report { ...@@ -552,10 +579,24 @@ typedef struct nr_csi_report {
int N2; int N2;
} nr_csi_report_t; } nr_csi_report_t;
// 38321 sec. 6.1.3.35
typedef struct {
uint8_t RI: 1; // 7th bit
uint8_t CQI: 4; // 3-6 bits
uint8_t R: 3; // 0-2 bits
} __attribute__ ((__packed__)) nr_sl_csi_report_t;
// 38321 sec. 6.1.3.34
typedef struct { typedef struct {
int CQI; uint8_t C1: 1; // 1st bit
int RI; uint8_t C2: 1; // 2nd bit
} nr_sl_csi_report_t; uint8_t C3: 1; // 3rd bit
uint8_t C4: 1; // 4th bit
uint8_t C5: 1; // 5th bit
uint8_t C6: 1; // 6th bit
uint8_t C7: 1; // 7th bit
uint8_t C8: 1; // 8th bit
} __attribute__ ((__packed__)) nr_sl_config_grant_t;
typedef enum { typedef enum {
NR_SRS_SRI_0 = 0, NR_SRS_SRI_0 = 0,
......
...@@ -737,9 +737,9 @@ void nr_ue_process_mac_sl_pdu(int module_idP, ...@@ -737,9 +737,9 @@ void nr_ue_process_mac_sl_pdu(int module_idP,
while (!done && pdu_len > 0){ while (!done && pdu_len > 0){
uint16_t mac_len = 0x0000; uint16_t mac_len = 0x0000;
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID; uint8_t rx_lcid = ((NR_MAC_SUBHEADER_LONG *)(pduP + sizeof(NR_SLSCH_MAC_SUBHEADER_FIXED)))->LCID;
LOG_D(NR_MAC, "[UE %x] LCID %d, PDU length %d\n", mac->src_id,rx_lcid, pdu_len); LOG_D(NR_MAC, "[UE %x] LCID %d, PDU length %d\n", mac->src_id, rx_lcid, pdu_len);
switch(rx_lcid){ switch(rx_lcid){
// MAC CE // MAC CE
case SL_SCH_LCID_4_19: case SL_SCH_LCID_4_19:
......
...@@ -2661,9 +2661,15 @@ typedef struct { ...@@ -2661,9 +2661,15 @@ typedef struct {
uint8_t phr_ce_len; uint8_t phr_ce_len;
uint8_t phr_header_len; uint8_t phr_header_len;
uint16_t sdu_length_total; uint16_t sdu_length_total;
NR_BSR_SHORT *bsr_s; union {
NR_BSR_SHORT *bsr_s;
NR_SL_BSR_SHORT *sl_bsr_s;
};
NR_BSR_LONG *bsr_l; NR_BSR_LONG *bsr_l;
NR_BSR_SHORT *bsr_t; union {
NR_BSR_SHORT *bsr_t;
NR_SL_BSR_SHORT *sl_bsr_t;
};
//NR_POWER_HEADROOM_CMD *phr_pr; //NR_POWER_HEADROOM_CMD *phr_pr;
int tot_mac_ce_len; int tot_mac_ce_len;
uint8_t total_mac_pdu_header_len; uint8_t total_mac_pdu_header_len;
...@@ -2724,15 +2730,16 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, ...@@ -2724,15 +2730,16 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
"Inconsistent BSR Trigger=%d !\n", "Inconsistent BSR Trigger=%d !\n",
mac->BSR_reporting_active); mac->BSR_reporting_active);
uint8_t size_bsr = get_softmodem_params()->sl_mode ? sizeof(NR_SL_BSR_SHORT) : sizeof(NR_BSR_SHORT);
//A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit //A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit
if (num_lcg_id_with_data <= 1) { if (num_lcg_id_with_data <= 1) {
if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) { if (buflen >= (size_bsr + sizeof(NR_MAC_SUBHEADER_FIXED) + 1)) {
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte mac_ce_p->bsr_ce_len = size_bsr;
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
} }
} else { } else {
if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) { if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) {
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size mac_ce_p->bsr_ce_len = num_lcg_id_with_data * size_bsr + 1; //variable size
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
} }
} }
...@@ -3252,6 +3259,8 @@ bool nr_ue_sl_pssch_scheduler(NR_UE_MAC_INST_t *mac, ...@@ -3252,6 +3259,8 @@ bool nr_ue_sl_pssch_scheduler(NR_UE_MAC_INST_t *mac,
uint16_t frame = sl_ind->frame_tx; uint16_t frame = sl_ind->frame_tx;
int lcid = 4; int lcid = 4;
int sdu_length = 0; int sdu_length = 0;
uint16_t sdu_length_total = 0;
uint8_t total_mac_pdu_header_len = 0;
if ((frame & 127) == 0 && slot == 0) { if ((frame & 127) == 0 && slot == 0) {
print_meas(&mac->rlc_data_req,"rlc_data_req",NULL,NULL); print_meas(&mac->rlc_data_req,"rlc_data_req",NULL,NULL);
...@@ -3293,94 +3302,103 @@ bool nr_ue_sl_pssch_scheduler(NR_UE_MAC_INST_t *mac, ...@@ -3293,94 +3302,103 @@ bool nr_ue_sl_pssch_scheduler(NR_UE_MAC_INST_t *mac,
int buflen = tx_config->tx_config_list[0].tx_pscch_pssch_psfch_config_pdu.tb_size; int buflen = tx_config->tx_config_list[0].tx_pscch_pssch_psfch_config_pdu.tb_size;
NR_UE_MAC_CE_INFO mac_ce_info = {0}; LOG_D(NR_MAC, "[UE%d] TTI-%d:%d TX PSCCH_PSSCH REQ TBS %d\n", sl_ind->module_id, frame, slot, buflen);
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
mac_ce_p->bsr_len = 0;
mac_ce_p->bsr_ce_len = 0;
mac_ce_p->bsr_header_len = 0;
mac_ce_p->phr_len = 0;
LOG_D(NR_MAC, "[UE%d] TTI-%d:%d TX PSCCH_PSSCH REQ TBS %d\n", sl_ind->module_id,frame, slot,buflen);
NR_SLSCH_MAC_SUBHEADER_FIXED *sl_sch_subheader = (NR_SLSCH_MAC_SUBHEADER_FIXED *) pdu;
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length sl_sch_subheader->V = 0;
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(0, 0, frame, slot, 0, pdu, buflen, mac_ce_p); sl_sch_subheader->R = 0;
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len; sl_sch_subheader->SRC = get_softmodem_params()->node_number;
sl_sch_subheader->DST = 0xab;
pdu += sizeof(NR_SLSCH_MAC_SUBHEADER_FIXED);
int buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); LOG_D(NR_PHY, "V %d, R %d, SRC %d, DST %d\n", sl_sch_subheader->V, sl_sch_subheader->R, sl_sch_subheader->SRC, sl_sch_subheader->DST);
int buflen_remain = buflen - sizeof(NR_SLSCH_MAC_SUBHEADER_FIXED);
LOG_D(NR_PHY, "buflen_remain after adding SL_SCH_MAC_SUBHEADER_FIXED %d\n", buflen_remain);
int num_sdus=0; int num_sdus=0;
while (buflen_remain > 0){ while (buflen_remain > 0) {
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu; NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu;
pdu += sh_size;
start_meas(&mac->rlc_data_req);
sdu_length = mac_rlc_data_req(0,
mac->src_id,
0,
frame,
ENB_FLAG_NO,
MBMS_FLAG_NO,
lcid,
buflen_remain,
(char *)pdu,
0,
0);
stop_meas(&mac->rlc_data_req);
AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n",
__FUNCTION__,
lcid,
sdu_length,
buflen_remain);
if (sdu_length > 0) {
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] SL-DXCH -> SLSCH, Generating SL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n",
__FUNCTION__,
0,
frame,
slot,
num_sdus + 1,
sdu_length,
lcid,
buflen);
header->R = 0;
header->F = 1;
header->LCID = lcid;
header->L = htons(sdu_length);
pdu += sdu_length;
sdu_length_total += sdu_length;
total_mac_pdu_header_len += sh_size;
buflen_remain -= (sh_size + sdu_length);
LOG_D(NR_PHY, "buflen_remain %d, subtracting (sh_size + sdu_length) %d, total_mac_pdu_header_len %hhu sdu total length %d, sdu_length %d\n", buflen_remain, (sh_size + sdu_length), total_mac_pdu_header_len, sdu_length_total, sdu_length);
num_sdus++;
pdu += sh_size; } else {
pdu -= sh_size;
start_meas(&mac->rlc_data_req); LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
sdu_length = mac_rlc_data_req(0, break;
mac->src_id, }
0,
frame,
ENB_FLAG_NO,
MBMS_FLAG_NO,
lcid,
buflen_remain,
(char *)pdu,
0,
0);
stop_meas(&mac->rlc_data_req);
AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n",
__FUNCTION__,
lcid,
sdu_length,
buflen_remain);
if (sdu_length > 0) { NR_UE_MAC_CE_INFO *mac_ce_p = (NR_UE_MAC_CE_INFO *) pdu;
mac_ce_p->bsr_len = 0;
mac_ce_p->bsr_ce_len = 0;
mac_ce_p->bsr_header_len = 0;
mac_ce_p->phr_len = 0;
mac_ce_p->sdu_length_total = sdu_length_total;
mac_ce_p->total_mac_pdu_header_len = total_mac_pdu_header_len;
LOG_D(NR_MAC, "[UE%d] TTI-%d:%d TX PSCCH_PSSCH REQ TBS %d\n", sl_ind->module_id, frame, slot, buflen);
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] SL-DXCH -> SLSCH, Generating SL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", //nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
__FUNCTION__, mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(0, 0, frame, slot, 0, pdu, buflen, mac_ce_p);
0, buflen_remain -= mac_ce_p->tot_mac_ce_len;
frame,
slot,
num_sdus + 1,
sdu_length,
lcid,
buflen);
header->R = 0; LOG_D(NR_PHY, "buflen_remain %d, total_mac_pdu_header_len %d, adding tot_mac_ce_len %d, \n", buflen_remain, mac_ce_p->total_mac_pdu_header_len, mac_ce_p->tot_mac_ce_len);
header->F = 1;
header->LCID = lcid;
header->L = htons(sdu_length);
pdu += sdu_length; if (buflen_remain > 0) {
mac_ce_p->sdu_length_total += sdu_length; LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
mac_ce_p->total_mac_pdu_header_len += sh_size; ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = SL_SCH_LCID_SL_PADDING;
num_sdus++; pdu++;
buflen_remain--;
if (IS_SOFTMODEM_RFSIM) {
for (int j = 0; j < buflen_remain; j++) {
pdu[j] = (unsigned char) rand();
}
} else { } else {
pdu -= sh_size; memset(pdu, 0, buflen_remain);
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
break;
} }
}
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
if (buflen_remain > 0) {
LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = SL_SCH_LCID_SL_PADDING;
pdu++;
buflen_remain--;
if (IS_SOFTMODEM_RFSIM) {
for (int j = 0; j < buflen_remain; j++) {
pdu[j] = (unsigned char) rand();
}
} else {
memset(pdu, 0, buflen_remain);
} }
} }
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment