mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.5 KiB
C++
187 lines
6.5 KiB
C++
6 years ago
|
/*
|
||
|
* Copyright 2013-2019 Software Radio Systems Limited
|
||
|
*
|
||
|
* This file is part of srsLTE.
|
||
|
*
|
||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Affero General Public License as
|
||
|
* published by the Free Software Foundation, either version 3 of
|
||
|
* the License, or (at your option) any later version.
|
||
|
*
|
||
|
* srsLTE is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU Affero General Public License for more details.
|
||
|
*
|
||
|
* A copy of the GNU Affero General Public License can be found in
|
||
|
* the LICENSE file in the top-level directory of this distribution
|
||
|
* and at http://www.gnu.org/licenses/.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "srslte/common/log_filter.h"
|
||
|
#include "srslte/interfaces/ue_interfaces.h"
|
||
|
#include "srsue/hdr/mac/mac.h"
|
||
|
#include <assert.h>
|
||
|
#include <iostream>
|
||
|
|
||
|
using namespace srsue;
|
||
|
using namespace srslte;
|
||
|
|
||
|
#define TESTASSERT(cond) \
|
||
|
{ \
|
||
|
if (!(cond)) { \
|
||
|
std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \
|
||
|
return SRSLTE_ERROR; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
namespace srslte {
|
||
|
|
||
|
// fake classes
|
||
|
class rlc_dummy : public srsue::rlc_interface_mac
|
||
|
{
|
||
|
public:
|
||
|
rlc_dummy(srslte::log_filter* log_) : received_bytes(0), log(log_) {}
|
||
|
bool has_data(const uint32_t lcid) { return false; }
|
||
|
uint32_t get_buffer_state(const uint32_t lcid) { return 10; }
|
||
|
int read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) { return 0; };
|
||
|
void write_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes)
|
||
|
{
|
||
|
log->debug_hex(payload, nof_bytes, "Received %d B on LCID %d\n", nof_bytes, lcid);
|
||
|
received_bytes += nof_bytes;
|
||
|
};
|
||
|
void write_pdu_bcch_bch(uint8_t* payload, uint32_t nof_bytes){};
|
||
|
void write_pdu_bcch_dlsch(uint8_t* payload, uint32_t nof_bytes){};
|
||
|
void write_pdu_pcch(uint8_t* payload, uint32_t nof_bytes){};
|
||
|
void write_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes){};
|
||
|
uint32_t get_received_bytes() { return received_bytes; }
|
||
|
|
||
|
private:
|
||
|
uint32_t received_bytes;
|
||
|
srslte::log_filter* log;
|
||
|
};
|
||
|
|
||
|
class phy_dummy : public phy_interface_mac
|
||
|
{
|
||
|
public:
|
||
|
phy_dummy() : scell_cmd(0){};
|
||
|
// phy_interface_mac
|
||
|
void configure_prach_params(){};
|
||
|
virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm){};
|
||
|
prach_info_t prach_get_info()
|
||
|
{
|
||
|
prach_info_t info = {};
|
||
|
return info;
|
||
|
};
|
||
|
void sr_send(){};
|
||
|
int sr_last_tx_tti() { return 0; };
|
||
|
void set_mch_period_stop(uint32_t stop){};
|
||
|
|
||
|
// phy_interface_mac_common
|
||
|
void set_crnti(uint16_t rnti){};
|
||
|
void set_timeadv_rar(uint32_t ta_cmd){};
|
||
|
void set_timeadv(uint32_t ta_cmd){};
|
||
|
void set_activation_deactivation_scell(uint32_t cmd) { scell_cmd = cmd; };
|
||
|
void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN], uint16_t rnti){};
|
||
|
uint32_t get_current_tti() { return 0; }
|
||
|
float get_phr() { return 0; };
|
||
|
float get_pathloss_db() { return 0; };
|
||
|
|
||
|
// getter for test execution
|
||
|
uint32_t get_scell_cmd() { return scell_cmd; }
|
||
|
|
||
|
private:
|
||
|
uint32_t scell_cmd;
|
||
|
};
|
||
|
|
||
|
class rrc_dummy : public rrc_interface_mac
|
||
|
{
|
||
|
public:
|
||
|
void ho_ra_completed(bool ra_successful) { printf("%s\n", __FUNCTION__); }
|
||
|
void release_pucch_srs() { printf("%s\n", __FUNCTION__); }
|
||
|
void run_tti(uint32_t tti) { printf("%s\n", __FUNCTION__); }
|
||
|
void ra_problem() { printf("%s\n", __FUNCTION__); }
|
||
|
};
|
||
|
|
||
|
} // namespace srslte
|
||
|
|
||
|
int mac_unpack_test()
|
||
|
{
|
||
|
// This MAC PDU contains three subheaders
|
||
|
const uint32_t mac_header_len = 4;
|
||
|
// Subheader 1 is SCell Activation/Deactivation CE
|
||
|
// - 1 byte SDU payload 0x02
|
||
|
const uint32_t mac_pdu1_len = 1;
|
||
|
// Subheader 2 is for LCID 1
|
||
|
// - 2 bytes SDU payload 0x00 0x08
|
||
|
const uint32_t mac_pdu2_len = 2;
|
||
|
// Subheader 3 is for LCID 3 (RLC AM PDU with 2 B header and 54 B data)
|
||
|
// - 56 bytes SDU payload 0x98 .. 0x89, 0x00, 0x00
|
||
|
const uint32_t mac_pdu3_len = 56;
|
||
|
|
||
|
uint8_t dl_sch_pdu[] = {0x3b, 0x21, 0x02, 0x03, 0x02, 0x00, 0x08, 0x98, 0x1b, 0x45, 0x00, 0x05, 0xda,
|
||
|
0xc7, 0x23, 0x40, 0x00, 0x40, 0x11, 0xe6, 0x9b, 0xc0, 0xa8, 0x03, 0x01, 0xc0,
|
||
|
0xa8, 0x03, 0x02, 0xd8, 0x29, 0x13, 0x89, 0x05, 0xc6, 0x2b, 0x73, 0x00, 0x0d,
|
||
|
0xc3, 0xb3, 0x5c, 0xa3, 0x23, 0xad, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x89, 0x00, 0x00};
|
||
|
|
||
|
srslte::log_filter rlc_log("RLC");
|
||
|
srslte::log_filter mac_log("MAC");
|
||
|
|
||
|
mac_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||
|
mac_log.set_hex_limit(100000);
|
||
|
rlc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||
|
rlc_log.set_hex_limit(100000);
|
||
|
|
||
|
// dummy layers
|
||
|
phy_dummy phy;
|
||
|
rlc_dummy rlc(&rlc_log);
|
||
|
rrc_dummy rrc;
|
||
|
|
||
|
// the actual MAC
|
||
|
mac mac;
|
||
|
mac.init(&phy, &rlc, &rrc, &mac_log);
|
||
|
|
||
|
// create dummy DL action and grant and push MAC PDU
|
||
|
mac_interface_phy::tb_action_dl_t dl_action;
|
||
|
mac_interface_phy::mac_grant_dl_t mac_grant;
|
||
|
bzero(&dl_action, sizeof(dl_action));
|
||
|
bzero(&mac_grant, sizeof(mac_grant));
|
||
|
mac_grant.rnti = 0xbeaf;
|
||
|
mac_grant.tb[0].tbs = sizeof(dl_sch_pdu);
|
||
|
int cc_idx = 0;
|
||
|
|
||
|
// Send grant to MAC and get action for this TB, then call tb_decoded to unlock MAC
|
||
|
mac.new_grant_dl(cc_idx, mac_grant, &dl_action);
|
||
|
|
||
|
// Copy PDU into provided buffer
|
||
|
bool dl_ack[SRSLTE_MAX_CODEWORDS] = {true, false};
|
||
|
memcpy(dl_action.tb[0].payload, dl_sch_pdu, sizeof(dl_sch_pdu));
|
||
|
dl_action.tb[0].enabled = true;
|
||
|
mac.tb_decoded(cc_idx, mac_grant, dl_ack);
|
||
|
|
||
|
// make sure MAC PDU thread picks up before stopping
|
||
|
sleep(1);
|
||
|
mac.run_tti(0);
|
||
|
mac.stop();
|
||
|
|
||
|
// check length of both received RLC PDUs
|
||
|
TESTASSERT(rlc.get_received_bytes() == mac_pdu2_len + mac_pdu3_len);
|
||
|
|
||
|
// check received SCell activation command
|
||
|
TESTASSERT(phy.get_scell_cmd() == 2);
|
||
|
|
||
|
return SRSLTE_SUCCESS;
|
||
|
}
|
||
|
|
||
|
int main(int argc, char** argv)
|
||
|
{
|
||
|
if (mac_unpack_test()) {
|
||
|
printf("MAC PDU unpack test failed.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|