Merge remote-tracking branch 'origin/episys-channel-model-org' into integration_2022_wk25
This commit is contained in:
@@ -1952,6 +1952,7 @@ set (MAC_SRC_UE
|
||||
|
||||
set (MAC_NR_SRC_UE
|
||||
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
|
||||
${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c
|
||||
${NR_UE_MAC_DIR}/config_ue.c
|
||||
${NR_UE_MAC_DIR}/mac_vars.c
|
||||
${NR_UE_MAC_DIR}/main_ue_nr.c
|
||||
|
||||
@@ -907,7 +907,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela
|
||||
|
||||
|
||||
|
||||
#define MCS_COUNT 28
|
||||
#define MCS_COUNT 29
|
||||
#define MCS_TABLE_LENGTH_MAX 64
|
||||
|
||||
|
||||
|
||||
@@ -241,8 +241,6 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
void processSlotTX(void *arg) {}
|
||||
|
||||
//nFAPI P7 dummy functions to avoid linking errors
|
||||
|
||||
@@ -227,8 +227,6 @@ nrUE_params_t *get_nrUE_params(void) {
|
||||
return &nrUE_params;
|
||||
}
|
||||
|
||||
nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
void processSlotTX(void *arg) {}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
@@ -225,8 +225,6 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
//nFAPI P7 dummy functions
|
||||
|
||||
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
|
||||
|
||||
@@ -66,17 +66,6 @@ queue_t nr_tx_req_queue;
|
||||
queue_t nr_ul_dci_req_queue;
|
||||
queue_t nr_ul_tti_req_queue;
|
||||
|
||||
static slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
|
||||
|
||||
//static int get_mcs_from_sinr(float sinr);
|
||||
//static int get_cqi_from_mcs(void);
|
||||
static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
|
||||
//static bool did_drop_transport_block(int slot, uint16_t rnti);
|
||||
static float get_bler_val(uint8_t mcs, int sinr);
|
||||
static bool should_drop_transport_block(int slot, uint16_t rnti);
|
||||
static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
|
||||
static inline bool is_channel_modeling(void);
|
||||
|
||||
void nrue_init_standalone_socket(int tx_port, int rx_port)
|
||||
{
|
||||
{
|
||||
@@ -939,7 +928,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
|
||||
return;
|
||||
}
|
||||
|
||||
static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
|
||||
void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
|
||||
{
|
||||
int count_sent = 0;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
|
||||
@@ -1343,245 +1332,3 @@ void RCconfig_nr_ue_L1(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static int get_mcs_from_sinr(float sinr)
|
||||
{
|
||||
if (sinr < (nr_bler_data[0].bler_table[0][0]))
|
||||
{
|
||||
LOG_D(NR_MAC, "The SINR found is smaller than first MCS table\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sinr > (nr_bler_data[NR_NUM_MCS-1].bler_table[nr_bler_data[NR_NUM_MCS-1].length - 1][0]))
|
||||
{
|
||||
LOG_D(NR_MAC, "The SINR found is larger than last MCS table\n");
|
||||
return NR_NUM_MCS-1;
|
||||
}
|
||||
|
||||
for (int n = NR_NUM_MCS-1; n >= 0; n--)
|
||||
{
|
||||
CHECK_INDEX(nr_bler_data, n);
|
||||
float largest_sinr = (nr_bler_data[n].bler_table[nr_bler_data[n].length - 1][0]);
|
||||
float smallest_sinr = (nr_bler_data[n].bler_table[0][0]);
|
||||
if (sinr < largest_sinr && sinr > smallest_sinr)
|
||||
{
|
||||
LOG_D(NR_MAC, "The SINR found in MCS %d table\n", n);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
LOG_E(NR_MAC, "Unable to get an MCS value.\n");
|
||||
abort();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static int get_cqi_from_mcs(void)
|
||||
{
|
||||
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||
9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15};
|
||||
assert(NUM_ELEMENTS(mcs_to_cqi) == NR_NUM_MCS);
|
||||
int slot = 0;
|
||||
while (slot < NUM_NFAPI_SLOT)
|
||||
{
|
||||
if (slot_rnti_mcs[slot].latest)
|
||||
{
|
||||
int num_pdus = slot_rnti_mcs[slot].num_pdus;
|
||||
if (num_pdus <= 0)
|
||||
{
|
||||
LOG_E(NR_MAC, "%s: slot_rnti_mcs[%d].num_pdus = 0\n", __FUNCTION__, slot);
|
||||
abort();
|
||||
}
|
||||
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
|
||||
int mcs = get_mcs_from_sinr(slot_rnti_mcs[slot].sinr);
|
||||
CHECK_INDEX(mcs_to_cqi, mcs);
|
||||
int cqi = mcs_to_cqi[mcs];
|
||||
LOG_D(NR_MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", slot_rnti_mcs[slot].sinr, mcs, cqi);
|
||||
return cqi;
|
||||
}
|
||||
slot++;
|
||||
}
|
||||
LOG_E(NR_MAC, "Unable to get CQI value because no MCS found\n");
|
||||
abort();
|
||||
}
|
||||
*/
|
||||
|
||||
static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index)
|
||||
{
|
||||
if (pdu == NULL)
|
||||
{
|
||||
LOG_E(NR_MAC,"PDU NULL\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* This function is executed for every pdsch pdu type in a dl_tti_request. We save
|
||||
the assocaited MCS and RNTI value for each. The 'index' passed in is a count of
|
||||
how many times we have called this function for a particular dl_tti_request. It
|
||||
allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/
|
||||
for (int i = 0; i < NUM_NFAPI_SLOT; i++)
|
||||
{
|
||||
slot_rnti_mcs[i].latest = false;
|
||||
}
|
||||
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].rnti, index);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].mcs, index);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index);
|
||||
slot_rnti_mcs[slot].rnti[index] = pdu->rnti;
|
||||
slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0];
|
||||
slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0];
|
||||
slot_rnti_mcs[slot].drop_flag[index] = false;
|
||||
slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus
|
||||
slot_rnti_mcs[slot].latest = true;
|
||||
LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
static bool did_drop_transport_block(int slot, uint16_t rnti)
|
||||
{
|
||||
int num_pdus = slot_rnti_mcs[slot].num_pdus;
|
||||
if (num_pdus <= 0)
|
||||
{
|
||||
LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n");
|
||||
return true;
|
||||
}
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
|
||||
for (int n = 0; n < num_pdus; n++)
|
||||
{
|
||||
if (slot_rnti_mcs[slot].rnti[n] == rnti && slot_rnti_mcs[slot].drop_flag[n])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
static float get_bler_val(uint8_t mcs, int sinr)
|
||||
{
|
||||
// 4th col = dropped packets, 5th col = total packets
|
||||
float bler_val = 0.0;
|
||||
CHECK_INDEX(nr_bler_data, mcs);
|
||||
LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr,
|
||||
(int)(nr_bler_data[mcs].bler_table[0][0] * 10),
|
||||
(int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)
|
||||
);
|
||||
|
||||
if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10))
|
||||
{
|
||||
LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs);
|
||||
bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5];
|
||||
return bler_val;
|
||||
}
|
||||
if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10))
|
||||
{
|
||||
LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs);
|
||||
bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5];
|
||||
return bler_val;
|
||||
}
|
||||
// Loop through bler table to find sinr_index
|
||||
for (int i = 0; i < nr_bler_data[mcs].length; i++)
|
||||
{
|
||||
int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10);
|
||||
if (temp_sinr == sinr)
|
||||
{
|
||||
bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
|
||||
return bler_val;
|
||||
}
|
||||
// Linear interpolation when SINR is between indices
|
||||
if (temp_sinr > sinr)
|
||||
{
|
||||
float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5];
|
||||
float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
|
||||
LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2);
|
||||
return ((bler_val1 + bler_val2) / 2);
|
||||
}
|
||||
}
|
||||
LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n");
|
||||
abort();
|
||||
|
||||
}
|
||||
|
||||
static inline bool is_channel_modeling(void)
|
||||
{
|
||||
/* TODO: For now we enable channel modeling based on the node_number.
|
||||
Replace with a command line option to enable/disable channel modeling.
|
||||
The LTE UE will crash when channel modeling is conducted for NSA
|
||||
mode. It does not crash for LTE mode. We have not implemented channel
|
||||
modeling for NSA mode yet. For now, we ensure only do do channel modeling
|
||||
in LTE/NR mode. */
|
||||
return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa;
|
||||
}
|
||||
|
||||
static bool should_drop_transport_block(int slot, uint16_t rnti)
|
||||
{
|
||||
if (!is_channel_modeling())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We want to avoid dropping setup messages because this would be pathological. */
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
|
||||
if (mac->ra.ra_state < RA_SUCCEEDED)
|
||||
{
|
||||
LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get block error rate (bler_val) from table based on every saved
|
||||
MCS and SINR to be used as the cutoff rate for dropping packets.
|
||||
Generate random uniform vairable to compare against bler_val. */
|
||||
int num_pdus = slot_rnti_mcs[slot].num_pdus;
|
||||
assert(slot < 20 && slot >= 0);
|
||||
LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n",
|
||||
rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr);
|
||||
assert(num_pdus > 0);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
|
||||
int n = 0;
|
||||
uint8_t mcs = 99;
|
||||
for (n = 0; n < num_pdus; n++)
|
||||
{
|
||||
if (slot_rnti_mcs[slot].rnti[n] == rnti)
|
||||
{
|
||||
mcs = slot_rnti_mcs[slot].mcs[n];
|
||||
}
|
||||
if (mcs != 99)
|
||||
{
|
||||
/* Use MCS to get the bler value. Since there can be multiple MCS
|
||||
values for a particular slot, we verify that all PDUs are not
|
||||
flagged for drop before returning. If even one is flagged for drop
|
||||
we return immediately because we drop the entire packet. */
|
||||
|
||||
LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n",
|
||||
slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr);
|
||||
|
||||
float bler_val;
|
||||
if (slot_rnti_mcs[slot].rvIndex[n] != 0)
|
||||
bler_val = 0;
|
||||
else
|
||||
bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10)));
|
||||
double drop_cutoff = ((double) rand() / (RAND_MAX));
|
||||
assert(drop_cutoff <= 1);
|
||||
LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]);
|
||||
if (drop_cutoff <= bler_val)
|
||||
{
|
||||
slot_rnti_mcs[slot].drop_flag[n] = true;
|
||||
LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot);
|
||||
return slot_rnti_mcs[slot].drop_flag[n];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mcs == 99)
|
||||
{
|
||||
LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n);
|
||||
abort();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,45 +40,12 @@
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
#include "NR_Packet_Drop.h"
|
||||
|
||||
#define NR_NUM_MCS 29
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
#define NUM_NFAPI_SLOT 20
|
||||
#define NR_NUM_LAYER 1
|
||||
extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
|
||||
|
||||
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
typedef struct nr_phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_slot;
|
||||
uint16_t message_id;
|
||||
uint16_t nb_of_sinrs;
|
||||
float sinr[NR_NUM_LAYER];
|
||||
// Incomplete, need all channel parameters
|
||||
} nr_phy_channel_params_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot;
|
||||
uint16_t rnti[256];
|
||||
uint8_t mcs[256];
|
||||
uint8_t rvIndex[256];
|
||||
float sinr;
|
||||
uint16_t num_pdus;
|
||||
bool drop_flag[256];
|
||||
bool latest;
|
||||
|
||||
} slot_rnti_mcs_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t length;
|
||||
float bler_table[NUM_SINR][NUM_BLER_COL];
|
||||
} nr_bler_struct;
|
||||
|
||||
extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
|
||||
typedef enum {
|
||||
ONLY_PUSCH,
|
||||
NOT_PUSCH,
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "NR_MAC_UE/mac_proto.h"
|
||||
|
||||
slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
|
||||
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index)
|
||||
{
|
||||
if (pdu == NULL)
|
||||
{
|
||||
LOG_E(NR_MAC,"PDU NULL\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* This function is executed for every pdsch pdu type in a dl_tti_request. We save
|
||||
the assocaited MCS and RNTI value for each. The 'index' passed in is a count of
|
||||
how many times we have called this function for a particular dl_tti_request. It
|
||||
allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/
|
||||
for (int i = 0; i < NUM_NFAPI_SLOT; i++)
|
||||
{
|
||||
slot_rnti_mcs[i].latest = false;
|
||||
}
|
||||
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].rnti, index);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].mcs, index);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index);
|
||||
slot_rnti_mcs[slot].rnti[index] = pdu->rnti;
|
||||
slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0];
|
||||
slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0];
|
||||
slot_rnti_mcs[slot].drop_flag[index] = false;
|
||||
slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus
|
||||
slot_rnti_mcs[slot].latest = true;
|
||||
LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float get_bler_val(uint8_t mcs, int sinr)
|
||||
{
|
||||
// 4th col = dropped packets, 5th col = total packets
|
||||
nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
float bler_val = 0.0;
|
||||
CHECK_INDEX(nr_bler_data, mcs);
|
||||
LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr,
|
||||
(int)(nr_bler_data[mcs].bler_table[0][0] * 10),
|
||||
(int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)
|
||||
);
|
||||
|
||||
if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10))
|
||||
{
|
||||
LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs);
|
||||
bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5];
|
||||
return bler_val;
|
||||
}
|
||||
if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10))
|
||||
{
|
||||
LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs);
|
||||
bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5];
|
||||
return bler_val;
|
||||
}
|
||||
// Loop through bler table to find sinr_index
|
||||
for (int i = 0; i < nr_bler_data[mcs].length; i++)
|
||||
{
|
||||
int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10);
|
||||
if (temp_sinr == sinr)
|
||||
{
|
||||
bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
|
||||
return bler_val;
|
||||
}
|
||||
// Linear interpolation when SINR is between indices
|
||||
if (temp_sinr > sinr)
|
||||
{
|
||||
float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5];
|
||||
float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
|
||||
LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2);
|
||||
return ((bler_val1 + bler_val2) / 2);
|
||||
}
|
||||
}
|
||||
LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n");
|
||||
abort();
|
||||
|
||||
}
|
||||
|
||||
bool is_channel_modeling(void)
|
||||
{
|
||||
/* TODO: For now we enable channel modeling based on the node_number.
|
||||
Replace with a command line option to enable/disable channel modeling.
|
||||
The LTE UE will crash when channel modeling is conducted for NSA
|
||||
mode. It does not crash for LTE mode. We have not implemented channel
|
||||
modeling for NSA mode yet. For now, we ensure only do do channel modeling
|
||||
in LTE/NR mode. */
|
||||
return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa;
|
||||
}
|
||||
|
||||
bool should_drop_transport_block(int slot, uint16_t rnti)
|
||||
{
|
||||
if (!is_channel_modeling())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We want to avoid dropping setup messages because this would be pathological. */
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
|
||||
if (mac->ra.ra_state < RA_SUCCEEDED)
|
||||
{
|
||||
LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get block error rate (bler_val) from table based on every saved
|
||||
MCS and SINR to be used as the cutoff rate for dropping packets.
|
||||
Generate random uniform vairable to compare against bler_val. */
|
||||
int num_pdus = slot_rnti_mcs[slot].num_pdus;
|
||||
assert(slot < 20 && slot >= 0);
|
||||
LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n",
|
||||
rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr);
|
||||
assert(num_pdus > 0);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
|
||||
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
|
||||
int n = 0;
|
||||
uint8_t mcs = 99;
|
||||
for (n = 0; n < num_pdus; n++)
|
||||
{
|
||||
if (slot_rnti_mcs[slot].rnti[n] == rnti)
|
||||
{
|
||||
mcs = slot_rnti_mcs[slot].mcs[n];
|
||||
}
|
||||
if (mcs != 99)
|
||||
{
|
||||
/* Use MCS to get the bler value. Since there can be multiple MCS
|
||||
values for a particular slot, we verify that all PDUs are not
|
||||
flagged for drop before returning. If even one is flagged for drop
|
||||
we return immediately because we drop the entire packet. */
|
||||
|
||||
LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n",
|
||||
slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr);
|
||||
|
||||
float bler_val;
|
||||
if (slot_rnti_mcs[slot].rvIndex[n] != 0)
|
||||
bler_val = 0;
|
||||
else
|
||||
bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10)));
|
||||
double drop_cutoff = ((double) rand() / (RAND_MAX));
|
||||
assert(drop_cutoff <= 1);
|
||||
LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]);
|
||||
if (drop_cutoff <= bler_val)
|
||||
{
|
||||
slot_rnti_mcs[slot].drop_flag[n] = true;
|
||||
LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot);
|
||||
return slot_rnti_mcs[slot].drop_flag[n];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mcs == 99)
|
||||
{
|
||||
LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n);
|
||||
abort();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#ifndef __NR_CHAN_MODEL_H__
|
||||
#define __NR_CHAN_MODEL_H__
|
||||
|
||||
#include <platform_types.h>
|
||||
#include <nfapi_nr_interface_scf.h>
|
||||
#include <openair1/PHY/thread_NR_UE.h>
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
|
||||
#define NR_NUM_MCS 29
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
#define NUM_NFAPI_SLOT 20
|
||||
#define NR_NUM_LAYER 1
|
||||
#define MAX_CHAN_PARAMS 256
|
||||
|
||||
typedef struct nr_phy_channel_params_t
|
||||
{
|
||||
uint16_t sfn_slot;
|
||||
uint16_t message_id;
|
||||
uint16_t nb_of_sinrs;
|
||||
float sinr[NR_NUM_LAYER];
|
||||
} nr_phy_channel_params_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot;
|
||||
uint16_t rnti[MAX_CHAN_PARAMS];
|
||||
uint8_t mcs[MAX_CHAN_PARAMS];
|
||||
uint8_t rvIndex[MAX_CHAN_PARAMS];
|
||||
float sinr;
|
||||
uint16_t num_pdus;
|
||||
bool drop_flag[MAX_CHAN_PARAMS];
|
||||
bool latest;
|
||||
} slot_rnti_mcs_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t length;
|
||||
float bler_table[NUM_SINR][NUM_BLER_COL];
|
||||
} nr_bler_struct;
|
||||
|
||||
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
|
||||
void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
|
||||
float get_bler_val(uint8_t mcs, int sinr);
|
||||
bool should_drop_transport_block(int slot, uint16_t rnti);
|
||||
bool is_channel_modeling(void);
|
||||
|
||||
#endif
|
||||
@@ -1956,7 +1956,7 @@ static int get_mcs_from_sinr(float sinr)
|
||||
|
||||
static int get_cqi_from_mcs(void)
|
||||
{
|
||||
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15};
|
||||
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
|
||||
assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS);
|
||||
int sf = 0;
|
||||
while(sf < NUM_NFAPI_SUBFRAME)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
|
||||
#include "queue_t.h"
|
||||
|
||||
#define NUM_MCS 28
|
||||
#define NUM_MCS 29
|
||||
#define NUM_SINR 100
|
||||
#define NUM_BLER_COL 13
|
||||
#define LTE_NUM_LAYER 1
|
||||
|
||||
Reference in New Issue
Block a user