mirror of https://github.com/PentHertz/srsLTE.git
add packing for CCCH over UL-SCH for MAC NR
This commit is contained in:
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;
|
||||||
|
@ -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)
|
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 CRNTI:
|
case CCCH_SIZE_48:
|
||||||
return 2;
|
return 6;
|
||||||
case SHORT_TRUNC_BSR:
|
case CCCH_SIZE_64:
|
||||||
return 1;
|
return 8;
|
||||||
case SHORT_BSR:
|
case CRNTI:
|
||||||
return 1;
|
return 2;
|
||||||
case PADDING:
|
case SHORT_TRUNC_BSR:
|
||||||
return 0;
|
return 1;
|
||||||
}
|
case SHORT_BSR:
|
||||||
} else {
|
return 1;
|
||||||
switch (lcid) {
|
case PADDING:
|
||||||
case CON_RES_ID:
|
return 0;
|
||||||
return 6;
|
|
||||||
case TA_CMD:
|
|
||||||
return 1;
|
|
||||||
case DRX_CMD:
|
|
||||||
return 0;
|
|
||||||
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;
|
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,12 +247,16 @@ 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 (nbytes < 256) {
|
if (ulsch && (lcid == mac_nr_sch_subpdu::CCCH_SIZE_48 || lcid == mac_nr_sch_subpdu::CCCH_SIZE_64)) {
|
||||||
return 2;
|
return 1;
|
||||||
} else {
|
} 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_)
|
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…
Reference in New Issue