add packing for CCCH over UL-SCH for MAC NR

This commit is contained in:
Andre Puschmann 2019-10-29 18:08:28 +01:00
parent b88b8fde7b
commit aa9733eb59
3 changed files with 107 additions and 31 deletions

View File

@ -37,6 +37,7 @@ public:
// 3GPP 38.321 v15.3.0 Combined Tables 6.2.1-1, 6.2.1-2
typedef enum {
// Values for DL-SCH
CCCH = 0b000000,
DRX_CMD = 0b111100,
TA_CMD = 0b111101,
CON_RES_ID = 0b111110,
@ -45,12 +46,13 @@ public:
CRNTI = 0b111010,
SHORT_TRUNC_BSR = 0b111011,
LONG_TRUNC_BSR = 0b111100,
CCCH_SIZE_48 = 0b110100,
CCCH_SIZE_64 = 0b000000,
SHORT_BSR = 0b111101,
LONG_BSR = 0b111110,
// Common
CCCH = 0b000000,
PADDING = 0b111111,
} nr_lcid_sch_t;
@ -59,6 +61,7 @@ public:
nr_lcid_sch_t get_type();
bool is_sdu();
bool is_var_len_ce();
bool is_ul_ccch();
uint32_t read_subheader(const uint8_t* ptr);
uint32_t get_total_length();
@ -103,7 +106,7 @@ public:
uint32_t get_remaing_len();
private:
uint32_t size_header_sdu(const uint32_t nbytes);
uint32_t size_header_sdu(const uint32_t lcid_, const uint32_t nbytes);
bool ulsch = false;
std::vector<mac_nr_sch_subpdu> subpdus;

View File

@ -53,7 +53,7 @@ uint32_t mac_nr_sch_subpdu::read_subheader(const uint8_t* ptr)
ptr++;
header_length = 1;
if (is_sdu() || is_var_len_ce()) {
if ((is_sdu() || is_var_len_ce()) && not is_ul_ccch()) {
// Read first length byte
sdu_length = (uint32_t)*ptr;
ptr++;
@ -76,8 +76,15 @@ void mac_nr_sch_subpdu::set_sdu(const uint32_t lcid_, const uint8_t* payload_, c
{
lcid = lcid_;
sdu = const_cast<uint8_t*>(payload_);
header_length = is_ul_ccch() ? 1 : 2;
sdu_length = len_;
header_length = 2;
if (is_ul_ccch()) {
F_bit = false;
sdu_length = sizeof_ce(lcid, parent->is_ulsch());
if (len_ != static_cast<uint32_t>(sdu_length)) {
fprintf(stderr, "Invalid SDU length of UL-SCH SDU (%d != %d)\n", len_, sdu_length);
}
}
if (sdu_length >= 256) {
F_bit = true;
@ -153,32 +160,41 @@ uint8_t* mac_nr_sch_subpdu::get_sdu()
uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul)
{
if (is_ul) {
switch (lcid) {
case CRNTI:
return 2;
case SHORT_TRUNC_BSR:
return 1;
case SHORT_BSR:
return 1;
case PADDING:
return 0;
}
} else {
switch (lcid) {
case CON_RES_ID:
return 6;
case TA_CMD:
return 1;
case DRX_CMD:
return 0;
case PADDING:
return 0;
}
if (is_ul) {
switch (lcid) {
case CCCH_SIZE_48:
return 6;
case CCCH_SIZE_64:
return 8;
case CRNTI:
return 2;
case SHORT_TRUNC_BSR:
return 1;
case SHORT_BSR:
return 1;
case PADDING:
return 0;
}
} else {
switch (lcid) {
case CON_RES_ID:
return 6;
case TA_CMD:
return 1;
case DRX_CMD:
return 0;
case PADDING:
return 0;
}
}
return 0;
}
inline bool mac_nr_sch_subpdu::is_ul_ccch()
{
return (parent->is_ulsch() && (lcid == CCCH_SIZE_48 || lcid == CCCH_SIZE_64));
}
void mac_nr_sch_pdu::pack()
{
// SDUs are written in place, only add padding if needed
@ -231,12 +247,16 @@ void mac_nr_sch_pdu::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool uls
ulsch = ulsch_;
}
uint32_t mac_nr_sch_pdu::size_header_sdu(const uint32_t nbytes)
uint32_t mac_nr_sch_pdu::size_header_sdu(const uint32_t lcid, const uint32_t nbytes)
{
if (nbytes < 256) {
return 2;
if (ulsch && (lcid == mac_nr_sch_subpdu::CCCH_SIZE_48 || lcid == mac_nr_sch_subpdu::CCCH_SIZE_64)) {
return 1;
} else {
return 3;
if (nbytes < 256) {
return 2;
} else {
return 3;
}
}
}
@ -247,7 +267,7 @@ uint32_t mac_nr_sch_pdu::get_remaing_len()
uint32_t mac_nr_sch_pdu::add_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_)
{
int header_size = size_header_sdu(len_);
int header_size = size_header_sdu(lcid_, len_);
if (header_size + len_ > remaining_len) {
printf("Header and SDU exceed space in PDU (%d > %d).\n", header_size + len_, remaining_len);

View File

@ -289,6 +289,54 @@ int mac_ul_sch_pdu_unpack_test1()
return SRSLTE_SUCCESS;
}
int mac_ul_sch_pdu_unpack_and_pack_test2()
{
// MAC PDU with UL-SCH (for UL-CCCH) subheader
// Bit 1-8
// | | | | | | | | |
// | R | R | LCID | Octet 1
// TV1 - MAC PDU with short subheader for CCCH, MAC SDU length is 8 B, total PDU is 10 B
uint8_t mac_ul_sch_pdu_1[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
if (pcap_handle) {
pcap_handle->write_ul_crnti(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI);
}
srslte::mac_nr_sch_pdu pdu(true);
pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1));
TESTASSERT(pdu.get_num_subpdus() == 1);
mac_nr_sch_subpdu subpdu = pdu.get_subpdu(0);
TESTASSERT(subpdu.get_total_length() == 9);
TESTASSERT(subpdu.get_sdu_length() == 8);
TESTASSERT(subpdu.get_lcid() == 0);
// pack PDU again
byte_buffer_t tx_buffer;
srslte::mac_nr_sch_pdu tx_pdu;
tx_pdu.init_tx(&tx_buffer, sizeof(mac_ul_sch_pdu_1), true);
// Add SDU part of TV from above
tx_pdu.add_sdu(0, &mac_ul_sch_pdu_1[1], 8);
TESTASSERT(tx_pdu.get_remaing_len() == 0);
TESTASSERT(tx_buffer.N_bytes == sizeof(mac_ul_sch_pdu_1));
TESTASSERT(memcmp(tx_buffer.msg, mac_ul_sch_pdu_1, tx_buffer.N_bytes) == 0);
if (pcap_handle) {
pcap_handle->write_ul_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI);
}
srslte::log_filter log("MAC");
log.set_level(srslte::LOG_LEVEL_DEBUG);
log.set_hex_limit(100000);
log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes);
return SRSLTE_SUCCESS;
}
int main(int argc, char** argv)
{
#if PCAP
@ -326,5 +374,10 @@ int main(int argc, char** argv)
return SRSLTE_ERROR;
}
if (mac_ul_sch_pdu_unpack_and_pack_test2()) {
fprintf(stderr, "mac_ul_sch_pdu_unpack_and_pack_test2() failed.\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}