add packing for CCCH over UL-SCH for MAC NR

master
Andre Puschmann 5 years ago
parent b88b8fde7b
commit aa9733eb59

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

@ -53,7 +53,7 @@ uint32_t mac_nr_sch_subpdu::read_subheader(const uint8_t* ptr)
ptr++; ptr++;
header_length = 1; 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 // Read first length byte
sdu_length = (uint32_t)*ptr; sdu_length = (uint32_t)*ptr;
ptr++; ptr++;
@ -76,8 +76,15 @@ void mac_nr_sch_subpdu::set_sdu(const uint32_t lcid_, const uint8_t* payload_, c
{ {
lcid = lcid_; lcid = lcid_;
sdu = const_cast<uint8_t*>(payload_); sdu = const_cast<uint8_t*>(payload_);
header_length = is_ul_ccch() ? 1 : 2;
sdu_length = len_; 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) { if (sdu_length >= 256) {
F_bit = true; F_bit = true;
@ -155,6 +162,10 @@ uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul)
{ {
if (is_ul) { if (is_ul) {
switch (lcid) { switch (lcid) {
case CCCH_SIZE_48:
return 6;
case CCCH_SIZE_64:
return 8;
case CRNTI: case CRNTI:
return 2; return 2;
case SHORT_TRUNC_BSR: case SHORT_TRUNC_BSR:
@ -179,6 +190,11 @@ uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul)
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() void mac_nr_sch_pdu::pack()
{ {
// SDUs are written in place, only add padding if needed // SDUs are written in place, only add padding if needed
@ -231,13 +247,17 @@ void mac_nr_sch_pdu::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool uls
ulsch = ulsch_; 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 (ulsch && (lcid == mac_nr_sch_subpdu::CCCH_SIZE_48 || lcid == mac_nr_sch_subpdu::CCCH_SIZE_64)) {
return 1;
} else {
if (nbytes < 256) { if (nbytes < 256) {
return 2; return 2;
} else { } else {
return 3; return 3;
} }
}
} }
uint32_t mac_nr_sch_pdu::get_remaing_len() uint32_t mac_nr_sch_pdu::get_remaing_len()
@ -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_) 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) { if (header_size + len_ > remaining_len) {
printf("Header and SDU exceed space in PDU (%d > %d).\n", header_size + len_, remaining_len); printf("Header and SDU exceed space in PDU (%d > %d).\n", header_size + len_, remaining_len);

@ -289,6 +289,54 @@ int mac_ul_sch_pdu_unpack_test1()
return SRSLTE_SUCCESS; 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) int main(int argc, char** argv)
{ {
#if PCAP #if PCAP
@ -326,5 +374,10 @@ int main(int argc, char** argv)
return SRSLTE_ERROR; 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; return SRSLTE_SUCCESS;
} }

Loading…
Cancel
Save