mirror of https://github.com/pvnis/srsRAN_4G.git
mac: implement MAC RAR PDU unpacking for NR
* add class for mac_rar_pdu_nr * extend test casemaster
parent
da9e3363f1
commit
f88943653b
@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_MAC_RAR_PDU_NR_H
|
||||||
|
#define SRSLTE_MAC_RAR_PDU_NR_H
|
||||||
|
|
||||||
|
#include "srslte/common/common.h"
|
||||||
|
#include "srslte/config.h"
|
||||||
|
#include "srslte/srslog/srslog.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class mac_rar_pdu_nr;
|
||||||
|
|
||||||
|
// 3GPP 38.321 v15.3.0 Sec 6.1.5
|
||||||
|
class mac_rar_subpdu_nr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Possible types of RAR subpdus (same like EUTRA)
|
||||||
|
typedef enum { BACKOFF = 0, RAPID } rar_subh_type_t;
|
||||||
|
|
||||||
|
mac_rar_subpdu_nr(mac_rar_pdu_nr* parent_);
|
||||||
|
|
||||||
|
// RAR content length in bits (38.321 Sec 6.2.3)
|
||||||
|
static const uint32_t UL_GRANT_NBITS = 27;
|
||||||
|
static const uint32_t TA_COMMAND_NBITS = 12;
|
||||||
|
|
||||||
|
// getter
|
||||||
|
bool read_subpdu(const uint8_t* ptr);
|
||||||
|
bool has_more_subpdus();
|
||||||
|
uint32_t get_total_length();
|
||||||
|
bool has_rapid();
|
||||||
|
uint8_t get_rapid();
|
||||||
|
uint16_t get_temp_crnti();
|
||||||
|
uint32_t get_ta();
|
||||||
|
void get_ul_grant(std::array<uint8_t, UL_GRANT_NBITS>& grant);
|
||||||
|
|
||||||
|
bool has_backoff();
|
||||||
|
uint8_t get_backoff();
|
||||||
|
|
||||||
|
// setter
|
||||||
|
uint32_t write_subpdu(const uint8_t* start_);
|
||||||
|
void set_backoff(const uint8_t backoff_indicator_);
|
||||||
|
|
||||||
|
std::string to_string();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int header_length = 1; // RAR PDU subheader is always 1 B
|
||||||
|
int payload_length = 0; // only used if MAC RAR is included
|
||||||
|
|
||||||
|
std::array<uint8_t, UL_GRANT_NBITS> ul_grant = {};
|
||||||
|
uint16_t ta = 0; // 12bit TA
|
||||||
|
uint16_t temp_crnti = 0;
|
||||||
|
uint16_t rapid = 0;
|
||||||
|
uint8_t backoff_indicator = 0;
|
||||||
|
rar_subh_type_t type = BACKOFF;
|
||||||
|
bool E_bit = 0;
|
||||||
|
|
||||||
|
srslog::basic_logger& logger;
|
||||||
|
|
||||||
|
mac_rar_pdu_nr* parent = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class mac_rar_pdu_nr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mac_rar_pdu_nr();
|
||||||
|
~mac_rar_pdu_nr() = default;
|
||||||
|
|
||||||
|
bool pack();
|
||||||
|
bool unpack(const uint8_t* payload, const uint32_t& len);
|
||||||
|
uint32_t get_num_subpdus();
|
||||||
|
const mac_rar_subpdu_nr& get_subpdu(const uint32_t& index);
|
||||||
|
|
||||||
|
uint32_t get_remaining_len();
|
||||||
|
|
||||||
|
void set_si_rapid(uint16_t si_rapid_); // configured through SIB1 for on-demand SI request (See 38.331 Sec 5.2.1)
|
||||||
|
bool has_si_rapid();
|
||||||
|
|
||||||
|
std::string to_string();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<mac_rar_subpdu_nr> subpdus;
|
||||||
|
uint32_t remaining_len = 0;
|
||||||
|
uint16_t si_rapid = 0;
|
||||||
|
bool si_rapid_set = false;
|
||||||
|
srslog::basic_logger& logger;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // SRSLTE_MAC_RAR_PDU_NR_H
|
@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/mac/mac_rar_pdu_nr.h"
|
||||||
|
#include <sstream>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#include "srslte/phy/utils/bit.h"
|
||||||
|
#include "srslte/phy/utils/vector.h"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
mac_rar_subpdu_nr::mac_rar_subpdu_nr(mac_rar_pdu_nr* parent_) :
|
||||||
|
parent(parent_), logger(srslog::fetch_basic_logger("MAC"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Return true if subPDU could be parsed correctly, false otherwise
|
||||||
|
bool mac_rar_subpdu_nr::read_subpdu(const uint8_t* ptr)
|
||||||
|
{
|
||||||
|
E_bit = (bool)(*ptr & 0x80) ? true : false;
|
||||||
|
type = (*ptr & 0x40) ? RAPID : BACKOFF;
|
||||||
|
if (type == RAPID) {
|
||||||
|
rapid = *ptr & 0x3f;
|
||||||
|
// if PDU is not configured with SI request, extract MAC RAR
|
||||||
|
if (parent->has_si_rapid() == false) {
|
||||||
|
const uint32_t MAC_RAR_NBYTES = 7;
|
||||||
|
if (parent->get_remaining_len() >= MAC_RAR_NBYTES) {
|
||||||
|
uint8_t* rar = const_cast<uint8_t*>(ptr + 1);
|
||||||
|
// check reserved bits
|
||||||
|
if (*rar & 0x80) {
|
||||||
|
logger.error("Error parsing RAR PDU, reserved bit is set.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TA is first 7 bits of 1st + 5 bits of 2nd octet
|
||||||
|
ta = (uint16_t)(((*(rar + 0) & 0x7f) << 5 | ((*(rar + 1) & 0xf8) >> 3)));
|
||||||
|
// Extract the first 3 bits of the UL grant from the 2nd octet
|
||||||
|
ul_grant.at(0) = *(rar + 1) & 0x4 ? 1 : 0;
|
||||||
|
ul_grant.at(1) = *(rar + 1) & 0x2 ? 1 : 0;
|
||||||
|
ul_grant.at(2) = *(rar + 1) & 0x1 ? 1 : 0;
|
||||||
|
// And now the remaining 3 full octets
|
||||||
|
uint8_t* x = &ul_grant.at(3);
|
||||||
|
srslte_bit_unpack(*(rar + 2), &x, 8);
|
||||||
|
srslte_bit_unpack(*(rar + 3), &x, 8);
|
||||||
|
srslte_bit_unpack(*(rar + 4), &x, 8);
|
||||||
|
// Temp CRNTI is octet 6 + 7
|
||||||
|
temp_crnti = ((uint16_t) * (rar + 5)) << 8 | *(rar + 6);
|
||||||
|
payload_length = MAC_RAR_NBYTES;
|
||||||
|
} else {
|
||||||
|
logger.error("Error parsing RAR PDU, remaining bytes not sufficant (%d < %d)",
|
||||||
|
parent->get_remaining_len(),
|
||||||
|
MAC_RAR_NBYTES);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// check reserved bits
|
||||||
|
if (*ptr & 0x10 || *ptr & 0x20) {
|
||||||
|
logger.error("Error parsing RAR PDU, reserved bit is set.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
backoff_indicator = *ptr & 0xf;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if another subPDU follows after that
|
||||||
|
bool mac_rar_subpdu_nr::has_more_subpdus()
|
||||||
|
{
|
||||||
|
return E_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section 6.1.2
|
||||||
|
uint32_t mac_rar_subpdu_nr::write_subpdu(const uint8_t* start_)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mac_rar_subpdu_nr::get_total_length()
|
||||||
|
{
|
||||||
|
return (header_length + payload_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mac_rar_subpdu_nr::has_rapid()
|
||||||
|
{
|
||||||
|
return (type == rar_subh_type_t::RAPID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mac_rar_subpdu_nr::get_rapid()
|
||||||
|
{
|
||||||
|
return rapid;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mac_rar_subpdu_nr::get_ta()
|
||||||
|
{
|
||||||
|
return ta;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mac_rar_subpdu_nr::get_temp_crnti()
|
||||||
|
{
|
||||||
|
return temp_crnti;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mac_rar_subpdu_nr::has_backoff()
|
||||||
|
{
|
||||||
|
return (type == rar_subh_type_t::BACKOFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_rar_subpdu_nr::set_backoff(const uint8_t backoff_indicator_)
|
||||||
|
{
|
||||||
|
backoff_indicator = backoff_indicator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_rar_subpdu_nr::get_ul_grant(std::array<uint8_t, UL_GRANT_NBITS>& grant_)
|
||||||
|
{
|
||||||
|
grant_ = ul_grant;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mac_rar_subpdu_nr::to_string()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
if (has_rapid()) {
|
||||||
|
ss << "RAPID: " << rapid << ", Temp C-RNTI: " << temp_crnti << ", TA: " << ta << ", UL Grant: ";
|
||||||
|
} else {
|
||||||
|
ss << "Backoff Indicator: " << backoff_indicator << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp[16] = {};
|
||||||
|
srslte_vec_sprint_hex(tmp, sizeof(tmp), ul_grant.data(), UL_GRANT_NBITS);
|
||||||
|
ss << tmp;
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_rar_pdu_nr::mac_rar_pdu_nr() : logger(srslog::fetch_basic_logger("MAC")) {}
|
||||||
|
|
||||||
|
bool mac_rar_pdu_nr::pack()
|
||||||
|
{
|
||||||
|
// not implemented yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mac_rar_pdu_nr::has_si_rapid()
|
||||||
|
{
|
||||||
|
return si_rapid_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_rar_pdu_nr::set_si_rapid(uint16_t si_rapid_)
|
||||||
|
{
|
||||||
|
si_rapid = si_rapid_;
|
||||||
|
si_rapid_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if PDU could be parsed successfully
|
||||||
|
bool mac_rar_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
bool have_more_subpdus = false;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
|
||||||
|
remaining_len = len;
|
||||||
|
|
||||||
|
do {
|
||||||
|
mac_rar_subpdu_nr rar_subpdu(this);
|
||||||
|
ret = rar_subpdu.read_subpdu(payload + offset);
|
||||||
|
have_more_subpdus = rar_subpdu.has_more_subpdus();
|
||||||
|
offset += rar_subpdu.get_total_length();
|
||||||
|
remaining_len -= rar_subpdu.get_total_length();
|
||||||
|
|
||||||
|
// only append if subPDU could be read successfully
|
||||||
|
if (ret == true) {
|
||||||
|
subpdus.push_back(rar_subpdu);
|
||||||
|
}
|
||||||
|
// continue reading as long as subPDUs can be extracted ok and we are not overrunning the PDU length
|
||||||
|
} while (ret && have_more_subpdus && offset <= len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mac_rar_pdu_nr::get_num_subpdus()
|
||||||
|
{
|
||||||
|
return subpdus.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const mac_rar_subpdu_nr& mac_rar_pdu_nr::get_subpdu(const uint32_t& index)
|
||||||
|
{
|
||||||
|
return subpdus.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mac_rar_pdu_nr::get_remaining_len()
|
||||||
|
{
|
||||||
|
return remaining_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mac_rar_pdu_nr::to_string()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
for (auto& subpdu : subpdus) {
|
||||||
|
ss << subpdu.to_string() << " ";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srslte
|
Loading…
Reference in New Issue